C ++ Battleships自由空间功能

时间:2016-04-06 12:13:43

标签: c++

我试图创建一个战舰游戏,计算机随机将战列舰放在棋盘上。

战舰不能一个放在另一个上面或彼此相邻。 我建立了一个函数来检查这个并且如果可用空间可用则返回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;

    }
}

这是一张示例输出的照片: enter image description here

1 个答案:

答案 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;
}