Plinko

Plinko Thumbnail Plinko Midgame Plinko GIF

Background

In December 2021, to prepare for a Python course I would be taking the following semester, I began to teach myself Python by watching YouTube videos and copying the tutorials (including the creation of a version of Pong). After getting the basics down, I decided in early January 2022 to create a game to see what I had learned. I ultimately decided to create a Plinko game.

How To Play

Use the up and down arrow keys (or W/S) to change the wager amount. Use the left and right arrow keys (or A/D) to move the the ball's starting position. Use the space bar to drop the ball. The ball will drop down the board and bounce left and right, until reaching one of the goal slots. The placed wager will be multiplied by the goal slot's reward and deposited into the player's "Money".

Process

I knew I would struggle with my first project, and I was right. The biggest problem was debugging - I hadn't yet learned how to debug code, so I didn't know how to fix my problems. More than 80% of the time I spent on this was fixing errors, and those fixes were more like "patches". I spent two weeks working on this project, and I was proud to both see a working product and know that I had learned something. I spent another two weeks making the occasional adjustment or change, and after one month of production, I called the project complete.

Looking Back

For my first project, I think the end result is pretty good. The game works pretty well. However, there are many things that should have been different. For one, it is almost impossible to lose money because the goal rewards are not placed well. This makes the game very simple and not very fun to play. However, the biggest problem is the code itself. There are very few comments, and it is hard to figure out what code does what. Thankfully, my variable and function names are fairly descriptive, so it isn't impossible to follow along. Overall, plenty of room for improvement, but a good start.

Tic-Tac-Toe

TicTacToe Thumbnail TicTacToe Midgame TicTacToe GIF

Background

In January 2022, immediately after finishing Plinko, I began working on a Tic-Tac-Toe game. I felt confident that I could manage it, especially since this was a common beginner project. I assumed this would take me a week at most, and that I could finish it before classes started back up.

How To Play

Two players alternate placing their symbol, X or O, in a 3x3 grid using "WASD" and the space bar. The starting player is randomized. Whichever player can place three of their symbols across the board horizontally, vertically, or diagonally is the winner.

Process

Some parts of the game were easy to implement, such as drawing shapes, as I had just learned these skills working on Plinko. However, keeping track of where the players placed their symbols was not something I knew how to do. I needed to do this so I could detect if a player had won and ensure that pieces couldn't be placed on top of one another. I ended up using lists to store coordinates because that was all I knew how to do. This made things much more difficult to work with, a problem made worse by the fact that, once again, I refused to comment my code. I remember thinking to myself, "I wrote this, I know exactly what everything does." I wish I could slap my younger self. If I had added comments, I bet most of the time I spent debugging would have disappeared. Bugs began to build on top of one another, and it must have gotten to the point where I couldn't be bothered anymore. I ended up leaving some features unimplemented in this game.

Looking Back

This project reminds me even today to never be over-confident and stay humble. For my skill level at the time, this Tic-Tac-Toe game is okay. But as I looked back through the code, I cringed at how much unnecessary code was written - triply nested loops, pointless if-else statements, no data structures, no comments - there is so much that can be improved upon. However, it also serves as a reminder of how much better I've gotten - the only reason I know that this project isn't good is because I've sinced learned better ways to do it. Although this project is probably my least favorite, it serves as my best lesson, and when I struggle on projects now, I think back to it

Baseball Simulator

Baseball Simulator Loading Baseball Simulator Empty Baseball Simulator Midgame Baseball Simulator Thumbnail Baseball GIF 1 Baseball GIF 2

Background

Being a huge baseball fan, I always wanted to create baseball-themed projects. I knew I couldn't create an actual baseball game like MLB The Show, but I figured I could simulate a baseball game using statsitics. I decided I would try to accomplish this for my next project.

Concept

I knew what I wanted to get out of this project. I had many reasons for wanting to create this, but among them was a way to "watch" games whenever I wanted. At the time, I was learning how to keep an official scorecard of games, and I wanted to be able to practice whenever I wanted. In order to accomplish this, I would need to give myself as full of an experience as I could. Therefore, I would need a transcript to tell me what was happening in the game, a scoreboard to confirm the number of runs and hits, and a lineup card. Aside from that, I wanted to add a way to keep track of runners visually. I drew a rough sketch of where I wanted everything to go, and then I began creating.

Process

I knew that before a game could be played, I would need some sort of database to store information about the team, such as its players' names, numbers, stats, etc. I also knew that I would need at least two teams to play the game. I created a file that contained three classes. The Player class served as the parent to the Batter and Pitcher classes, and I would use these classes to create my rosters. I went to my favorite website, BaseballReference.com, and got the rosters of my two favorite teams: the New York Mets and the Seattle Mariners. I created a Player instance of each member of the starting lineup as well as their ace starter, set-up man, and closer.

I had aspirations of making this as realistic as possible, so that if a good team played a bad team, then the good team had a better chance of winning. Therefore, I decided that I would need to incorporate the players' real stats into their instances. Once again, I went to BaseballReference and took stats such as Strikeout Rate, Walk Rate, Batting Average on Balls In Play, and Slugging, as well as the pitchers' counterparts. For each player, I took the average of each stat over the player's last few years and used it to create each player as faithfully as possible. I stored each team's batters and pitchers in a list and combined the lists to create the team roster. After importing that to my main file, I was ready to start working on the simulation.

A common process in the creation of my projects was that the graphics side of production went smoothly, but the logic of the program took much longer. I started out by drawing the scoreboard's outline and filling it with the teams' names and 0's in the R-H-E column. I created variables and Turtles to keep track of team total stats and update them as the game progressed, as well as one to update each team's inning's run box. Since these required the game to be in progress to take effect, I would bring everything together when the logic of the simulation was completed.

The user needs to know which players are on their team, so I added lineup cards to the sides of the window. While knowing which players are on the team is important, I wanted the user to be able to see which players were actively participating in the current at-bat, much like real scoreboards at stadiums. I added a little indicator next to the name of the active batter and pitcher, which moves as the active players change (though apparently I never got around to adding this to the pitchers. As previously mentioned, I will not update projects for documentation purposes).

It was at this point that I decided to work on the game's logic, which I attempted to structure as reasonably as possible. I didn't want the game to go pitch by pitch, as that would take too long. Instead, I decided to do one plate appearance at a time. A plate appearance begins when the transcript says that the pitcher is pitching to the batter. After this point, the program calls a series of functions to determine the result of the plate appearance. The flow of logic goes as follows:

  1. Does the batter strike out?
  2. If not, does the batter walk?
  3. If not, does the batter get a hit? If so, how many bases?
  4. If not, the batter hit into an out.

At each stage of the above process, a function is called with the batter's and pitcher's stats to determine whether the answer to the question is yes or no. Once a plate result has been reached, the transcript will update to inform the user of the plate result and the program will update all respective variables and graphics. After this step, the next batter steps up to the plate and the process repeats until the final out of the game is recorded, the home team walks it off, or the game ends in a tie.

The final feature to add was the scorebug, and this was the most difficult part of the simulator. Keeping track of which bases were occupied and coloring them properly was simple, but getting the outs counter and half-inning marker to work was a nightmare. My first attempt involved using Turtles to draw the shapes, but getting them in the right positions at the right times was a challenge. There was some sort of conflict between objects that caused them to disappear at times. After some time was spent tinkering with them, I realized that I could accomplish the same task by simply writing a dot and hyphen with a Turtle. After I figured that out, everything else went smoothly. I was able to connect all the graphics to the logic, and from there all that was left was some quality-of-life improvements. I added a loading screen to make the simulation feel more genuine and a speed selector in case people wanted to speed through the game. After adjusting some colors and positioning, I finished with a product I was extremely proud of.

Reflection

There are, of course, some things I would fix or improve upon, and I do plan on making an updated version in the future. The most apparent improvement would be to add more teams and a team selection feature, as well as expanded rosters. I would also like to make this more of a game by allowing the user to control parts of the simulation. This would include actions such as setting lineups, pinch-hitting/running, bullpen management, and hitting and pitching strategy, essentially turning the user into a manager. In addition, better graphics are also a point of improvement, not only statically but also dynamically. I would like to re-design the scorebug to show pitches being thrown, batters swinging, and runners moving around the bases. I would also like to include more graphics, animations, and sound effects. In terms of the code, I'm very happy with the way I organized everything. I had a lot of variables and Turtles, and I kept them structured in a way that allowed me to find whatever I needed very quickly. I also did a much better job of naming my variables more clearly. My usage of comments was still severely lacking, but it does show some progress compared to the previous projects I made.

Baseball Clicker

BaseballClicker LightMode BaseballClicker Thumbnail BaseballClicker GIF BaseballClicker MidGame BaseballClicker EndGame

Background

One of my favorite games when I was younger was a game called "Cookie Clicker". The game revolved around clicking a picture of a cookie in order to obtain a cookie. The more you clicked, the more cookies you got, and you could spend those cookies on things that automatically generated cookies for you. I'd have the game running in the background of my laptop as I watched YouTube videos or played other games, and I'd check in every once in a while to upgrade my buildings. I wanted to make my own version of the game, and so I decided to apply my love of baseball to the concept and create Baseball Clicker.

Concept

In order to create the basic features of this game, I needed to have a button that would give points, objects that could be purchased to automatically generate points, and upgrades that strengthen those objects. I'd also need a scoreboard to display vital information to the player. I also wanted to create graphics, since none of my other projects had anything more complex than a few connected lines and basic shapes.

Process

I wanted to divide the main JFrame into sections and have each section contain one core feature. In "Cookie Clicker", the cookie was on the left side of the screen, with the scoreboard above it. The center of the screen has graphics that display the number of each building you have. The right side of the screen has the buttons to purchase buildings, with the upgrades listed above it. I didn't want to copy that layout, not only because it seemed rather complex but also because I didn't have a need for such a sophisticated layout. I decided to split my screen into five sections: North, East, South, West, and Center. Thankfully this corresponds perfectly with Java's AWT BorderLayout.

The first thing I wanted to do was get the basics of the game down; click a button, and add a point to the scoreboard. I started with the button by making a class that extends a JButton, setting the image of the button to be an image of a baseball, and adding a MouseListener. Once I ensured that the clicks were being registered, I shifted over to the scoreboard, which was nothing more than a JPanel with some JLabels displaying some basic text. I set the mouseClicked() event on the JButton to update the number of baseballs the player has, and then update the scoreboard to reflect this change.

Once I had that working, I began to add equipment items, which was my version of the buildings in "Cookie Clicker". After deciding on a few baseball-related objects, I began using them to create instances of EquipmentButton, which is a class that extends a JButtons. It features all the information on an equipment type, such as its name, price, quantity, contribution to the automatically generated Baseballs per Second (BPS), and a picture of the item. Each button also contains a MouseListener. When clicked, the button runs a check to see if the item can be purchased. If it can, it decreases the user's baseball count by the price, adds one to its quantity count, and updates all related attributes. All of these buttons were in an array for future reference.

The next step was to display the buttons, which I would do by simply adding them to a JPanel. After creating the EquipmentButtonPanel class, I moved into it the code to create, store, and display each button sequentially, so the least powerful item would be at the top, similar to the original game. I set this panel to the east side of the screen and tested the buttons to ensure that they updated their information appropriately.

The upgrade system didn't turn out as I had originally planned. I wanted there to be different effects for each piece of equipment, so that some upgrades were a x2 multiplier, while others were a cost reduction or a package of multiple of the equipment. However, this quickly grew too complicated, so I just made all upgrades the x2 multiplier, similar to the original game. The process for creating the UpgradeButtons was nearly identical to the EquipmentButtons. The only difference was that each upgrade button needed to be linked to its corresponding equipment button, so I created a method to find the button by iterating through the EquipmentButtonPanel and retrieving its data.

The final sections that needed to be developed were the header and footer sections at the top and bottom of the JFrame. I wanted the top to exclusively contain game-related information, so the player wouldn't be distracted by anything. As such, the header primarily contains the scoreboard, which displays the number of baseballs and the current BPS. It also contains an options mode, which provides the user with the ability to start a new game or toggle a "Dark Mode", which turns the colors of the objects in the game darker. The footer contains the very brief credits JLabel and the URL of my website.

There are many smaller features in the game that I don't have time to elaborate on, such as changing the color of buttons when a purchase is possible, the layouts of the buttons and panels, and the animation on the baseball. However, there are three that I want to call special attention to.

My favorite part about this project was the art that I created. Pixel art is a hobby of mine that I don't get to indulge in often, so when I realized that I shouldn't be using pictures I found on the internet of baseball bats and helmets, I was elated that I would be creating my own work. Looking at the images used for the equipment, it is apparent that I parodied baseball-related brands, such as Dubble Bubble, Gatorade, Mizuno, Marucci, and others. Many of these were brands that I grew up using when I played baseball, and I wanted to "honor" them by including them in my game. While these were a lot of fun to create, the main baseball is by far my favorite piece of art that I created for this game. I modeled it after an authentic MLB baseball, and I love how it came out. From the signature of the "Commissioner" to the logo at the bottom, I spent hours on making these little details, and I think it came out great.

A game like Baseball Clicker is not meant to be played in a single session. As such, I needed to include some sort of save data system for the game. The very first version of "Cookie Clicker" was easily hacked, as the save data was just a concatenation of the amount of each item that was purchased. I wanted to prevent this, so I used a very basic encryption to prevent this from being accomplished so easily. I created a key to use for my encryption/decryption, which was just a number. I stored this key in the first slot of an ArrayList. Then, for every number I needed to save, such as the number of baseballs, the BPS, or the number of equipment or upgrade level, I would multiply that number by the key and store each in a different spot of the ArrayList. The key was randomized every time the game was run, which contributed to its security. I wrote the contents of the ArrayList to a file, saveData.txt, so the data could be loaded in when the user wanted to resume playing. I needed to separate the encrypted numbers in the text file with some sort of delimiter so that when the data was being read in, the numbers could be decrypted properly. As such, after each index's content was written out to the text file, I appended the zero-width character to make it hard to see at first glance where one number ended and the next began. While this is far from fool-proof, it does add an extra level of security and I had fun doing it.

In "Cookie Clicker", once numbers reached the millions, they were abbreviated to the form X.XXX M. I wanted to do the same thing, as displaying these large numbers becomes pointless when the smaller digits are changing so rapidly. As such, I needed to come up with a way to display my numbers in that format. I accomplished this using a HashMap to map the power of 10 of a number to its number suffix (M for million, B for Billion, etc.) and a function to properly format the number. This proved to be one of the most difficult parts of the game development process. After searching for a way to accomplish this, I found the library java.text, which contained a class DecimalFormat. Even with this class, I still struggled to get my function to work properly. At first, I couldn't get the decimal point in the number to be a valid delimiter. Once I solved that, more problems arose. Numbers would be displayed with the wrong suffix, the decimal point would disappear at random intervals, and other minor bugs. The biggest issue was the case where a number in the thousands was being displayed. Contrary to the way "Cookie Clicker" displays its thousands, I wanted Baseball Clicker to display the thousands with a decimal point. However, I ran into a problem where sometimes the function would format the number, and other times it would leave it. I eventually solved this problem, but it would not surprise me if other problems surrounding the number formatting system were present. If you find one, please let me know so I can fix it!

Reflection

Despite how in-depth and complex this project is, I still don't feel that this is my best work. I still think Baseball Simulator is a better product, but that isn't to say that this is a poor product by any means. I take pride in the fact that I produced this game rather quickly with a fairly rudimentary understanding of Java, programming, and game development as a whole. However, there are so many areas for improvement. I think that, visually, it is incredibly bland and could use much better graphics. Sound effects and background music would be a very nice addition as well. Additional features, such as a statistics page, achievements, more upgrade and equipment diversity, and customization options would all contribute to a much better game. Maybe I will update it in the future and add some of these features.

Compared to previous projects, my commenting in this project is a drastic improvement. I learned about JavaDOC basics in class, and since I knew my commenting abilities could use an overhaul, I tried to comment as much as I could while not flooding the files. Looking through it now, it is much easier to follow along, and I was actually able to make some adjustments to the code to improve the efficiency and performance. Again, there is always room for improvement, but I think that I now have a solid foundation for commenting.

Gacha Simulator

Code is available at the link above. Check back soon for my account!