Battleship game in README.md
4 min read • November 7, 2022
Some time ago, while I was browsing for GitHub profile customization ideas, I stumbled across the profile of @JonathanGin52, who has an interactive Connect 4 Game in GitHub README.md. I liked the idea and wanted to make something similar.
First, check out the short video below to see it in action, orEverything works by using a few components
- GitHub Actions - to run the code when someone interacts with README.md
- Python script - to take care of game logic and updating README with new values
- Database (MongoDB) - to store all the data (statistics, coordinates, etc.)
- README.md file - game’s GUI
Board representation
To represent the board, I created this bitboard to represent each table cell by a different number. When someone makes a move, I can easily find its location. It’s also easy to generate ships with this method. I can choose one random number and then go horizontally or vertically to get the rest of the ship.
Note the extra numbers on the right. All of these numbers are treated as incorrect. This way Python script knows when the row ends.
+---------------------------------------+
| 0 | 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
+---------------------------------------+
GitHub Actions
Whenever an issue with the prefix battleship|action|location
is opened, it triggers the GitHub Actions workflow. The title of the issue and the user’s username are passed as environment variables to a Python script, which then splits the issue title every |
and decides if it should create a new game or make a move based on action
.
Creating a new game
When a new game has to get created, we need to make a blank board with ships placed randomly. To do it, we call the create_game()
function that calls the place_ships()
function, which generates a ship by choosing one random place on board and then generating the rest of it horizontally or vertically (example below).
+-------------------------------+
| | | | | | - | | |
| | | | | | - | | |
| | | | | | - | | |
| - | - | - | - | - | • | - | - |
| | | | | | - | | |
| | | | | | - | | |
| | | | | | - | | |
+-------------------------------+
Database
Now we have to store ships’ location somewhere. We could place them in a plain text file, but then everyone could see where the ships are, so we have to hide them elsewhere. That’s when a proper database comes in handy. I used MongoDB for this as it fits my needs.
Modifying the README
Time to change our board visually by updating the README
file. We can do it using the same method we would use to modify a text file. First, we read the file line by line and save content to a variable. We can then modify the specific lines we want. To create an empty table cell, I used a blank image with a link by using this format: [![](image link)](link that creates issue)
.
Committing, pushing, and closing the issue
The last step is to commit and push everything to GitHub. We can do it with GitHub Actions with a few commands (see battleships.yml > Commit and push). Then to keep everything clean, we should close the issue by using peter-evans/close-issue@v2
.
Playing the game
The process is the same as creating a new game. Instead, we have to check if the location shot has the ship or not by using our database and modifying this location in README with either a white or red mark image.
Statistics
- The statistics under the game title were made with shields.io.
- A leaderboard is made by storing all users with their statistics and sorting the database by shots hit.
Links and inspirations
- Play Battleship game on my GitHub profile
- Connect Four game by @JonathanGin52
- Tic-Tac-Toe by @DoubleGremlin181