During the journey of self-learning, it is important to test out your skills. When it comes to programming, this comes in the form of personal projects.
After learning objected oriented design, algorithms and data structures in Python, the next step in my journey was to create a project. I wanted to build one that would incorporate my new knowledge and be something I could put on my resume. I heard about the power and flexibility of Pygame, a Python game development library, so I decided to try out a project with it. For those unfamiliar with Pygame, it provides a GUI (graphical user interface) that you can draw on and respond to user input events with.
The question was then, what game do I make? I knew that rendering 3d graphics would be outside my realm of capabilities, so I limited my choices to board games. With some more searching around I settled on Battleship.
For those not familiar with the classic American board game, two player have their own hidden boards where they place their ships. The players then go back and forth, calling out coordinates on their opponent's board. The goal is to sink all of the opponent's ship.
As I describe my journey of building Battleship with Pygame, I will explain to you why your next project should involve python game development.
1. It Reinforces your Learning
The number one reason to devote yourself to any personal programming project is to reinforce your learning. It's easy to follow along with tutorials where there is never any errors. However, if you challenge yourself to creating a project, your knowledge will be tested and fortified.
Object Oriented Design in Python
The general concept of OOD is that you can have classes that have their own private data and provide public methods that allows other classes to interact with that object.
When it comes to the board game Battleship, I knew that the board, ships and AI (who the user is playing against) should be represented as classes in Python.
As seen above, the class structure of my Battleship project takes a hierarchical structure. The AI has its own instance of the Board class. Then the Board class stores the instances of the Ship class. The methods provided allow for the user or AI to attempt a set of coordinates on the opponent's board and check whether there is a winner.
One benefit of OOD is abstraction. This describes how a program can interact with an object without being concerned with how its method are implemented. One example of abstraction from my Battleship project deals with the AI class. At first, when the AI attempted a target on the user's board, it's attempt coordinates method randomly selected a pair of coordinates. However, at the end of the project I decided I wanted to make the AI "smarter" by implementing an algorithm. I was able to achieve this by only re-writing the specific attempt coordinates method for the AI class. The main program was only concerned with receiving a pair of coordinates, allowing this functionality change to occur.
When it comes to any programming project, you need to consider how the data will be stored. One of the most important question I had for my own project was how I was going to store the state of the game board. I opted for a list representation of a 10x10 matrix whose indices related to the board coordinates and contained whether there is a ship, miss or empty.
[['w', Submarine, 'w', 'w', 'w', 'w', 'w', 'w', 'w', 'w'], ['w', Submarine, 'w', 'w', 'w', 'w', 'w', 'w', 'w', 'w'], ['w', Submarine, 'w', Carrier, 'w', 'w', Battleship, 'w', 'w', 'w'], ['w', 'w', 'm', Carrier, 'w', 'w', Battleship, 'w', Destroyer, 'w'], ['w', 'w', 'm', Carrier, 'w', 'w', Battleship, 'w', Destroyer, 'w'], ['w', 'w', 'w', Carrier, 'w', 'w', Battleship, 'w', Destroyer, 'w'], ['w', 'w', 'm', Carrier, 'w', 'w', 'm', 'w', 'w', 'w'], ['w', Patrol Boat, 'w', 'w', 'w', 'w', 'w', 'w', 'w', 'w'], ['w', Patrol Boat, 'w', 'w', 'w', 'w', 'w', 'w', 'w', 'w'], ['w', 'w', 'w', 'w', 'w', 'w', 'w', 'w', 'w', 'w']]
In the representation above, 'w' represented water, 'm' represented a miss and the ship names were a reference to each ship object. When a ship object was referenced from the board data structure, specific methods could be called on the ship instance to register a hit or check if a ship was sunk.
When implementing algorithms in python game development, you can literally see your algorithms in action. Since the user plays against an AI, I decided to implement an algorithm for it that mimics how a human would play.
If you have played Battleship before, you know that after you land your first hit on a ship, you will attempt surrounding coordinates until that ship is sunk. This is a very intuitive concept but having the computer resemble any type of intelligence requires work.
The Hunt Algorithm
According to the hunt algorithm, the AI is in two modes: hunt mode and target mode. The AI will start in hunt mode and fire at random until striking a ship. Once the AI strikes a ship, it will pass the surrounding coordinates to a target queue and enter target mode. While in target mode, the AI will pop a set of coordinates off the end of the target queue and attempt a target there. The AI will return to hunt mode once the ship has sunk, denoted with an empty queue.
The gif above is a demo of the hunt algorithm in action on the final version of my project. The AI is attacking on the Player's side.
This article about Battleship on Data Genetic's provides a very detailed explanation of the algorithm including visuals.
2. Great for Putting on Your Resume
Another reason to pursue a personal programming project is to have something that you can put on your resume and talk about to recruiters. However, certain project qualities can make for a better project to put on your resume than others.
The most important factor of a project that impresses potential employers is the ability to demonstrate your skills. As mentioned before, my project not only shows off my Python programming skills but the more conceptual skills of OOD, data structures and algorithms.
Another core reason that python game development projects are great for resumes is their ease to understand. When explaining you project in an interview, you want something that is easy to explain to the interviewer. Most American's already understand the board game of Battleship but even if they did not, I could easily explain it in a couple of sentences. Less time spent explaining your project and more on how it portrays your skills will result in a better interview process.
Lastly, a python game development project is great for resumes because it provides a visual component. A project with a GUI will be more appealing to an interviewer than something that runs in the terminal. The interviewer can also interact with your project and maybe even gain entertainment from it.
3. Learn about Game Development
One of many popular programming careers is in game development. When building a python game development project, you can learn about the basics behind planning and executing a virtual game.
When it comes to building a game using Pygame, there are generally two steps:
- Building the text based game.
- Creating the GUI.
Building the text based game first allows for you to define all of the games objects and establish the game event loop. The game event loop handles the user input and responds accordingly. The loop only terminates when a winner has been determined.
For my Battleship Project, the event loop is as follows:
- The user attempts a set of coordinates on the enemy's board.
- Check if the user has won.
- The enemy attempts a set of coordinates on the user's board.
- Check if the enemy has won.
Once you successfully create a text-based version of the game, you can implement the GUI using the Pygame library. Using Pygame's draw methods, you define functions that can take the state of the game at any moment and display it to the user. Also, instead of having the user type into the console, the GUI allows for your game to respond to user input events. Your program then interprets these events and calls the correlating method.
For instance, when a user clicks on a set of coordinates on the enemy's board, the program is able to identify the coordinates the user clicked on and pass it off to the Board class method for attempting a set of coordinates. The method then returns the result of the attempt, which is displayed by updating the enemy's board and displaying text on the top.
4. Learn How to Use Libraries
After developing a strong foundation in Python, the next step is learning libraries. For any task you can imagine from machine learning, to web scraping, to web development or game development, Python has a library for it. By attempting a Pygame project, you will learn how to interact with a library. You will learn what library documentation is and how to read it. When documentation is not enough, you will learn about community forums like Stack Overflow or Reddit.
5. They are Fun to Build
Building a Pygame project is very fun! Watching as your game progresses from a blank screen to a fully functioning game is very rewarding. You can play your game as you go. Also, with game development, you have the creative powers to design or add elements as you see fit. The freedom of creativity can lead to an awesome end product.
Your next project should definitely involve python game development. Projects can be very time consuming so you need to be sure you are choosing one wisely. You want a project that reinforces your skills, is great for putting on a resume and fun to build. Python game development is just that and creates an end product your friends can try out!
If you want to check out my project's source code, you can view it on GitHub.