C语言 确保船只不重叠



我已经在这个任务上停留了很长时间,所以我认为是时候寻求一些帮助了。我正在制作一个战舰游戏,我目前正在编写一个函数,其中飞船随机放置在 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 1n");
initalize_game_board(&person);
printf("nPlayer 2n");
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("CARRIERn");
direction = rand() % 4;
printf("Direction: %dn", 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:%dn", 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:%dn", 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:%dn", 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:%dn", cell_row, cell_col);
cell_col += 1;
}
}
//Battle Ship
printf("BATTLE SHIPn");
direction = rand() % 4;
printf("Direction: %dn", 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:%dn", 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:%dn", 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:%dn", 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:%dn", cell_row, cell_col);
cell_col += 1;
}
}

我已经尝试了 do while 、while 和 for 循环的组合来尝试让船重置,但我只是想不出一种方法来做到这一点

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

我喜欢Joud的回答。此外,使用名称和长度字段创建一个"船"结构。然后,您可以拥有一组飞船,并在 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
}

伪代码可能会有所帮助。检查游戏板>板,了解该单元格是否可用。

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

一个简单的方法是实现一个函数来检查随机生成的单元格是否足够。可能的签名如下所示:

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

此函数采用随机生成的单元格、飞船的方向和飞船的长度,它会检查从"方向"中的"细胞"开始的所有"ship_length"单元(即飞船需要容纳的单元数量)是否可用。这仅涉及检查您的 2D 矢量在这些单元格中是否具有非零元素(因为您在放置船只时填充它们)。

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

此外,很多代码都是多余的,你可以封装在一个函数中放置一艘船。它将使您的生活更轻松,并且您的代码看起来更干净。 希望这有帮助,祝你好运!

最新更新