Create a basic battleship game of C++ on a 10 by 10 grid using arrays for human
ID: 3818604 • Letter: C
Question
Create a basic battleship game of C++ on a 10 by 10 grid using arrays for human vs computer interaction.
The ships that will be used:
Carrier: 5 spots
Battleship: 4 spots
Cruiser: 3 spots
Submarine: 3 spots
Destroyer: 2 spots
The program should have functions.
The computer should be able to randomly place each of the ships legally and randomly hit a ship, but once the computer knows it has hit a ship it should make an educated guess where to hit so that it can get rid of the ship
The program should display hit and miss locations using (A-J) for rows
and (1-10) for columns and the user should be able to see their placement of the ships on the (ocean) grid.
Each turn, the user should get an update on the (target) grid from misses and hits as well on the board.
Please use comments. Also, if any of this sounds confusing it's pretty much normal battle ship but the 2nd player is the computer.
Explanation / Answer
We write the pseudo code for our battleship game .
#include <iostream> #include <string> #include <stdlib.h> #include <iomanip> //header which provides manipulations for parameters #include <vector> //header for providing manipulations for vectors //variables for storing current status of ships of player on the board const int empty = 0; // contains water const int occupied = 1; // contains a ship const int missed = 1; // shot into ocean const int hit = 0; // shot and hit using namespace std; //C++ standard library features are declared here
//intialise board coordinates and ship types const int BOARD_WIDTH = 10; const int BOARD_HEIGHT = 10; const int SHIP_TYPES = 5; const char isWATER = 247; //ASCII Character Code const char isHIT = 'X'; //if player ship is hit ,denote as 'X' const char isSHIP = 'S'; //structure for creating a point(X,Y) on the grid struct POINT { //A location on the grid defined //by X(horizontal) Y(vertical) coordinates int X; int Y; }; struct SHIP { //Ship name--can be Carrier,Battleship,Cruiser,Sumarine,Destroyer string name; //Total points occupied on the grid int length; //Coordinates of those points POINT onGrid[5]; //0-4 max length of biggest ship //Whether or not those points are a "hit" bool hitFlag[5]; }ship[SHIP_TYPES]; struct PLAYER { char grid[BOARD_WIDTH][BOARD_HEIGHT]; }player[3]; //player's 1 & 2,i.e. computer enum DIRECTION {HORIZONTAL,VERTICAL}; //structure for placing ship on board, using direction and shiptype struct PLACESHIPS { DIRECTION direction; SHIP shipType; }placeShip; //Functions required for playing the game void LoadShips(); //Load ships onto board void ResetBoard(); //Reset board after game finishes void DrawBoard(int);//Update board after player places ship PLACESHIPS UserInputShipPlacement();//call user ship placementmethod bool UserInputAttack(int&,int&,int); bool GameOverCheck(int);//check if game is over between players 1 and 2
int board[ 10 ][ 10 ]; // Two-dimensional array for gameboard.
//First, we initialise the game board void initialize_board( int array1[ 10 ][ 10 ] ) { // create a blank board for (int x=0; x<10; x++) { for (int y=0; y<10; y++) { array1[x][y] = occupied; } } } void print_board(int array2[10][10]) { for(char a = 'A'; a <= 'J'; a++) { //letter coordinates (A-J) for rows cout << setw(5) << a; //sets field width to be 5 for variable a } cout << endl; for(int i = 1; i <= 10; i++) { //number coordinates (1-10) for columns if(i == 10) cout << i; else cout << " " << i ; for(int j = 0; j < 10 ; j++) { if(array2[i][j] == occupied || array2[i][j] == empty){ cout << setw(5) << " |" ; } else if(array2[i][j] == missed ) { cout << setw(5) << "O|";//if ship missed display O| } else if(array2[i][j] == hit ) { cout << setw(5) << "X|";//if ship hit display X } } cout << " "; } } class cShip { int x1, y1, x2, y2; // The position of the front and back of the ship int size; int damage[]; // for storing the damage caused by opponent or enemy public: cShip(int x1, int y1, int x2, int y2, int size); // constructor for ship ~cShip(); // destructor for destroying the damage array of ship bool isDestroyed(); // for checking if ship is destroyed bool is3(int x, int y); }; int main() { initialize_board(board); determine_player_choice(); print_board(board); LoadShips(); ResetBoard();//reset board for next game loop
//"Place Ships" phase of game //Loop through each player... for (int plyr=1; plyr<3; ++plyr) { //Loop through each ship type to place for (int thisShip=0; thisShip<SHIP_TYPES; ++thisShip) { //Display gameboard for player system("cls"); DrawBoard(plyr); //Give instructions to the player for playingbattleship cout << " "; cout << "INSTRUCTIONS (Player " << plyr << ") "; cout << "You are about to place your ships. Format should be: "; cout << "Facing (0:Horizontal,1:Vertical), X (top-row) coords, Y (left-side) coords "; cout << "Example: 0 4 5 This would place a ship beginning at X:4 Y:5 going horizontal "; cout << "Ship to place: " << ship[thisShip].name << " which has a length of " << ship[thisShip].length << " "; cout << "Where do you want it placed? "; //Get input from user and loop until valid data is returned PLACESHIPS aShip; aShip.shipType.onGrid[0].X = -1; while (aShip.shipType.onGrid[0].X == -1) { aShip = UserInputShipPlacement(); } //Combine user data with "this ship" data aShip.shipType.length = ship[thisShip].length; aShip.shipType.name = ship[thisShip].name; //Add the first grid point to the current player's game board player[plyr].grid[aShip.shipType.onGrid[0].X] [aShip.shipType.onGrid[0].Y] = isSHIP; //Determine ALL grid points based on length and direction for (int i=1; i<aShip.shipType.length; ++i) { if (aShip.direction == HORIZONTAL){ aShip.shipType.onGrid[i].X = aShip.shipType.onGrid[i-1].X+1; aShip.shipType.onGrid[i].Y = aShip.shipType.onGrid[i-1].Y; } if (aShip.direction == VERTICAL){ aShip.shipType.onGrid[i].Y = aShip.shipType.onGrid[i-1].Y+1; aShip.shipType.onGrid[i].X = aShip.shipType.onGrid[i-1].X; } //Add the REMAINING grid points to our current players game board player[plyr].grid[aShip.shipType.onGrid[i].X] [aShip.shipType.onGrid[i].Y] = isSHIP; } //Loop back through each ship type } //Loop back through each player } //Ready to play the game gameRunning = true; int thisPlayer = 1; do { //Because we are ATTACKING now, the //opposite players(Player 2) board is the display board int enemyPlayer; if (thisPlayer == 1) enemyPlayer = 2; if (thisPlayer == 2) enemyPlayer = 1; system("cls"); DrawBoard(enemyPlayer); //Get attack coords from this player bool Input = false; int x,y; while (Input == false) { Input = UserInputAttack(x,y,thisPlayer); } //Check board; if a ship is there, set as HIT.. otherwise MISS if (player[enemyPlayer].grid[x][y] == isSHIP) player[enemyPlayer].grid[x][y] = isHIT; if (player[enemyPlayer].grid[x][y] == isWATER) player[enemyPlayer].grid[x][y] = isMISS; //Check to see if the game is over //If 0 is returned, nobody has won yet int aWin = GameOverCheck(enemyPlayer); if (aWin != 0) { gameRunning = false; break; } //Alternate between each player as we loop back around thisPlayer = (thisPlayer == 1) ? 2 : 1; } while (gameRunning); system("cls"); cout << " CONGRATULATIONS!!! PLAYER " << thisPlayer << " HAS WON THE GAME! "; system("pause"); return 0; }
bool GameOverCheck(int enemyPLAYER) { bool winner = true; //Loop through enemy board for (int w=0; w<BOARD_WIDTH; ++w){ for (int h=0; h<BOARD_HEIGHT; ++h){ //If any ships remain, game is NOT over if (player[enemyPLAYER].grid[w][h] = isSHIP) { winner = false; return winner; } }} //If we get here, somebody won, game over! return winner; } bool UserInputAttack(int& x, int& y, int theplayer) { cout << " PLAYER " << theplayer << ", ENTER COORDINATES TO ATTACK: "; bool Input = false; cin >> x >> y; if (x<0 || x>=BOARD_WIDTH) return Input; if (y<0 || y>=BOARD_HEIGHT) return Input; Input = true; return Input; } PLACESHIPS UserInputShipPlacement() { int d, x, y; PLACESHIPS tmp; tmp.shipType.onGrid[0].X = -1; //Get 3 integers from user cin >> d >> x >> y; if (d!=0 && d!=1) return tmp; if (x<0 || x>=BOARD_WIDTH) return tmp; if (y<0 || y>=BOARD_HEIGHT) return tmp; //Good data tmp.direction = (DIRECTION)d; tmp.shipType.onGrid[0].X = x; tmp.shipType.onGrid[0].Y = y; return tmp; } void LoadShips() { //Sets the default data for the ships //we plan to include in the game //IMPORTANT!! > MUST MATCH SHIP_TYPES -Default=5 (0-4) ship[0].name = "Carrier"; ship[0].length = 5; ship[1].name = "Battleship"; ship[1].length = 4; ship[2].name = "Cruiser"; ship[2].length = 3; ship[3].name = "Submarine"; ship[3].length = 3; ship[4].name = "Destroyer"; ship[4].length = 2; } void ResetBoard() { //Loop through each player for (int plyr=1; plyr<3; ++plyr) { //For each grid point, set contents to 'water' for (int w=0; w<BOARD_WIDTH; ++w){ for (int h=0; h<BOARD_HEIGHT; ++h){ player[plyr].grid[w][h] = isWATER; }} //Loop back to next player } } void DrawBoard(int thisPlayer) { //Draws the board for a player (thisPlayer) cout << "PLAYER " << thisPlayer << "'s GAME BOARD "; //Loop through top row (i.e.board_width) and number of columns cout << " "; for (int w=0; w<BOARD_WIDTH; ++w) { if (w < 10) //Numbers only 1 character long, add two spaces after cout << w << " "; else if (w >= 10) //Numbers 2 characters long, add only 1 space after cout << w << " "; } cout << " "; //Loop through each grid point and display to console for (int h=0; h<BOARD_HEIGHT; ++h){ for (int w=0; w<BOARD_WIDTH; ++w){ //If this is the FIRST (left) grid point, number the grid first if (w==0) cout << h << " "; //If h was 1 character long, add an extra space to keep numbers lined up if (w<10 && w==0) cout << " "; //Display contents of this grid (if game isn't running yet, we are placing ships //so display the ships if (gameRunning == false) cout << player[thisPlayer].grid[w][h] << " "; //Don't show ships, BUT show damage if it's hit if (gameRunning == true && player[thisPlayer].grid[w][h] != isSHIP) { cout << player[thisPlayer].grid[w][h] << " ";} else if (gameRunning == true && player[thisPlayer].grid[w][h] == isSHIP) { cout << isWATER << " ";} if (w == BOARD_WIDTH-1) cout << " "; } } }