lakshmen
lakshmen

Reputation: 29094

Indicating ships are shot down in game in C++

I am writing the battleship game in C++. I have set the values as below.

//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

When the user hit the ship, the value is changed from 1 to 3. The problem i face is how do I indicate that the whole ship is down.

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

I have already done the ship being hit, but I am not sure how to show that the whole ship is shot down after the third shot like in this:

enter image description here

Need some guidance on this... Not sure how to start on this..

Upvotes: 1

Views: 1580

Answers (4)

Kevin
Kevin

Reputation: 25269

Maybe you could consider a bitboard representation of the board. Typically I've seen it used for chess, but since your board has 64 squares it seems appropriate here as well. The basic idea is that each location on the grid is represented by exactly one bit in a 64 bit int. Then operations can be performed quickly and easily via bit manipulation. In that type of representation, you would determine if a ship is sunk via something like this:

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

And other operations, are equally easy.

For example, is a ship hit?

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

Did I win the game?

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

Apply a move to the board:

bool make_move(uint64_t& board, uint64_t move) {
    board &= move;
}

Upvotes: 2

Medinoc
Medinoc

Reputation: 6618

You need to either store the coordinates of the ships in another data structure (so you can find the ship from a hit, and then mark all its squares as sunk) or make your matrix store more complex data (a ship ID) so you can mark all cases for that ship as sunk.

The latter would give you data such as:

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

Display-wise, you just do a if((value & shipIdMask) != 0) to check if there is a ship in there, and you check hits likewise. When a ship is hit, you can go the lazy way and simply sweep the entire matrix for squares with the same ship ID. If all of them are hit, you sweep them again and mark them all as sunk.

Both techniques can be combined if you don't want to sweep the whole matrix each time (use the ship ID to get the ship's actual coordinates in an array).

Upvotes: 2

Thomas Matthews
Thomas Matthews

Reputation: 57749

I suggest you make your grid cells have information, such as a pointer to the ship at that location.

Another idea is to have a container of ships and each ship will contain the coordinates of each of it's cells (locations). The ship would contain the status of those cells (visible, hit, sunk, etc.).

Upvotes: 1

Neil Kirk
Neil Kirk

Reputation: 21813

A simple solution, not necessarily the best. Make your grid of a struct instead of an int. This struct contains a flag for whether a ship is present, the ID of a ship there, (this lets you tell them apart; if no ship is present the value shouldn't be used) and a separate flag for whether the cell has been hit. Now make an array for each ship ID in your game, which contains the number of cells that make up your ship. So [0] -> 3, means ship ID 0 takes up 3 squares. Whenever a new hit is registered against a cell containing this ship ID, decrease the value in the array. When it is 0, you know the whole ship has been hit.

Upvotes: 2

Related Questions