//==================================================== includes#include <iostream>#include <iomanip>#include <string>#include <ctime> // For time()#include <cstdlib> // For srand() and rand()using namespace std;//========================================= global declarations// Damage enum defines possible values at each grid point.enum Damage {WATER_UNBOMBED, WATER_BOMBED, SHIP_UNBOMBED , SHIP_BOMBED};// The display array defines what to display for// each of the Damage enum values. Changes to the// Damage enum require this to be changed also.const char display[] = {'-', 'O', '-', 'X'};const int SHIP_SIZE = 3;const int NUMBER_OF_SHIPS = 4;const int CANAL_LENGTH = 24; // Width of the grid.Damage grid[CANAL_LENGTH]; // Records status of every grid cell.//================================================== prototypesvoid dropBomb(int coord);void executeCommand(char cmd);void findOpenWater(int positions[], int& number);void initGrid();bool isGameOver();void printGrid();//======================================================== mainint main() { srand(time(0)); // Initialize random number generator cout << "You are to find and bomb ships in the Suez Canal." << endl; cout << "Each ship is " << SHIP_SIZE << " units long." << endl; cout << "Use the b command and follow it with a coordinate to drop a bomb." << endl; char ans; do { initGrid(); // Randomly place ships on the grid. printGrid(); char commandCode; while (cin >> commandCode) { executeCommand(commandCode); if (isGameOver()) { cout << "I surrender." << endl; break; } } cout << "Do you want to play again? (y/n) "; cin >> ans; } while (ans == 'y'); return 0;}//end main//======================================================= executeCommandvoid executeCommand(char cmd) { switch (cmd) { case 'q': // quit exit(0); break; case 'b': // bomb int loc; cin >> loc; if (loc>=0 && loc<CANAL_LENGTH) { dropBomb(loc); } else { cout << "Bombing coordinate must be between 0 and " << CANAL_LENGTH-1 << endl; } printGrid(); break; default: // error cerr << "Bad input " << cmd << endl; break; }}//======================================================= dropBombvoid dropBomb(int coord) { switch (grid[coord]) { case WATER_UNBOMBED: grid[coord] = WATER_BOMBED; break; case SHIP_UNBOMBED: grid[coord] = SHIP_BOMBED; break; } return;}//======================================================= initGrid// initGrid() places random ships on the grid.void initGrid() { //-- Initialize the grid to empty water for (int i=0; i<CANAL_LENGTH; i++) { grid[i] = WATER_UNBOMBED; } //-- Make a list of where ships could be placed. int openWaterPositions[CANAL_LENGTH]; int howManyPositions; // number of elements in openWaterPositions for (int shipNum=0; shipNum < NUMBER_OF_SHIPS; shipNum++) { findOpenWater(openWaterPositions, howManyPositions); // sets both parameters if (howManyPositions == 0) { break; // we're done even if we didn't put all ships in water. } //-- Choose one of the open water positions randomly. int onePosition = rand() % howManyPositions; int start = openWaterPositions[onePosition]; //-- Put a ship starting from there to the right. for (int pos=start; pos<start+SHIP_SIZE; pos++) { grid[pos] = SHIP_UNBOMBED; } }}//====================================================== findOpenWatervoid findOpenWater(int positions[], int& number) { number = 0; // Start assuming no open water found. int consecutiveWater = 0; for (int i=CANAL_LENGTH-1; i>=0; i--) { if (grid[i]==WATER_UNBOMBED) { consecutiveWater++; if (consecutiveWater > SHIP_SIZE) { //-- record this as a possible position. positions[number] = i; number++; } } else { consecutiveWater = 0; } }}//====================================================== printGridvoid printGrid() { cout << endl; for (int i=0; i<CANAL_LENGTH; i++) { cout << " " << display[grid[i]]; } cout << endl; //-- Print coordinates. for (int coord=0; coord<CANAL_LENGTH; coord++) { cout << setw(2) << coord; } cout << endl << endl;}//====================================================== isGameOverbool isGameOver() { for (int coord=0; coord<CANAL_LENGTH; coord++) { if (grid[coord] == SHIP_UNBOMBED) { return false; } } return true;}