c++ program DESCRIPTION The game \"Battleship\" consists of a split board where
ID: 3805937 • Letter: C
Question
c++ program
DESCRIPTION
The game "Battleship" consists of a split board where each player places various objects (battle ships) along a 2-dimensional grid outside of the view of their opponent. Each player's turn consists of guessing a location on their opponent's board where a hidden ship might reside. If the player guesses a location coinciding with their opponent's ship, their ship is considered "hit" and their opponent confirms verbally by saying "hit," and the player continues to guess locations. If the player guesses a location that is empty on their opponent's board, their opponent confirms verbally by saying "miss," and the player's turn ends.
When an opponent's ship's locations have all been detected ("hit"), the object is considered "sunk," and is confirmed by the opponent by saying "hit and sunk" when the last location of a ship has been determined.
This programming project aims to develop the foundation of a larger Battleship game program by first establishing functions and routines that verify valid game boards for play.
The Ships
In Battleship, there are 5 objects involved in gameplay:
(A)ircraft carrier - length 5
(B)attleship - length 4
(C)ruiser - Length 3
(D)estroyer - Length 2
(S)ubmarine - Length 3
The Board
Boardplay involves a 2-dimensional grid, with lettered rows and numbered columns. Entities on the board are referenced by {number,letter} pairs, such as "A3"
The board consists of 10 rows (A-J) and 10 columns (1-10).
Game Initialization
The game begins with players placing each of the 5 ship objects in distinct positions on the game board, in strictly horizontal or strictly vertical orientation. Ships may not be placed at angles, or dangle off the valid 10x10 grid of the game board.
Your programming task
Your programming task for this project is to read in a board representing an initial game layout. Your program will need to:
Prompt the user for a file containing a valid board. If invalid, print an error message and prompt again.
Upon opening the file, your task is to verify:
All ships are placed on the board.
All ship locations are valid.
All ship lengths are valid.
The board dimensions in the file are valid.
A valid board file consists of comma-separated fields. Each field is either blank or contains a single lower-case letter from the set {a,b,c,d,s}, corresponding to the 5 ship types listed above.
An example of valid board content would be:
,,,,,c,,,a
b,b,b,b,,c,,,a
,,,,,c,,,a
,,,,s,,,,a
,,,,s,,,,a
,,,,s,,,,
,,,,,,,,
,,,,,,,,
,,d,d,,,,,
The following properties are imposed on the input file:
There are no spaces between commas or characters.
All letters are lowercase.
All letters are taken from the set {a,b,c,d,s}.
There are exactly ten rows
There are exactly 9 commas in each row.
Program Output
Your program must output only the following, corresponding to input files with the respective properties:
"Board is valid."
"Board is invalid: " and then:
"Board file could not be read."
"Board has too many rows."
"Board has too few rows."
"Board has too many columns in row ."
"Board has too few columns in row ."
"Board has invalid entries."
"Board has incorrect format on row at column starting at ."
where "" and "" represent their respective locations in the input file.
Explanation / Answer
#include <iostream>
#include <string>
using namespace std;
const int MAXWIDTH = 15;
const int MAXHEIGHT = 10;
const int SHIPTYPE = 5;
const char WATER = 247; //ascii value
const char HIT = 'X';
const char isSHIP = 'S';
const char isMISS = '0';
struct LOCATION_POINT {
//coordinates
int X;
int Y;
};
struct SHIP_STRUCT {
string ShipName;
//grid points len
int len;
// coordinates
LOCATION_POINT LocationGrid[5];
bool isHitFlas[5];
}ship[SHIPTYPE];
struct BatttleShip_Player {
char grid[MAXWIDTH][MAXHEIGHT];
}player[3];
enum SHIP_DIRECTION {HORIZONTAL,VERTICAL};
struct PLACESHIPS {
SHIP_DIRECTION dhipDirection;
SHIP_STRUCT shipType;
};
bool isGameON = false;
// function prototype declarations
void ShipsLoading();
void BoardReset();
void BuildBoard(int);
PLACESHIPS inputShip_placement();
bool Attack(int&,int&,int);
bool isGameOver(int);
int main()
{
ShipsLoading();
BoardReset();
//ships placing.. looping each player
for (int player=1; player<3; ++player)
{
// placing each ship
for (int currShip=0; currShip<SHIPTYPE; ++currShip)
{
// printing gameboard
system("cls");
BuildBoard(player);
// printing instructions
cout << " Game Rules for Player " << player <<endl;
cout << "place the ships and format should be: "<<endl;
cout << "Ship Face (0 -> Horizontal, 1 -> Vertical)"<<endl;
cout << "Eg: 0 7 2 means m and n coordinates are 7 and 2 and going ship horizontally";
cout << "Place ship: " << ship[currShip].ShipName << " having length of " << ship[currShip].len <<endl;
cout << "Enter your locations ";
PLACESHIPS shipPlacement;
shipPlacement.shipType.LocationGrid[0].X = -1;
while (shipPlacement.shipType.LocationGrid[0].X == -1)
{
shipPlacement = inputShip_placement();
}
// integrating userdata
shipPlacement.shipType.len = ship[currShip].len;
shipPlacement.shipType.ShipName = ship[currShip].ShipName;
// addding grid points to board
player[player].grid[shipPlacement.shipType.LocationGrid[0].X][shipPlacement.shipType.LocationGrid[0].Y] = isSHIP;
// gathering all ship loations
for (int i=1; i<shipPlacement.shipType.len; ++i)
{
if (shipPlacement.dhipDirection == HORIZONTAL){
shipPlacement.shipType.LocationGrid[i].X = shipPlacement.shipType.LocationGrid[i-1].X+1;
shipPlacement.shipType.LocationGrid[i].Y = shipPlacement.shipType.LocationGrid[i-1].Y; }
if (shipPlacement.dhipDirection == VERTICAL){
shipPlacement.shipType.LocationGrid[i].Y = shipPlacement.shipType.LocationGrid[i-1].Y+1;
shipPlacement.shipType.LocationGrid[i].X = shipPlacement.shipType.LocationGrid[i-1].X; }
player[player].grid[shipPlacement.shipType.LocationGrid[i].X][shipPlacement.shipType.LocationGrid[i].Y] = isSHIP;
}
}
}
// now playing game
isGameON = true;
int curr_ship = 1;
do {
// attacking
int enemy_ship;
if (curr_ship == 1) enemy_ship = 2;
if (curr_ship == 2) enemy_ship = 1;
system("cls");
BuildBoard(enemy_ship);
bool validInput = false;
int m,n;
while (validInput == false) {
validInput = Attack(m,n,curr_ship);
}
// after attack, checking hit or miss
if (player[enemy_ship].grid[m][n] == isSHIP) player[enemy_ship].grid[m][n] = HIT;
if (player[enemy_ship].grid[m][n] == WATER) player[enemy_ship].grid[m][n] = isMISS;
// check game won or not
int playerWin = isGameOver(enemy_ship);
if (playerWin != 0) {
isGameON = false;
break;
}
// switching ships..
curr_ship = (curr_ship == 1) ? 2 : 1;
} while (isGameON);
system("cls");
cout << " congrats !! Player " << curr_ship << " has won game! "<<endl;";
system("pause");
return 0;
}
bool isGameOver(int enemyPLAYER)
{
bool won = true;
// checking enemy board
for (int z=0; z<MAXWIDTH; ++z){
for (int n=0; n<MAXHEIGHT; ++n){
// if ship exist, then game is not over
if (player[enemyPLAYER].grid[z][n] = isSHIP)
{
won = false;
return won;
}
}
}
return won;
}
bool Attack(int& m, int& n, int _player)
{
cout << " Captain " << _player << ", enter ship coordinates to attack: ";
bool validInput = false;
cin >> m >> n;
if (m<0 || m>=MAXWIDTH) return validInput;
if (n<0 || n>=MAXHEIGHT) return validInput;
validInput = true;
return validInput;
}
PLACESHIPS inputShip_placement()
{
int depth, m, n;
PLACESHIPS temp;
temp.shipType.LocationGrid[0].X = -1;
// rading three values from user
cin >> depth >> m >> n;
if (depth!=0 && depth!=1) return temp;
if (m<0 || m>=MAXWIDTH) return temp;
if (n<0 || n>=MAXHEIGHT) return temp;
// valid data
temp.dhipDirection = (SHIP_DIRECTION)depth;
temp.shipType.LocationGrid[0].X = m;
temp.shipType.LocationGrid[0].Y = n;
return temp;
}
void ShipsLoading()
{
ship[0].ShipName = "SHIP_CRUISER"; ship[0].len = 2;
ship[1].ShipName = "SHIP_Frigate"; ship[1].len = 3;
ship[2].ShipName = "Sub_marine"; ship[2].len = 3;
ship[3].ShipName = "SHIPESCORT"; ship[3].len = 4;
ship[4].ShipName = "Battle_Ship"; ship[4].len = 5;
}
void BoardReset()
{
// resseting board for all players
for (int currPlayer=1; currPlayer<3; ++currPlayer)
{
for (int z=0; z<MAXWIDTH; ++z){
for (int n=0; n<MAXHEIGHT; ++n){
player[currPlayer].grid[z][n] = WATER;
}
}
}
}
void BuildBoard(int curr_ship)
{
// print board for given player
cout << "BatttleShip_Player " << curr_ship << " BOARD"<<endl;
cout << "**** ----------------------------------- *****"<<endl;
cout << " ";
for (int z=0; z<MAXWIDTH; ++z) {
if (z < 10)
//after one character placing two space
cout << z << " ";
else if (z >= 10)
// fr two characters long placing one spce
cout << z << " ";
}
cout <<endl;
// printing location coordinates
for (int n=0; n<MAXHEIGHT; ++n){
for (int z=0; z<MAXWIDTH; ++z){
if (z==0) cout << n << " ";
// extra space for one character
if (z<10 && z==0) cout << " ";
// display ships
if (isGameON == false) cout << player[curr_ship].grid[z][n] << " ";
// not showing ships, if ship not there
if (isGameON == true && player[curr_ship].grid[z][n] != isSHIP)
{cout << player[curr_ship].grid[z][n] << " ";}
else if (isGameON == true && player[curr_ship].grid[z][n] == isSHIP)
{cout << WATER << " ";}
if (z == MAXWIDTH-1) cout <<endl;
}
}
}
Related Questions
Navigate
Integrity-first tutoring: explanations and feedback only — we do not complete graded work. Learn more.