- You must haveat leastthe following classes
- Each class must be in its own file
- All functions/methods must have type hints on their parameters and the return type
You are of course allowed to have more than these classes (I certainly did) but you must have the ones specified and they must be named exactly as above.
rmat
The configuration file has the following format
num_rows num_cols first_ship_name first_ship_length second_ship_name second_ship_length third_ship_name thrid_ship_name ...
All ship names will begin with a unique character and will not start with X, O, or * (the hit, miss, and blank characters). This will be important later when we are displaying the ships on the board.
As an example, the classic game of battleship has the following configuration file
10 10 Patrol 2 Submarine 3 Destroyer 3 Battleship 4 Carrier 5
These contents of these files are left up to the user but will always be correctly formated and logically consistent. For example, there will never be a configuration file where the length of the ship is larger than one of the board's dimensions. Another legal configuration file could be
20 13 Anaconda 8 RaceCar 3 SkyScraper 12 Banana 6
Notice that
- The board is a different size. 20 X 13 as opposed to 10 X 10
- The "ships" are different
- There are a different number of ships. 4 instead of 5
Setting Up The Game
For each player in the game
- Ask the player for their name. Each player's name must be unique. If they enter the same name as the other player they should be told this and asked for a new name. This repeats until the user finally enters a valid name.
- Ask them where they want to place each ship.
- Ships should be placed in the order they are found within the configuration file.
- First, ask the user whether they want to place the ship
horizontal
orvertical
.
- Anyprefixof
horizontal
orvertical
should be accepted as that word. For example, h, hori, horiz, would all meanhorizontal
and v, vert, verti would all meanhorizontal
.
- Then ask them for coordinate they would like to place the ship in the form
row, col
- Horizontal ships are placed left to right and vertical ships are placed top to bottom.
- If the user enters invalid input anywhere along the way they should be told what they did wrong and then you start anew at step 2.2.
Invalid Ship Placements and Response
A ship placement is invalid if
- An orientation that is not a prefix of either
horizontal
orvertical
was entered.
{user_input} does not represent an Orientation
- The location is not in the form
row, col
{user_input} is not in the form x,y
- Either row or col is not an integer
- row: {row} is not a valid value for row.\n It should be an integer between 0 and {num_rows - 1}
- col:
{col} is not a valid value for column.\n It should be an integer between 0 and {num_cols - 1}
- The coordinate is out of bounds
Cannot place {ship} {direction} at {row}, {col} because it would be out of bounds.
- If, based on the ship's orientation, placing the ship at that location would cause part of the ship to be placed out of bounds
Cannot place {ship} {direction} at {row}, {col} because it would end up out of bounds.
- Placing the ship at that location would cause it to overlap with another ship
Cannot place {ship} {direction} at {row}, {col} because it would overlap with {overlapping_ships}.
- overlapping_ships is a list of ship initials this ship would overlap with sorted alphabetically
The Gameplay Loop
On each players turn
- Ask them for the location that they want to fire at in the form
row, col
. If they enter an invalid firing location tell them what is wrong with their input and continue to ask them for a new location they enter a valid location.
- Shoot that spot
- Display
Miss
if they missed
- Display
You hit {player_name}'s {ship_name}
if you hit a ship
- Display
You destroyed {player_name}'s {ship_name}
if you destroyed it.
- Switch to the next player's turn.
The game ends when all of a player's ships have been destroyed. A ship is destroyed when all of its sections have been hit.
Invalid Firing Locations
A Firing Location is invalid if
- The input is not in the form
row, col
{user_input is not a valid location.\n Enter the firing location in the form row, column
- Either row or col is not an integer
- row:
Row should be an integer. {row} is NOT an integer.
- col:
Column should be an integer. {col} is NOT an integer.
- The location is out of bounds
{row}, {col} is not in bounds of our {num_rows} X {num_cols} board.
- The location has already been fired at
You have already fired at {row}, {col}.
Displaying the Board
A board should be displayed like the following example
0 1 2 3 4 5 6 7 8 9 0 * * * * * * * * * * 1 * * * * * * * * * * 2 * * * * * * * * * * 3 * * * * * * * * * * 4 * * * * * * * * * * 5 * * * * * * * * * * 6 * * * * * * * * * * 7 * * * * * * * * * * 8 * * * * * * * * * * 9 * * * * * * * * * *
When ships are placed on the board you should use the first letter of their name to represent them. For example,
0 1 2 3 4 5 6 7 8 9 0 * * S * * * * * * * 1 * * S * * * D * * * 2 * * S * * * D * * * 3 * * * * * * D * * * 4 * * * * * * * * C * 5 * * * * * * * * C * 6 * * * * P P * * C * 7 * * * * * * * * C * 8 * B B B B * * * C * 9 * * * * * * * * * *
Hits to a ship should be displayed as an X and misses should be displayed as a O (that's the letter O and not zero). So after a bit of time, the player's board might look like
0 1 2 3 4 5 6 7 8 9 0 * * S * * * O * * * 1 * * S * * * X * * * 2 * * S * O * X * * * 3 * * * * * * D * * * 4 * * * * O * * * C * 5 * * * * * * * * C * 6 * * * * X X * * C * 7 * * * * * * O * C * 8 * B B B B * * * C * 9 * * * * * * O * * *
Examples
If you click on the test cases on Mimir you should be able to see what the output of the program looks like. Your output has to match mine so please be sure to read over some of those examples.
Hints and Suggestions
- Just because I said that you have to create certain classes doesn't mean that you are limited to only having those classes. Those are only the basic classes and I did have more in my solution. When you encounter a newthingin your program don't be afraid to make a class for it.
- This project is much bigger than most of you have worked on before so be prepared for a challenge. Make sure that you start early, plan out what you want to do, and ask lots of questions. It will greatly smooth out the development process for you.
- Be careful with references and copies and make sure you are getting the one you want. This is especially important when dealing with containers.
What to Submit
A zip folder that contains
- A folder namedBattleShip.
- Which contains a python file namedmain.pythat when run will play your game
- And also contains the rest of your solution
Your program will be run aspython3 BattleShip/main.py path_to_config_file
so make sure that it can be run like this.