我试图创建一个战舰游戏,计算机随机将战列舰放在棋盘上。
战舰不能一个放在另一个上面或彼此相邻。 我建立了一个函数来检查这个并且如果可用空间可用则返回true,但由于某种原因,程序仍然会使船只违反规则。它并不是每次都会发生,但它仍然会发生。
这是检查可用空间的函数:
bool Game2::CheckPlace(int row, int column, DIRECTION direct, Battleship ship)//this function checks if a ship can be layed at the coordinates it recieved.
{
if (board[row][column] != '_' || board[row][column + 1] != '_' || board[row + 1][column + 1] != '_' || board[row + 1][column] != '_' || board[row - 1][column - 1] != '_' || board[row][column - 1] != '_' || board[row + 1][column - 1] != '_' || board[row + 1][column] != '_' || board[row + 1][column + 1] != '_')
return false;
if (direct == horizontal)//for horizontal direction
{
if (10 - column < ship.GetLength())//if there is no space left for the ship.
return false;
for (int i = 0; i < ship.GetLength(); ++i)//this loop creates a kind of a block that moves together to find surrounding ships.
{
if (row == 0 && column == 0 && (board[row + 1][column + i] != '_' || board[row + 1][column + 1 + i] != '_' || board[row][column + 1 + i] != '_'))//top left corner
return false;
if (row == 9 && column == 0 && (board[row - 1][column + i] != '_' || board[row - 1][column + 1 + i] != '_') || board[row][column + 1 + i] != '_')//bottom left corner
return false;
if (row > 0 && row < 9 && column > 0 && column < 9 && board[row][column + 1 + i] != '_' || board[row + 1][column + 1 + i] != '_' || board[row + 1][column + i] != '_' || board[row + 1][column - 1 + i] != '_' || board[row][column - 1 + i] != '_' || board[row - 1][column - 1 + i] != '_' || board[row - 1][column + i] != '_' || board[row - 1][column + 1 + i] != '_')//middle of the board
return false;
if (row == 0 && column > 0 && column < 9 && (board[row][column - 1 + i] != '_' || board[row][column + i] != '_' || board[row][column + 1 + i] != '_' || board[row + 1][column - 1 + i] != '_' || board[row + 1][column + i] != '_' || board[row + 1][column + 1 + i] != '_'))
return false;
if (row == 9 && column > 0 && column < 9 && (board[row - 1][column - 1 + i] != '_' || board[row - 1][column + i] != '_' || board[row - 1][column + 1 + i] != '_' || board[row][column - 1 + i] != '_' || board[row][column + i] != '_' || board[row][column + 1 + i] != '_'))
return false;
if (column = 0 && row > 0 && row < 9 && (board[row + 1][column + i] != '_' || board[row + 1][column + 1 + i] != '_' || board[row][column + 1 + i] != '_' || board[row - 1][column + i] != '_' || board[row - 1][column + 1 + i] != '_'))
return false;
}
return true;
}
if (direct == vertical)
{
if (10 - row < ship.GetLength())//if there is no space left for the ship.
return false;
for (int i = 0; i < ship.GetLength(); ++i)//this loop creates a kind of a block that moves together to find surrounding ships.
{
if (row == 0 && column == 0 && (board[row + i][column + 1] != '_' || board[row + 1 + i][column + 1] != '_' || board[row + 1 + i][column] != '_'))
return false;
if (row == 0 && column == 9 && (board[row + i][column - 1] != '_' || board[row + 1 + i][column - 1] != '_' || board[row + 1 + i][column] != '_'))
return false;
if (row == 0 && column > 0 && column < 9)
if (board[row + i][column + 1] != '_' || board[row + 1 + i][column + 1] != '_' || board[row + 1 + i][column] != '_' || board[row + i][column - 1] != '_' || board[row + 1 + i][column - 1] != '_')
return false;
if (column == 0 && row > 0 && row < 9 && (board[row + i][column + 1] != '_' || board[row + 1 + i][column + 1] != '_' || board[row + 1 + i][column] != '_' || board[row - 1 + i][column + 1] != '_' || board[row - 1 + i][column] != '_'))
return false;
if (column == 9 && row > 0 && row < 9 && (board[row + i][column - 1] != '_' || board[row + 1 + i][column - 1] != '_' || board[row + 1 + i][column] != '_' || board[row - 1 + i][column - 1] != '_' || board[row - 1 + i][column] != '_'))
return false;
if (row > 0 && row < 9 && column > 0 && column < 9)
if ((board[row + i][column + 1] != '_' || board[row + 1 + i][column + 1] != '_' || board[row + 1 + i][column] != '_' || board[row + i][column - 1] != '_' || board[row + 1 + i][column - 1] != '_' || board[row - 1 + i][column + 1] != '_' || board[row - 1 + i][column] != '_' || board[row - 1 + i][column - 1] != '_'))
return false;
}
return true;
}
}
答案 0 :(得分:0)
@interjay已经回答了你的问题,指出了条件中的错误:
if ( column = 0 ... // should be ==
正如许多其他人所说,请记住始终启用编译器可能出现的所有警告。您也可以尝试首先编写文字:
if ( 0 = column ... // that's an error every compiler can catch
我写这个答案的主要原因是,如果可以的话,我想向您展示一个不同的(可能更易读,更不容易出错)算法来完成您的任务。
将船及其周围的水想象成海中的矩形(板)。要检查矩形内的所有单元格很简单,可以在嵌套循环中完成。要正确定义搜索矩形的顶点可能比较棘手,但不能太多。
我想我已经弄清楚你如何存储有关船只的数据(至少需要这些数据),所以这段代码应该有效:
const int rows = 10;
const int cols = 10;
bool CheckPlace(int row, int column, DIRECTION direct, Battleship ship) {
// check if the top left corner of the ship is inside the board
if ( row < 0 || row >= rows || column < 0 || column >= cols )
return false;
int r_min = row, // temporary top side of the rectangle
c_min = column, // temporary left side
r_max = row + 2, // temporary bottom side
c_max = column + 2; // temporary right side
// update top and left size if there is enough space
if ( r_min > 0 ) --r_min;
if ( c_min > 0 ) --c_min;
// use ship length and direction to update values for right and bottom side
// max values are one past the border of the rectangle
if ( horizontal == direct )
c_max += ship.GetLength() - 1;
else
r_max += ship.GetLength() - 1;
// check if the bottom rigth corner of the ship is outside the board
if ( r_max > rows + 1 || c_max > cols + 1 )
return false;
// clip the rectangle if the ship is near the border
if ( r_max > rows )
--r_max;
if ( c_max > cols )
--c_max;
// check inside the rectangle
for ( int i = r_min; i < r_max; ++i ) {
for ( int j = c_min; j < c_max; ++j ) {
if ( '_' != board[i][j] )
return false;
}
}
// open water
return true;
}