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

私はすでに船が攻撃されていることを確認しましたが、次のように 3 回目の射撃の後に船全体が撃墜されたことを示す方法がわかりません。

ここに画像の説明を入力

これに関するガイダンスが必要です...これを開始する方法がわからない..

4

4 に答える 4

2

おそらく、ボードのビットボード表現を考えることができます。通常、チェスに使用されるのを見てきましたが、ボードには 64 の正方形があるため、ここでも適切なようです。基本的な考え方は、グリッド上の各位置が 64 ビット int の正確に 1 ビットで表されるということです。その後、ビット操作を介して操作をすばやく簡単に実行できます。そのタイプの表現では、次のような方法で船が沈んでいるかどうかを判断します。

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;

表示if((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

グリッド セルに、その場所の船へのポインターなどの情報を含めることをお勧めします。

もう 1 つのアイデアは、船のコンテナを用意することです。各船には、それぞれのセル (場所) の座標が含まれます。船には、それらのセルのステータス (可視、ヒット、沈没など) が含まれます。

于 2013-08-19T14:41:53.103 に答える