Connect Four - Masters
By Jay Marriner, 03/10/2023
In July I began working part time on my Masters for Computer Science and Artificial Intelligence. Recently I completed my first module for the course which was to take an existing code base for a broken connect 4 game; fix it, improve it and meet certain criteria in the process such as using OOP principles, create a persistent way of storing data (a save file) and more. This was to be done in Java which if you have read one of my earlier blog posts I have a rudimentary understanding of.

Overview

As a quick snapshot overview of the project - the programming portion went great and I managed to implement all the required functionality, fix all the requested bugs and managed to implement a few try catch blocks to ensure clean input. With the time given and working full-time during the week the project turned out better than I had hoped; especially when encountering teething problems whilst working in Java.

Fixing the codebase

The first task I was faced with was to fix the existing codebase provided to us at the start of the module. This is something that in the past I had struggled with as I hadn't been exposed to other peoples codebases often in University however now having worked in industry for a year I found I was able to much faster pickup the codebase and understand how things were working relatively quick. There were a few teething problems of course as there always is working on other peoples code (especially when it is intentionally broken for you to find). One issue I noted whilst working through these fixes was that I had initially created a spaghetti mess of a method to store the computers moves. I had initially opted to pass values back to a main class from various subclasses where the logic takes place - this was not ideal as the project required both a text based version of the game and a GUI version (as seen in the video). This would have meant passing data back to the main class would not have worked when launching the application from the other main class for the GUI. I instead went back and reworked this code to work with a listener which worked great and allowed for the GUI to be created in a matter of 2 hours since it was taking existing logic and applying it to simplistic but functional GUI elements (buttons). Overall I think fixing the codebase went well and I enjoyed getting to see constant progress as more of the game started to work as I fixed various aspects. Along the way I also ensured to add many checks to user input to ensure the game would not have memory leaks or crash due to incorrect user input.

Functionality

After cleaning up the codebase and ensuring existing features were working we were required to add a number of features; the first feature I opted to implement was the undo button. This was not difficult as I already had a method that was storing the moves everytime the computer or player made a move and so I just needed to make a separate method that could be called when the player chose to undo that would remove the last 2 moves and set them back to empty board pieces. After implementing and testing undo the natural progression seemed to be the "Clear" functionality which as the name suggests - cleared the board of any and all moves. This method simply iterated on the undo method until there were no remaining moves left in the locally stored list. This meant this functionality reused existing code and took about 5 minutes to implement. Moving on was to a part that I was slightly nervous at first about - saving. I had written save files in the past but wasn't totally up to speed on how this could be accomplished in Java. Luckily I found the process fairly similar to most coding languages with the most comparable being Python to me. I decided for this project a simple save file would suffice and it would be over-engineering to stop the file being edited by salting the values. This meant the save file was simply a list of each move that had been placed on the board accompanied by a number representing the piece placed.

As seen in the image above you can see 3 numbers. The red number (left) notes the user (2 being player whilst 1 represents the computer), the green number (middle) represents the x axis and the blue number (right) represents the y axis. To ensure the save data would be easy to load I made it so each move would go onto a new line. That brings us to the final feature of loading! This simply read the text file line by line in a loop, within this loop it would split the data (2,0,5) at the "," giving us 2 and 0 and 5. I then converted this string data back into integers which then based on the first number (1 or 2) would run the appropriate method for the player or the computer playing a move and pass through the x and y axis values to ensure the move is added at the correct place. There was already an existing method for adding moves at designated points and so I utilised this to place all the moves on loading.

Building a GUI

The GUI section was perhaps the most frustrating as we were required to only use Java Swing and the APIs that this provides can be quite difficult to work with to achieve a nice result - I infact tried 4 different packages within Swing for the layout - the first being "Grid layout" which turned out - did not in fact allow buttons to be different sizes to a grid size which caused issues with the layout as a whole. Without getting into the weeds; it meant I had to pivot to an alternative package. The one I ended up using was still quite difficult to use but did allow me to make a fairly clean UI whilst still allowing for all the functionality to be in the game board. I think overall the GUI does match up with the examples we were shown for how it looks; being simplistic but functional. I did have the slight oversight of not updating the head text properly and so it is always telling the user to place their first move, this was simply down to time constraints introduced from having to pivot the entire grid system.

Final Words

I think to close the project went fairly well and I'm proud of what I was able to accomplish in a language I had relatively no knowledge of prior to starting the course. There are of course improvements that could've been made and oversights in certain areas that done again I would do differently but as a first project in Java I believe this went about as well as a person could expect! I look forward to working more with Java and learning to utilise the language to its full potential.