【问题标题】:Making sure the ships do not overlap确保船只不重叠
【发布时间】:2017-03-31 02:41:24
【问题描述】:

我已经在这个任务上卡了很长时间,所以我想是时候寻求帮助了。我正在制作战舰游戏,我目前正在编写一个函数,其中战舰随机放置在 10 x 10 网格上。我已经完成了,但我的问题是它们何时重叠。

我想不出一种方法来获取不与先前随机放置的船重叠的坐标。在我当前的代码中,我试图找出一种方法来制作它,以便如果坐标重叠,它将再次循环船,直到它具有不与任何其他船重叠的正确数量的单元格。我正在以 3 文件格式编写,因此我将包含每个文件中所需的代码。

在函数中,上下左右是随机的,所以在战舰中我的方向= 0,所以我只使用向上

这是头文件

typedef struct game_board
{
    int board[10][10];
    int row;
    int col;
    char symbol;
}Game_Board;

Game_Board initalize_game_board(Game_Board *player);

//Game_Board manually_place_ships_on_board(Game_Board *player);
Game_Board randomlly_place_ships_on_board(Game_Board *player);

主要

Game_Board person, computer;
    int who_goes_first = 0;

    person.symbol = '~';
    person.row = 10;
    person.col = 10;
    computer.symbol = '-';
    computer.row = 10;
    computer.col = 10;

    welcome_screen(outfile);

    printf("Player 1\n");
    initalize_game_board(&person);
    printf("\nPlayer 2\n");
    initalize_game_board(&computer);
    who_goes_first = select_who_starts_first();
    //manually_place_ships_on_board(&person);
    randomlly_place_ships_on_board(&computer);

函数。出于冗余原因,我只包括前 2 艘船

int direction = 0, i = 0, cell_row = 0, cell_col = 0;


    //Carrier
    printf("CARRIER\n");
    direction = rand() % 4;
    printf("Direction: %d\n", direction);
    player->symbol = 'c';
    if (direction == 0) // up 
    {
        cell_row = rand() % 10;
        if (cell_row <= 4)
        {
            cell_row += 4;
        }
        cell_col = rand() % 10;
        for (i = 0; i < 5; i++)
        {
            player->board[cell_row][cell_col] = player->symbol;
            printf("UP: Row:%d Col:%d\n", cell_row, cell_col);
            cell_row -= 1;
        }
    }
    else if (direction == 1) // down
    {
        cell_row = rand() % 6;
        cell_col = rand() % 10;
        for (i = 0; i < 5; i++)
        {
            player->board[cell_row][cell_col] = player->symbol;
            printf("DOWN: Row:%d Col:%d\n", cell_row, cell_col);
            cell_row += 1;
        }
    }
    else if (direction == 2) // left
    {
        cell_row = rand() % 10;
        cell_col = rand() % 10;
        if (cell_col <= 4)
        {
            cell_col += 4;
        }
        for (i = 0; i < 5; i++)
        {
            player->board[cell_row][cell_col] = player->symbol;
            cell_col -= 1;
            printf("LEFT: Row:%d Col:%d\n", cell_row, cell_col);
        }
    }
    else if (direction == 3) // right
    {
        cell_row = rand() % 10;
        cell_col = rand() % 6;
        for (i = 0; i < 5; i++)
        {
            player->board[cell_row][cell_col] = player->symbol;
            printf("RIGHT: row:%d Col:%d\n", cell_row, cell_col);
            cell_col += 1;
        }
    }

    //Battle Ship
    printf("BATTLE SHIP\n");

    direction = rand() % 4;
    printf("Direction: %d\n", direction);
    player->symbol = 'b';
    if (direction == 0) // up 
    {

        cell_row = rand() % 10;

        if (cell_row <= 3)
        {
            cell_row += 3;
        }

        cell_col = rand() % 10;


        for (i = 0; i < 4; i++)
        {
            player->board[cell_row][cell_col] = player->symbol;
            printf("UP: Row:%d Col:%d\n", cell_row, cell_col);
            cell_row -= 1;
        }
    }
    else if (direction == 1) // down
    {
        cell_row = rand() % 7;
        cell_col = rand() % 10;
        for (i = 0; i < 4; i++)
        {
            player->board[cell_row][cell_col] = player->symbol;
            printf("DOWN: Row:%d Col:%d\n", cell_row, cell_col);
            cell_row += 1;
        }
    }
    else if (direction == 2) // left
    {
        cell_row = rand() % 10;
        cell_col = rand() % 10;
        if (cell_col <= 3)
        {
            cell_col += 3;
        }
        for (i = 0; i < 4; i++)
        {
            player->board[cell_row][cell_col] = player->symbol;
            printf("LEFT: Row:%d Col:%d\n", cell_row, cell_col);
            cell_col -= 1;
        }
    }
    else if (direction == 3) // right
    {
        cell_row = rand() % 10;
        cell_col = rand() % 7;
        for (i = 0; i < 4; i++)
        {
            player->board[cell_row][cell_col] = player->symbol;
            printf("RIGHT: row:%d Col:%d\n", cell_row, cell_col);
            cell_col += 1;
        }
    }

我尝试过结合使用 do while、while 和 for 循环来尝试让船重置,但我就是想不出办法让这项工作发挥作用

我真的可以使用一些指导或朝着正确方向迈出一步来解决此任务。提前非常感谢!

【问题讨论】:

  • 我建议设计一个函数来放置不同大小的船只,而不是为每种类型的船只专门编码。您还可以设计一个功能,在放置新船之前检查棋盘以检查边界并查看是否有任何建议的位置已被占用。

标签: c loops random grid overlap


【解决方案1】:

我喜欢 Joud 的回答。此外,制作一个带有名称和长度字段的“ship”结构。然后你可以有一个船数组,并在一个 for 循环中将每艘船传递给函数:

loop(i) //pseudocode
{
   randomlly_place_ship_on_board(&computer, &ship[i]) 
}
...
randomlly_place_ship_on_board(Game_Board *player, Ship * sh)
{
   // Only takes care of one ship, sh.
   // Call isAvailableCells to determine placement, like
   while (!isAvailableCells...)
         // re-attempt placement
}

伪代码可能会有所帮助。检查 gameboard->board 是否该单元格可用。

【讨论】:

    【解决方案2】:

    出现重叠的原因是,当您放置第二艘船时,您绝不会检查随机生成的单元格(就行和列而言)是否实际上是空的。 也就是说,当你为你的战舰调用 rand() 时,你永远不会检查你得到的列或行(以及相邻的,取决于船的方向)是否实际上是空的,或者它们是否已经被使用您的运营商。

    一种简单的方法是实现一个检查随机生成的单元格是否足够的函数。可能的签名类似于:

    int isAvailableCell(int cell, int direction,  int ship_length);
    

    这个函数获取随机生成的单元格,你的船的方向和你的船的长度,它会检查是否所有的“ship_length”单元格(即船需要适应的单元格的数量)从“方向”中的“单元格”开始可用。这仅涉及检查您的 2D 矢量是否在这些单元格中具有非零元素(因为您在放置船时填充它们)。

    如果单元格不够用,则需要再次调用 rand()。显然,这是一种非常低效的蛮力方法,因为您最终可能会多次生成不合适的单元格,但我认为此时您不必担心性能。

    另外,很多代码是多余的,你可以将一艘船封装在一个函数中。它会让你的生活更轻松,你的代码看起来更干净。 希望这会有所帮助,祝你好运!

    【讨论】:

      猜你喜欢
      • 2014-01-18
      • 1970-01-01
      • 2018-01-05
      • 1970-01-01
      • 1970-01-01
      • 2010-09-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多