1

I'm trying to make a simple battle ship game. I'm stuck on trying to randomly place the ships on my board.I have a feeling it is because I should be using a vector instead of an array. but I'm not sure how to create a 2d vector.

Here's what I have so far:

using namespace std;



void clearBoard(const int row, const int col) 
{
    int grid[row][col];
    for (int i = 0; i < row; i++) {
        for (int j = 0; j < col;j++) {
            grid[i][j] = 0;
            cout << grid[i][j] << " ";

        }
        cout << endl;
    }
}

void setShips(int max_ships1, int row, int col)
{
    int ship_counter = 0;
    while(ship_counter < max_ships1) {
        int x = rand() % row;
        int y = rand() % col;
        int matrix[x][y]
        if (matrix[x][y] != 1) {
            ship_counter++;
            matrix[x][y] = 1;
            cout << matrix[x][y] << " ";
        }
    cout << endl;
    }
}

int main(int argc, char* argv[])
{

    int _row = atoi(argv[0]);
    int _col = atoi(argv[2]);

    int max_ships;
    if (_row > _col) {
        max_ships = _row;
    }
    else if (_col > _row) {
        max_ships = _col;
    }
    else {
        max_ships = _row;
    }

    cout << "enter the size of the board:";
    cin >> _row >> _col;
    clearBoard(_row, _col);
    setShips(_row,_col,max_ships);





    return 0;

}

If the user decides on a 3x3 board, the first function returns:

0 0 0
0 0 0
0 0 0

I'm hoping to randomly generate 1's to represent a battleship's position. Here's an example on a 3x3 board:

1 0 0
0 1 0
1 0 0

Thanks.

Jeremy78
  • 21
  • 1
  • 6

2 Answers2

1

Your main problem is that grid goes out of scope (and is effectively deleted) when clearBoard returns, and matrix (a completely unrelated array to grid) goes out of scope each time through your while loop. That means that you're filling grid with zeroes, then creating a bunch of other arrays with random data and sometimes setting one element to 1. You need to either make grid global, or return it from clearBoard and pass it to setShips as an argument.

Passing around multidimensional raw arrays is kind of complicated, so using a vector might make this a bit easier for you if you don't want to make the array global. To create a two-dimensional vector, you might think that std::vector<std::vector<int>> will work, but that's not quite right. You can do it that way, as mentioned in the comments, but technically, std::vector<std::vector<int>> is what's called a jagged array, meaning that you can have each row be a different length - unlike your raw 2D array, where you know that each row must always be the same length.

The proper way to make a two-dimensional array with a vector is this:

std::vector<int> grid(row * col);
grid[i * row + j] = 1; // Or i * col + j will also work.

As you can see, it's a bit more complicated to get an element out by its (x,y) coordinates. It doesn't matter which of the two calculation methods you use, but in one version i is x and j is y, while in the other, the reverse is true (i is y, etc).

celticminstrel
  • 1,637
  • 13
  • 21
  • Thanks, I just have one question about implementation. Once I declare `std::vector grid(row * col);`, should set `grid[i * row + j] = 1;` in setShips and `grid[i * row + j] = 0;` in clearBoard? Sorry to ask, grabbing the elements is slightly confusing to me. – Jeremy78 Jul 12 '15 at 06:51
  • Pretty much, but don't forget that you need to do that on the _same object_, unlike in the code you posted (as my first paragraph says). – celticminstrel Jul 12 '15 at 15:15
  • When I declared `std::vector grid(row * col);` in my function, it says that vector of type does not have a call operator. I tried changing the return type of the function from void to int, but still the same error. I tried declaring the array global, but I get the error: `Floating point exception: 8`. Very sorry to bother you like this but I'm new to programming and don't really have anyone that can help me. – Jeremy78 Jul 12 '15 at 18:16
  • You must be doing something else wrong, because that statement `std::vector grid(row * col);` is correct and has nothing to do with call operators. – celticminstrel Jul 12 '15 at 18:26
0

You can also set up a 2D vector like this :

#include<vector>
#include<iostream>
using namespace std;

int main()
{

    std::vector< std::vector<int> > grid2D;

    //m * n is the size of the grid

    int m = 10;
    int n = 10;

    //Grow rows by m
    grid2D.resize(m);

   //Grow Columns by n
    for(int i = 0 ; i < m ; ++i) grid2D[i].resize(n);

  // print out 2D grid on screen
    for(i = 0 ; i < m ; ++i){
        for(int j = 0 ; j < n ; ++j){       

            grid2D[i][j]=0;
            cout<<""<<grid2D[i][j]<<" ";

        }
        cout<<"\n";

    }
    cout<<"\n";
    return 0;
}    
Software_Designer
  • 8,490
  • 3
  • 24
  • 28