Jump to content

What's up guys, my professor assigned my class a lab where she wants me to create a battleship game using 2d arrays. I'm running into trouble when determining if the user hit the ship or missed it. This is what I have so far. I'm not a 100% if the create board part is correct. Thanks for the help in advance.


#include <iostream>
#include <time.h>

using namespace std;

bool set_ships(int **& matrix, int size, int num1);

int main()
{
    int ** B;
    int size, num_ships, row, col;
    int num_hits = 0;

    cout << "***** Battleship *****" << endl;
    cout << "How many rows/columns is the board? ";
    cin >> size;

    /*Part1: CREATE THE BATTLESHIP BOARD AND SET ALL ELEMENTS TO 0*/
    int board[size][size];
    void create_board(int array1[size][size])//creates the game board
    {
        for (int x = 0; x < size; x++)
        {
            for (int y = 0; y < size; y++)
            {
                array1[x][y] = 0;
            }
        }
    }
    /*******************************************************/

    cout << "A " << size << "x" << size << " board has been created.\n";
    cout << "How many ships? ";
    cin >> num_ships;
    set_ships(B, size, num_ships);

    while (num_hits != num_ships)
    {
        cout << "What row: ";
        cin >> row;
        cout << "What col: ";
        cin >> col;
        /*Part2: DETERMINE IF IT’S A HIT. IF SO, UPDATE INFORMATION & TELL USER.*/
        if (row && col == 0) {
            cout << "HIT! Nice shot!" << endl;
        }
        else(row && col != 1) {
            cout << "MISS! Reload and try again." << endl;
        }
        /*Part2: DETERMINE IF IT’S A HIT. IF SO, UPDATE INFORMATION & TELL USER.*/
    }
}

cout << "You sunk my battleships!" << endl;

/*Part3: CLEAN UP YOUR MEMORY*/


/*Part3: CLEAN UP YOUR MEMORY*/


return 0;
}

bool set_ships(int **& B, int size, int num_ships) {
    /*Part4: Write me! */
    //Randomly Generate a row AND a col
    //If that row and col has a 0 then make it 1 to put a ship there
    //If there is a ship there already (meaning its 1 already) then skip 
    //continue until you created the num_ships needed
    /*Part4: Write me! */
    return true;
}


 

Sample Output:(what it should look like when complete.)

How many rows/columns is the board? 5

A 5x5 board has been created.

How many ships? 2

What row: 0

What col: 0

Miss! Try again.

What row: 4

What col: 2

Hit!

What row: 4

What col: 2

You already guessed that. Try again.

What row: 1

What col: 1

Miss! Try again.

What row: 3

What col: 3

Hit!

You sunk my battleships!

Link to comment
https://linustechtips.com/topic/661129-2d-array-battleship-game-help/
Share on other sites

Link to post
Share on other sites

It looks like you are not firing your create_board function, you only define it inside your main function, but you're not calling it.

Second thing, I'm not sure about board afaik it is g++ specific, and you should read about new (and then delete[]) operator to dynamically create arrays. I see you had good idea with int **B which seems to be unused. I noticed set_ships, I'm not sure but this function looks like addition to your create_board function that sets positions of ships on a board but that reference in argument list makes me thing that you have to create array inside that function so it will change pointer that B is pointing to.

 

Also 

if (row && col == 0) {

is not doing what you thin it does. It checks if col == 0 is true and if row is true (any non 0 is evaluating to true) so it is like if(true && col == 0) when row is non 0 and if(false && col == 0) when row is 0. You need to always type like this:

if (row == 0 && col == 0) {

Edit: I made you an example how set_ships function with that reference to array of pointers would work with and without reference:

 

#include <iostream>

void create(int **&board, int size){
	board = new int*[size];
	for(int x = 0; x < size; x++){
		board[x] = new int[size];
		for(int y = 0; y < size; y++){
			board[x][y] = x + y;
		}
	}
}

void print(int **board, int size){
	for(int x = 0; x < size; x++){
		for(int y = 0; y < size; y++){
			std::cout << board[x][y] << ", ";
		}
		std::cout << std::endl;
	}
}

void destroy(int **&board, int size){
	for(int x = 0; x < size; x++){
		delete[] board[x];
	}
	delete[] board;	
	board = nullptr;
}

int main(){
	
	int size;
	std::cout << "board size: ";
	std::cin >> size;
	
	int **board;
	std::cout << "board before create: " << board << std::endl;
	create(board, size);
	
	print(board, size);
	std::cout << "board after create: " << board << std::endl;
	
	destroy(board, size);	
	std::cout << "board after destroy: " << board << std::endl;
	
	return 0;	
}

This will output:

board size: 3
board before create: 0x28ff88
0, 1, 2,
1, 2, 3,
2, 3, 4,
board after create: 0x782dc8
board after destroy: 0

pointer before create has some trash value (0x28ff88).

after creating array and assigning new pointer to board inside create function, it will change to new pointer, and because board is reference, it will take effect outside function, and now board points to new address (0x742dc8)

destroy function destroys the array, as it was creating rows now it destroys those rows and then destroys root pointer.

 

You can see why referencing board is important inside create function (and not so much in delete function). When you remove reference operator and you will end up with such function header:

void create(int **board, int size){

When you run such code the output will be something like this:

board size: 3
board before create: 0x28ff88
2686932, 1999608066, 2130567168,
68550480, -1871259897, -1869574000,
0, -1, 4194304,
board after create: 0x28ff88
board after destroy: 0x28ff88

What happens there is, inside of create function, board variable is a copy of passed board variable, not a reference, so even we create array inside we lost the pointer at the end of function execution (and cause memory leak).

Then it just gets worse, we access memory we didn't allocate by old trash pointer value (0x28ff88) as create function didn't change it it remains as trhas value and even worse, we pass it to delete function. If we change delete function in same way we did with create function then inside delete function board is not reference either, and function still can destroy it, it just cannot change it's value to nullptr which is not necessary.

 

Only print function has no real use of referencing board as it prints only the data it points to, and there is no sense changing root pointer of array inside print function.

Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×