This is working version of a one-dimensional Battleship game. It places multiple ships on a one-dimensional grid (the Suez Canal).
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 |
// battleship3a/main.cpp -- Version 3a of Battleship game. // Fred Swartz, 2003-11-25 // This second version adds the following to version 2. // * Places multiple ships randomly on grid. // // FUNCTIONALITY TO BE ADDED // * Make it two-dimensional. // * Should be a developer command to display where ships are. // // USER INTERFACE // * Not robust - crashes if bombing coordinate missing. //==================================================== 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. //================================================== prototypes void dropBomb(int coord); void executeCommand(char cmd); void findOpenWater(int positions[], int& number); void initGrid(); bool isGameOver(); void printGrid(); //======================================================== main int 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 //======================================================= executeCommand void 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; } } //======================================================= dropBomb void 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; } } } //====================================================== findOpenWater void 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; } } } //====================================================== printGrid void 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; } //====================================================== isGameOver bool isGameOver() { for (int coord=0; coord<CANAL_LENGTH; coord++) { if (grid[coord] == SHIP_UNBOMBED) { return false; } } return true; } |