I would like to create a battleship game in C++. I have the game working but I cant really decide how to determine what positions make up a ship. My game board is a 15 x 15 so, for example:

0000000000000010
0000000000000010
0000000000000010
0000000011000000
0001000000000000
0001000000000000

ect....

So what I would like is to be able to somehow say when all positions have been hit for a ship, OH you sank the frigate or OH you sank the Destroyer.

Here is what I have to far:

#include <iostream>
#include <cstdlib>

using namespace std;

int genrow(int dir);
int gencol(int dir);
int gendir();
void setupboard();
void insertship(int row, int col, int dir);
void positionShips();
void printarray();
void gatherCoord();

int xpos;
int ypos;
int mydir;
int shipsize;
int myGuess = 0;
int stop = 0;
int guessX, guessY;
int gameboard[15][15];
int shipPositions[2][15];

int main()
{
	srand(1);
	setupboard();
	cout << "X" << "\tY" << endl;
	positionShips();
	gatherCoord();
	printarray();
	while (myGuess < 5)
	{
		cout << "Where would you like to attack: ";
		cin >> guessX >> guessY;
		int row = 0;
		for (row = 0; row < 15; row = row + 1)
		{
			int col = 0;
			for (col = 0; col < 15; col = col + 1)
			{
				gameboard[row][col];
				if (gameboard[row][col] == 1 && guessX == row && guessY == col)
					cout << "Thats a hit!" << endl;
				else if (gameboard[row][col] == 0 && guessX == row && guessY == col)
					cout << "Miss! Try again!" << endl;
				else
					 "Do Nothing";
			}
		}
		myGuess = myGuess + 1;
	}
		
	cout << endl;
	system("pause");
	return 0;
}

int genrow(int dir)
{
	xpos = rand() % 14;
	if (xpos < shipsize - 1 && dir == 0)
		xpos = xpos + (shipsize - 1);
	else if(xpos > 15 - shipsize && dir == 2)
		xpos = xpos - (shipsize - 1);
	else
		"Do nothing";
	return xpos;
}

int gencol(int dir)
{
	ypos = rand() % 14;
	if (ypos < shipsize - 1 && dir == 3)
		ypos = ypos + (shipsize - 1);
	else if(ypos > 15 - shipsize && dir == 1)
		ypos = ypos - (shipsize - 1);
	else
		"Do nothing";
	return ypos;
}

int gendir()
{
	return rand() % 3;
}
void setupboard()
{
	int row = 0;
	while (row < 15)
	{
		int col = 0;
		while (col < 15)
		{
			gameboard[row][col] = 0;
			col = col + 1;
		}
		row = row + 1;
	}
}

void insertship(int row, int col, int dir)
{
	int mycount = 0;
	gameboard[row][col] = 1;
	while (mycount < shipsize - 1)
	{
		if (dir == 0)
		{
			row = row - 1;
			gameboard[row][col] = 1;
		}
		else if(dir == 1)
		{
			col = col + 1;
			gameboard[row][col] = 1;
		}
		else if(dir == 2)
		{
			row = row + 1;
			gameboard[row][col] = 1;
		}
		else if(dir == 3)
		{
			col = col - 1;
			gameboard[row][col] = 1;
		}
		else
			cout << "You should not be here!";
		mycount = mycount + 1;
	}
}

void printarray()
{
	int myrow = 0;
	while (myrow < 15)
	{
		int mycol = 0;
		while (mycol < 15)
		{
			cout << gameboard[myrow][mycol];
			mycol = mycol + 1;
		}
		cout << endl;
		myrow = myrow + 1;
	}
}

void gatherCoord()
{
	int row = 0;
	for (row = 0; row < 15; row = row + 1)
	{
		int col = 0;
		for (col = 0; col < 15; col = col + 1)
		{
			int cX = 0;
			if (gameboard[row][col] == 1)
			{
				shipPositions[cX][0] = row;
				shipPositions[cX][1] = col;
				cout << shipPositions[cX][0] << "\t";
				cout << shipPositions[cX][1] << endl;
				cX = cX + 1;
			}
			else if (gameboard[row][col] == 0)
				"Do Nothing";
			else
				"What happened?";
		}
	}
}

void positionShips()
{
	while (stop < 5)
	{
		if (stop < 2)
			shipsize = 2;
		else if (stop < 4)
			shipsize = 3;
		else
			shipsize = 4;
		mydir = gendir();
		xpos = genrow(mydir);
		ypos = gencol(mydir);
		insertship(xpos, ypos, mydir);
		stop = stop + 1;
	}
}

Thanks for help in advance

Dani AI

Generated

Both and are on the right track: model ships as types instead of only marking cells. A clear pattern is to keep a Ship object that stores its coordinates, a parallel hit mask or a remaining-parts counter, plus a name/size. The board holds a ship ID per cell (empty = -1). That makes hit detection O(1) (index the board at the guessed row/col) and lets sink detection be immediate (remaining == 0) without scanning the whole grid every guess.

struct Ship {
    std::string name;
    std::vector<std::pair<int,int>> parts;
    std::vector<bool> hit;
    int remaining;
    Ship(const std::string& n, const std::vector<std::pair<int,int>>& p)
      : name(n), parts(p), hit(p.size(), false), remaining((int)p.size()) {}
    bool hitAt(int r,int c) {
        for(size_t i=0;i<parts.size();++i)
            if(parts[i].first==r && parts[i].second==c) {
                if(!hit[i]) { hit[i]=true; --remaining; }
                return true;
            }
        return false;
    }
    bool isSunk() const { return remaining==0; }
};

Practical usage notes: allocate board as vector<vector<int>> initialized to -1; when placing ship i set board[r][c] = i for each part. On a guess check bounds, read id = board[r][c]; if id == -1 it's a miss, otherwise call ships[id].hitAt(r,c) and then ships[id].isSunk() to announce e.g. "Destroyer sunk". Ensure hitAt ignores repeated hits on the same cell so the remaining counter cannot go negative. For placement, test for overlap before writing IDs and make direction generation cover all four orientations while handling edge conditions (avoid off-by-one errors).

Quick debugging tips: print ship parts after placement for visual verification, unit-test hitAt/isSunk on small cases, keep coordinate conventions consistent (0-based vs 1-based), and prefer srand(time(nullptr)) for real randomness. This design keeps logic modular, makes sink reporting trivial, and implements the class-based ideas suggested by and .

Recommended Answers

All 2 Replies

This fairly screams for user defined types. I am thinking of 2 types: cell and ship. cell would keep track of where on the board the ship is placed and which cells in the board have been selected. Each cell would have an x and a y value in addition to a character value with empty 0 being unselected, empty being selected but no ship, and 1 being ship hit in this cell. ship would indicate how many hits the ship can take before it's sunk, an array of cells declared dynamically that would keep track of how it is positioned, and an array of ints to indicate if the ship hit at a given position or not. I would also have a function to display the board indicating which cells have been selected already and the outcome of the selection. If you haven't learned about user defined types, this is the project that should do it for you.

Like the poster up there says, you could make own class called cell and put there a value like bool hasShip; Then you could implement all the usefull functions into that class, like how much ship has health left, the position of the cell, etc. It's not that hard.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.