Question: For this project, you will be using everything we have discussed so far about programming in C++ to implement a game called Sea Battle. This
For this project, you will be using everything we have discussed so far about programming in C++ to implement a game called "Sea Battle". This is a two-player version of the popular strategy game, Battleship. This game is played on four 10x10 grids, two for each player. Each player is assigned: a primary grid, a tracking grid, and a fleet of nine ships, deployed at random within their respective primary grids. Depending on their size, the ships occupy two to five squares each, and they must be deployed in such a way that all of the ships fit within the bounds of the grid without overlapping (that is, without extending below the last row of the grid or "wrapping" from the right side of one row to the left side of the following row). The players take turns firing shots at target squares within their opponent's primary grid, one shot per turn, recording hits and misses within their respective tracking grids. The object of the game is to sink every ship in the opponent's fleet; to sink a ship, it is necessary to hit every square it occupies. The first player to sink every ship in their opponent's fleet is the winner. At the start of a game, both players launch the "Sea Battle" program on their own workstations, so that neither player can see their opponent's screen. After agreeing which player is Player 1 and which is Player 2, both players enter their respective player numbers, as well as the player number which will be given the first turn. The program then creates a primary grid and tracking grid for each player, randomly populates the primary grid with a fleet of ships, and prints the contents of both grids to the screen. The attacking player is asked to select the coordinates of a target square, which they then announce to their opponent. The coordinates are entered by both players; the target square is then marked on the tracking grid of the attacking player, and on the primary grid of the opponent. The opponent announces to the attacking player whether the shot was a "miss" (the target square was not occupied by any ship), a "hit" (the target square was occupied by a ship), or a "sink" (the target square was occupied by the last remaining square of a ship). Both players enter this information at their workstations so that their fleet counts are kept up to date. The players then reverse roles on the next turn, and continue taking shots until all of the ships in one player's fleet have been sunk. The complement of ships in each player's fleet is as follows: Quantity Ship Type Squares Code 1 Aircraft Carrier 5 A 1 Battleship 4 B 2 Cruiser 3 C 2 Submarine 3 S 3 Patrol Boat 2 P The squares occupied by each ship are indicated by their respective letter codes within the primary grid. As the players take their shots, the target squares are marked with a "/" (a "splash mark") if the shot was a miss, or an "X" (a "bang mark") if the shot resulted in a hit or a sink. See the example shown below, which depicts the output from the first few turns of a typical game. The player's input is shown in bold. Welcome to ...
_____ _________ ____ ___ ______________ ________ / ___// ____/ | / __ )/ |/_ __/_ __/ / / ____/ / \__ \/ __/ / /| | / __ / /| | / / / / / / / __/ / / ___/ / /___/ ___ | / /_/ / ___ |/ / / / / /___/ /___/_/ /____/_____/_/ |_| /_____/_/ |_/_/ /_/ /_____/_____(_)
Will you play as Player (1) or as Player (2)? 1
Which player will take the first turn (1/2)? 1
PRIMARY A B C D E F G H I J 1 - - - - - - - - - - 2 - [C][C][C] - [S][S][S] - - 3 [P][P] - - - - - - - - 4 - - - - - - - - - - 5 - - - - [P][P][B] - - - 6 - - - [C] - - [B] - - - 7 - - - [C] - - [B] - - [P] 8 - - - [C] - - [B] - - [P] 9 - - - - - - [S][S][S] - 10 - [A][A][A][A][A] - - - - TRACKING A B C D E F G H I J 1 - - - - - - - - - - 2 - - - - - - - - - - 3 - - - - - - - - - - 4 - - - - - - - - - - 5 - - - - - - - - - - 6 - - - - - - - - - - 7 - - - - - - - - - - 8 - - - - - - - - - - 9 - - - - - - - - - - 10 - - - - - - - - - - Player: 9, Opponent: 9. Choose Your Target (in tracking grid): E5 Was this a (M)iss, a (H)it, or a (S)ink? m PRIMARY A B C D E F G H I J 1 - - - - - - - - - - 2 - [C][C][C] - [S][S][S] - - 3 [P][P] - - - - - - - - 4 - - - - - - - - - - 5 - - - - [P][P][B] - - - 6 - - - [C] - - [B] - - - 7 - - - [C] - - [B] - - [P] 8 - - - [C] - - [B] - - [P] 9 - - - - - - [S][S][S] - 10 - [A][A][A][A][A] - - - - TRACKING A B C D E F G H I J 1 - - - - - - - - - - 2 - - - - - - - - - - 3 - - - - - - - - - - 4 - - - - - - - - - - 5 - - - - / - - - - - 6 - - - - - - - - - - 7 - - - - - - - - - - 8 - - - - - - - - - - 9 - - - - - - - - - - 10 - - - - - - - - - - Player: 9, Opponent: 9. Ask Opponent For Target: e5 * * * * B O O M * * * * Your opponent scored a hit! Did it sink a ship (Y/N)? n PRIMARY A B C D E F G H I J 1 - - - - - - - - - - 2 - [C][C][C] - [S][S][S] - - 3 [P][P] - - - - - - - - 4 - - - - - - - - - - 5 - - - - X [P][B] - - - 6 - - - [C] - - [B] - - - 7 - - - [C] - - [B] - - [P] 8 - - - [C] - - [B] - - [P] 9 - - - - - - [S][S][S] - 10 - [A][A][A][A][A] - - - - TRACKING A B C D E F G H I J 1 - - - - - - - - - - 2 - - - - - - - - - - 3 - - - - - - - - - - 4 - - - - - - - - - - 5 - - - - / - - - - - 6 - - - - - - - - - - 7 - - - - - - - - - - 8 - - - - - - - - - - 9 - - - - - - - - - - 10 - - - - - - - - - - Player: 9, Opponent: 9. Choose Your Target (in tracking grid): f5 Was this a (M)iss, a (H)it, or a (S)ink? h PRIMARY A B C D E F G H I J 1 - - - - - - - - - - 2 - [C][C][C] - [S][S][S] - - 3 [P][P] - - - - - - - - 4 - - - - - - - - - - 5 - - - - X [P][B] - - - 6 - - - [C] - - [B] - - - 7 - - - [C] - - [B] - - [P] 8 - - - [C] - - [B] - - [P] 9 - - - - - - [S][S][S] - 10 - [A][A][A][A][A] - - - - TRACKING A B C D E F G H I J 1 - - - - - - - - - - 2 - - - - - - - - - - 3 - - - - - - - - - - 4 - - - - - - - - - - 5 - - - - / X - - - - 6 - - - - - - - - - - 7 - - - - - - - - - - 8 - - - - - - - - - - 9 - - - - - - - - - - 10 - - - - - - - - - - Player: 9, Opponent: 9. Ask Opponent For Target: d5 PRIMARY A B C D E F G H I J 1 - - - - - - - - - - 2 - [C][C][C] - [S][S][S] - - 3 [P][P] - - - - - - - - 4 - - - - - - - - - - 5 - - - / X [P][B] - - - 6 - - - [C] - - [B] - - - 7 - - - [C] - - [B] - - [P] 8 - - - [C] - - [B] - - [P] 9 - - - - - - [S][S][S] - 10 - [A][A][A][A][A] - - - - TRACKING A B C D E F G H I J 1 - - - - - - - - - - 2 - - - - - - - - - - 3 - - - - - - - - - - 4 - - - - - - - - - - 5 - - - - / X - - - - 6 - - - - - - - - - - 7 - - - - - - - - - - 8 - - - - - - - - - - 9 - - - - - - - - - - 10 - - - - - - - - - - Player: 9, Opponent: 9. Choose Your Target (in tracking grid): g5 Was this a (M)iss, a (H)it, or a (S)ink? s PRIMARY A B C D E F G H I J 1 - - - - - - - - - - 2 - [C][C][C] - [S][S][S] - - 3 [P][P] - - - - - - - - 4 - - - - - - - - - - 5 - - - / X [P][B] - - - 6 - - - [C] - - [B] - - - 7 - - - [C] - - [B] - - [P] 8 - - - [C] - - [B] - - [P] 9 - - - - - - [S][S][S] - 10 - [A][A][A][A][A] - - - - TRACKING A B C D E F G H I J 1 - - - - - - - - - - 2 - - - - - - - - - - 3 - - - - - - - - - - 4 - - - - - - - - - - 5 - - - - / X X - - - 6 - - - - - - - - - - 7 - - - - - - - - - - 8 - - - - - - - - - - 9 - - - - - - - - - - 10 - - - - - - - - - - Player: 9, Opponent: 8. Ask Opponent For Target: f5 * * * * B O O M * * * * Your opponent scored a hit! Did it sink a ship (Y/N)? y PRIMARY A B C D E F G H I J 1 - - - - - - - - - - 2 - [C][C][C] - [S][S][S] - - 3 [P][P] - - - - - - - - 4 - - - - - - - - - - 5 - - - / X X [B] - - - 6 - - - [C] - - [B] - - - 7 - - - [C] - - [B] - - [P] 8 - - - [C] - - [B] - - [P] 9 - - - - - - [S][S][S] - 10 - [A][A][A][A][A] - - - - TRACKING A B C D E F G H I J 1 - - - - - - - - - - 2 - - - - - - - - - - 3 - - - - - - - - - - 4 - - - - - - - - - - 5 - - - - / X X - - - 6 - - - - - - - - - - 7 - - - - - - - - - - 8 - - - - - - - - - - 9 - - - - - - - - - - 10 - - - - - - - - - - Player: 8, Opponent: 8. Choose Your Target (in tracking grid):
(The ship deployment shown here is random, of course, so your ships will be deployed differently.) The attached archive is an incomplete implementation of the game. Use this "skeleton program" as a starting point, referring to the "Project #2 Design Tips" (see below) for more information about how your completed game should work. As you work through this assignment, you can test your program on your own by launching two instances of the program, one for each "player". As you take turns for both players, I suggest alternating between minimizing and restoring the corresponding windows, so that only one is visible at a time. Once your program is running, you can use our weekly lab meetings to pair up with a classmate, so that the two of you can test your own versions of this program with a live human opponent. You may even consider switching workstations, so that each player tries the other player's version of the program as they play through the game.
Your game logic for Project #2 should follow this sequence. Important implementation details are included in this description, so read it carefully as you plan your version of this program! In this description, "Player A" refers to the player who is taking a turn, and "Player B" refers to their opponent.
To begin working on this assignment, unpack the five source code files in the attached archive into a new folder. Next, create a new project in this folder, then add the five source code files to the project. To do this, select "New" from the Dev-C++ "File" menu, and choose "Project". Next, choose "Console Application" in the "New Project" dialog box, change the project name to "Project2", and click "OK". Finally, select the folder in which you unpacked the source files from Blackboard as the location for the project ".dev" file (this is the file you can double-click later to re-open the project). Dev-C++ will create a skeleton "main.cpp" file for you. Close this file, remove it from the project, and add the five source files to the project. To add or remove files to a project, right-click the project name in the "Project" window and choose "Add Files" or "Remove Files".
Read the program files carefully. They contain a "skeleton" (a partial implementation) of the game of "Sea Battle". This includes two user-defined data types: a Cell (a struct containing row and col members, representing the row and column of the coordinate), and a Grid (a class containing public methods for setting/getting a cell of the grid, for deploying the fleet into the grid, and for printing the grid to the screen). With the exception of the "deploy_fleet()" method, these data types are fully defined for you; refer to the comments included in the program files for details. You will find an "// INSERT YOUR CODE HERE" comment at the beginning of blocks that are incomplete, in both the "main.cpp" and "grid.cpp" program files. These blocks will contain a series of comments which will provide an outline for a suggested implementation; it is up to you to write the code to complete these blocks. Before you begin, replace the "
Notice that the respective sizes of both the primary and tracking grids are entered into your program using constants. Both grids are initialized by the constructor, which fills them with dashes ('-'), indicating an "untouched" square.
To complete the program, you must supply the main game logic, as well as the necessary code in the "deploy_fleet()" method of the Grid class to populate the primary grid with a randomly-deployed fleet of ships. The comments included in the skeleton program are meant to serve as an outline for your implementation, although you should feel free to experiment with different approaches.
When deploying your fleet, the location and orientation (horizontal or vertical) of every ship should be chosen at random, and the ships should be positioned so that they remain within the bounds of the grid and do not overlap any other ships. That is, no vertically-positioned ship should extend beyond the bottom of the grid, and no horizontally-positioned ship should "wrap around" from the right side of one row into the left side of the following row. Ships may be positioned in adjacent rows or columns, as long as no single square is occupied by more than one ship. To do this, your program will need to randomly select the orientation of the ship, and the row and column of the first square of the ship, and then "scan ahead" into the adjacent columns or rows (depending on the orientation) to see if all of the squares needed by the ship are empty (that is, if they contain dashes). If even one of them is occupied, another position and orientation must be chosen and scanned, but if no occupied squares are found, that means that the "footprint" is empty, and the ship can be safely positioned within it by filling each square in the "footprint" with the corresponding letter for the ship (the code for filling in the ships is provided for you). Repeat this process until all nine ships have been positioned within the grid.
The program should begin by asking both players for their number (1 or 2), and which player will be the one to take the first turn. After deciding between themselves which player is which number, and which player should go first, that player should enter this information at the prompts.
At the start of each turn, the program should print the primary grid and the tracking grid to the screen (use the print() method of the Grid class to do this). See the sample output in the assignment instructions for an illustration of what your output should look like.
The program should prompt "Player A" (the player whose turn it is) to enter the coordinates (the row letter and column number) of the target square. Use the "get_cell()" function included in the skeleton program (look in the "util.cpp" program file) to do this; this function will validate the player's input, checking to see if the row and column are within range; if either one is out of range, the program will ask the player to enter their input again. "Player A" should then announce the coordinates of the target square to "Player B", and "Player B" should announce to "Player A" whether their shot was a "miss", a "hit", or a "sink", as described in the instructions. "Player A" should be prompted to enter this information by entering an 'M', an 'H', or an 'S'. If the shot was a miss, a "splash mark" ('/') should be placed in the target square in the tracking grid; if it was a hit or a sink, a "bang mark" ('X') should be placed in the target square instead. If the shot was a sink, the program should also decrement the opponent's fleet count by one. Finally, the program should check both fleet counts; if either has reached zero, the game is over; if they have not, the other player takes the next turn.
During "Player A"'s turn, the program should prompt "Player B" to enter the coordinates of the target square selected by "Player A". This shot is then recorded in "Player B"'s primary grid. Before placing the 'X' into the primary grid, the program should check the target square to see if it is already occupied by a ship (which would result in either a hit or a sink); if the square is occupied, a "BOOM!" message should be printed. "Player B" should then be prompted to indicate whether or not this hit sank the ship (for the sake of simplicity, your version of this game does not have to detect sunken ships). "Player B" should then announce to "Player A" whether the shot was a miss, a hit, or a sink. Finally, the program should check both fleet counts; if either has reached zero, the game is over; if they have not, the other player takes the next turn.
Repeat at Step 7 until one of the fleet counts reaches zero. If the player's own fleet count reaches zero, a "GAME OVER" message should be displayed; if the opponent's fleet count reaches zero, a congratulatory message should be printed.
Step by Step Solution
There are 3 Steps involved in it
Get step-by-step solutions from verified subject matter experts
