1

我正在用 C++ 编写战舰游戏。我已将值设置如下。

//const int empty    = 0;  // contains water
//const int occupied = 1;  // contains a ship 
//const int missed   = 2;  // shot into ocean W
//const int shot     = 3;  // ship is shot down H
//const int shipdown = 4;  // whole ship is shot down S

当用户击中船时,该值从 1 变为 3。我面临的问题是如何指示整艘船都倒下了。

int Grid[64];
int currentSquareValue = Grid[(row-1)*8+(column-1)];
switch(currentSquareValue)
{
  case 0:
    Grid[(row-1)*8+(column-1)] = 2;
    break;
  case 1:
    Grid[(row-1)*8+(column-1)] = 3;
    break;
  default:
    break;
}

//Printing out the Grid
for(int i = 0 ; i <=8; i++)
{
    //Print Row Header
    if(i != 0) cout << i << char(179);
    for(int j = 0; j <= 8; j++)
    {
       if(i == 0) 
       {
        //Print Column Header
            cout << j << char(179);
       }
       else
       {
          //Avoid the first row and column header
        if(j > 0 && i > 0) 
        {
           int currentSquareValue = Grid[(i-1)*8+(j-1)];
           switch(currentSquareValue)
            {
              case 0:
                cout << " " << char(179);
                break;
              case 1:
                cout << " " << char(179);
                break;
              case 2:
                cout << "W" << char(179);
                break;
              case 3:
                cout << "H" << char(179);
                break;
              case 4:
                cout << "S" << char(179);
                break;
              default:
                break;
            }
        }
    }
}

我已经完成了被击中的船,但我不确定如何表明在第三次射击后整艘船被击落,如下所示:

在此处输入图像描述

需要一些指导......不知道如何开始......

4

4 回答 4

2

也许你可以考虑板的位板表示。通常我已经看到它用于国际象棋,但是由于您的棋盘有 64 个方格,因此在这里似乎也很合适。基本思想是网格上的每个位置都由 64 位 int 中的一位表示。然后可以通过位操作快速轻松地执行操作。在这种类型的表示中,您将通过以下方式确定一艘船是否沉没:

bool is_sunk(uint64_t board, uint64_t ship) {
    return board & ship == ship;
}

和其他操作一样,同样容易。

例如,一艘船被击中了吗?

bool is_hit(uint64_t board, uint64_t ship) {
    return board & ship != 0;
}

我赢了比赛吗?

bool is_won(uint64_t board, uint64_t* ships, int size) {
    uint64_6 opponents_ships = 0;
    for (int i = 0; i < size; i++) opponents_ships |= *ships;
    return is_sunk(board, opponents_ships); 
}

向棋盘应用移动:

bool make_move(uint64_t& board, uint64_t move) {
    board &= move;
}
于 2013-08-19T14:42:49.810 回答
2

您需要将船舶的坐标存储在另一个数据结构中(这样您就可以从命中中找到船舶,然后将其所有方格标记为沉没)或让您的矩阵存储更复杂的数据(船舶 ID),这样您就可以将该船的所有箱子标记为沉没。

后者将为您提供以下数据:

const unsigned int empty = 0x0000;
const unsigned int shipIdMask = 0x00FF;
const unsigned int hitFlag = 0x0100;
const unsigned int sunkFlag = 0x0200;

显示方面,您只需执行 aif((value & shipIdMask) != 0)检查其中是否有船,然后同样检查命中。当一艘船被击中时,你可以采取懒惰的方式,简单地扫描整个矩阵以寻找具有相同船 ID 的方格。如果它们都被击中,则再次扫掠它们并将它们全部标记为沉没。

如果您不想每次都扫描整个矩阵,则可以结合使用这两种技术(使用船舶 ID 在数组中获取船舶的实际坐标)。

于 2013-08-19T14:44:03.330 回答
2

一个简单的解决方案,不一定是最好的。将您的网格设为结构而不是 int。这个结构包含一个标志,表示是否有船,那里有船的 ID,(这让你可以区分它们;如果没有船,则不应使用该值)和一个单独的标志,表示单元格是否已经打。现在为游戏中的每个船 ID 创建一个数组,其中包含组成船的单元数。所以 [0] -> 3,意味着船舶 ID 0 占用 3 个方格。每当针对包含此船 ID 的单元格注册新命中时,减少数组中的值。当它为 0 时,你就知道整艘船都被击中了。

于 2013-08-19T14:41:05.437 回答
1

我建议您让您的网格单元格包含信息,例如指向该位置的船的指针。

另一个想法是拥有一个船容器,每艘船将包含每个单元格(位置)的坐标。该船将包含这些单元的状态(可见、命中、沉没等)。

于 2013-08-19T14:41:53.103 回答