Ultimate Battleship Fabi8bit's version
Ultimate Battleship Fabi8bit's version is a terminal game developed in Python and based on the Code Institute Portfolio Project number 3 called Ultimate Battleship. The game runs on the Code Institute mock terminal on the Heroku platform. Here is the direct link to play the game on the mock terminal: Ultimate Battleship Fabi8bit's version The original game is a two-player strategy game, and the objective is to sink all of the opponent ships before the opponent sinks yours. It's typically played on a square grid of varying dimensions, where the player can place the ships. In this simplified version of the game, the user and the computer are the two players, and ships occupy only one space on the grid. The placement of the ships is also automated and it happens in a totally random way for both the player and the computer.
Flowchart
How to play
At the launch of the program, the user will find a welcome page. There will be a prompt to see game instructions. The user will have to choose "yes" or "no". If the user enters "y" to choose yes, instructions will pop up. To proceed to the game user must press enter. If the user choses "no" the game will be launched. Now the user will be able to enter the player name, choose the size of the battlefield grid, and the size of the fleet. The grid is composed by a sequence of "°" symbols, and the user's ships are indicated by an "@" symbol. Of course the computer board is presented as an empty grid. A missed shot will be marked on the board with the "X" symbol on the corresponding coordinate, while a hit will be displayed as "*" symbol. The user will input the coordinates for their shots, while the coordinates for the computer are generated randomly. The winner is the one who sinks the opponent ships first.
Existing features
Game set-up
-
Custom name for the user
- The name of the user will be used throughout the game to display the score.
-
Size of the battleship grid
- The user can choose among three sizes for the grid: small (3x3), medium (5x5), large (7x7). To facilitate the input for the size, one must enter the letter s for small, m for medium, or l for large.
-
Size of the fleet
- The user can choose among three sizes for their fleet: small (3 ships), medium (5 ships), large (7 ships). To facilitate the input for the size of the fleet, one must enter the letter s for small, m for medium, or l for large.
Consistent interface
At the launch of the program the screen is cleared. The guesses, the scores, and the battlefield grids are displayed in the same position throughout the game, so the user can find all the needed information in the same spot.
-
Random ships placement
- A function that generates random coordinates will position the ships (the computer's fleet is hidden to the user's view)
-
User input for guesses
- The users can choose the coordinates for their guesses
- The computer guesses are randomly generated
-
Input validation
- The entered coordinates pass through a validation function that checks whether the entered data is correct. The game won't proceed until the input is correct.
- Fleet and battlefield sizes have to be a letter among s, m, or l
- Coordinates have to be numbers
- The same guess cannot be entered more than once
Features to be implemented in the future
- User against user
- Custom ship placement
- Graphic Interface
Data model and data flow
For the data model I was entirely inspired by the one used in the Ultimate Battleship example presented during the course. I changed the names of the classes and functions, and figured out what would be the best way for data flow. I tried to keep all the functions "atomic" as suggested during the course. The data flow goes as follows as you can also check in the simplified flowchart:
- The screen will be cleared and a welcome message is displayed.
- The User will be asked if wants to display the game instructions.
- The User will be asked to type the name, and this value will be assigned as the name for the player when the Battllefield class is instantiated.
- The User will be asked to insert the desired size for the battlefield grid and fleet. This value will be passed for the instance creation.
- The computer and the player instances will be created: The Battlefield class stores grid size, fleet size, name, type (this value will be used for if statements inside the functions), opponent guesses, ships coordinates. The class also has methods like the grid print, random coordinates generator, ships coordinates list creator, opponent guess list creator.
- The random ship placement method will be invoked at this point for both players and passed through a validation function to ensure that the coordinates are unique and within battlefield grid size. The right coordinates returned by the function are added to the relative player's coordinates list in the instantiated Class.
- The battlefield grid will be printed in the console. The ships are displayed only in the player's grid.
- The user is prompted to the guess part. The input for Row and Column is asked sequentially, and verified.
- The consolle will be cleared again at this point, and the scoreboard and the updated grid will be printed to the consolle in the same spot, giving the impression that the interface is updating live. The Hit and Miss shots are reppresented with an "*" or "X" respectively, on both grids.
- The guesses list is updated on both instances of Class Battlefield
- The loop keeps going until one of the two scores reaches the size of the fleet, which means there are no more ships to sink. The loop will break.
- The winner function is invoked. After a simple score check, the winner's name will be returned by this function.
- The winner's name will be printed to the consolle, and the program will close.
Testing
-
The code was passed through the Code Institute PEP8 linter without any issues.
-
Invalid inputs are rejected by the evaluation data processes:
Feature Expected Outcome Testing Performed Result Pass/Fail Display Instructions y/n The instruction will be printed to the consolle if yes or proceed to the game if no Insert y or n respectively As expected Pass Display Instructions y/n The instruction will be printed to the consolle if yes or proceed to the game if no Insert capitol Y or N The input is transformed to lower case and acting as it's y or n Pass Display Instructions y/n The instruction will be printed to the consolle if yes or proceed to the game if no Enter different characters than y or n The user is prompted to only enter y or n Pass Enter Name The input is validated and proceed to the next step if correct Enter correct name As expected Pass Enter Name The input is validated and proceed to the next step if correct No input The user is prompted to enter at least one character Pass Enter Name The input is validated and proceed to the next step if correct Enter only a space The user is prompted to enter at least one character, not only spaces Pass Enter the size of the grid and the fleet The input is validated and proceed to the next step if correct Enter correct values (s,m,l) As expected Pass Enter the size of the grid and the fleet The input is validated and proceed to the next step if correct Enter capitol values (S,M,L) The input is transformed to lower case and acting as it's s or m or l Pass Enter the size of the grid and the fleet The input is validated and proceed to the next step if correct Enter values different than s,m,l Value Error is raised. The user is prompted to only enter s, m, or l values Pass Enter rows and columns for coordinates The input is validated and proceed to the next step if correct Enter correct values between 0 and the size of the grid-1 As expected Pass Enter rows and columns for coordinates The input is validated and proceed to the next step if correct Enter values out of range Value Error is raised. The user is prompted to only enter values in the range 0 to size of grid -1 Pass Enter rows and columns for coordinates The input is validated and proceed to the next step if correct Enter values twice Value Error is raised. The user is prompted to not enter values the coordinates twice Pass -
A complete match was run for every size settings without issues
-
The program works without any issues on the local terminal as well on the Heroku mock terminal.
Deployment steps
- Clone or fork this repository
- Create a new Heroku app
- Under app settings configure the variables: KEY: PORT, VALUE: 8000
- Add the buildpacks in this order: Python, Node JS
- Link the Heroku app to this repository under the Deploy tab
- Under the Manual deploy section select the main branch and click on Deploy Branch
- When build is complete, click on View to open the mock terminal
Credits
-
this code: " not in ("s", "m", "l") " under the validate_data function is a tip taken from this post https://stackoverflow.com/questions/22304500/multiple-or-condition-in-python
-
this code: " if not (all([isinstance(item, int) for item in t])) " under validate_coord function, is a tip taken from this post https://datascienceparichay.com/article/python-check-tuple-contains-only-numbers/
-
this code: " winner_check = max(scores, key=scores.get) " under winner function, is a tip taken from this post https://datagy.io/python-get-dictionary-key-with-max-value/