Tagproject

2018 Fall Game Project – Cards

Fall semester of my Junior year at Virginia Tech was more a laid-back one when compared to my earlier semesters – mainly due to the fact that I was a year ahead of schedule and most, if not all, of my hard classes were behind me. I took the solid amount of free time that I had to start researching new and interesting computer science topics, while building on the skills I had learned previously either at my internship with Cox, or through the work I had done by myself. After coming up with a couple of different ideas, I settled on a basic card game, twisted in such a way as to challenge what I knew and force me to learn some new and interesting concepts.

Essentially, my goal was to create a multiplayer standard 52 card game that was able to support any rules the players decided to enforce. The idea was to create a simple backend so that I could have the liberty on focusing on the more challenging and new concepts like communicating with a central game server. I also wanted to test my abilities in making a backend in C, as it is well known that lower level languages, like C and C++, are great for games due to their relatively fast execution times. However, making all other aspects of a game in C (i.e. rendering) can be rather frustrating and time consuming, so I also decided to code the frontend in another language. As such, I settled on python/pygame. Finally, as I wanted to make the game multiplayer, I needed to include a server framework that was able to communicate with n many clients at a time, while still being able to interface with the backend C code. After doing some research, I decided on ASP.NET, as I am generally unfamiliar with C# and the .NET framework, and wanted to use the opportunity to learn something new instead of falling back on a framework I’m more comfortable with. Using C# also allowed me to interface with the backend incredibly easily (detailed later). I decided to upload the server on AWS/EC2, as I’m always looking for an excuse to learn more about the Cloud/AWS and practice using it.

The final architecture of the card game project.

Coding the C backend was the easiest part of the project – mainly due to my comfort level with the language (thanks to the many difficult low-level programming courses taught by Virginia Tech), but also due to the nature of the project. The game is fairly simple; there exists only a couple of noteworthy objects/data structures. The main deck, the cards on the table, and the cards in each of the player’s hands. All of these objects can be represented as a Deck, each containing Cards. I created the Deck data structure as a hybrid between a stack and an array list. It supports popping and pushing, as drawing from a deck usually entails popping from one deck and pushing it onto another, but the need for placing or picking cards from specific indices was also necessary, as a player picks and chooses specific cards to move onto or into their hand from the table. As of right now, the backend supports 4 basic functions – drawing from the main deck to the table, drawing from the main deck to a player’s hand, picking a card up from the table and placing it into a player’s hand, and placing a card from a player’s hand onto the table. Keeping it relatively simple, at least for the time being, allowed me to write up this portion of the project quickly and move on to the newer and more challenging parts of this project. I definitely plan on revisiting this section and fleshing it out to add more functionality later down the line.

Next came creating the server and wrapper for the backend. Like I stated before, however, this was relatively easy, as the choice for C# made interfacing the C backend easy (through DllImport) and the .NET framework allowed for a speedy standing-up of a basic RESTful web API (through MVC). Essentially, the client makes requests on various endpoints depending on the method they want to invoke. All I really had to do was create endpoints for each of the 4 functions described in the paragraph above. Other than that, I created register/unregister endpoints for when a player joins or leaves the session (mainly to ensure that the number of players didn’t exceed the maximum of 4, and to assign each player a specific player id), and basic start/terminate endpoints. After creating the C# server, all that was left was to publish it on an AWS EC2 instance, which admittedly took some time as I was unfamiliar with how to do so, but was achievable in the end after some time and googling.

Finally came creating the frontend in Python. Thankfully, interfacing the server was relatively easy due to the urllib library. As a result, I really just needed to focus on getting the correct information from the server and translating it into something that could be easily understood and rendered using pygame. I achieved this by adding an endpoint to the server that retrieved a JSON object of the entire table (including the main deck, the cards on the table, and each of the hands). The python code regularly makes checks to this endpoint and references it against a stored version. If they differ, the local versions of these decks are changed to reflect the differences. All I really needed to do at that point was render the cards and come up with an intuitive way to activate the backend functions. I took inspiration from the popular online card game Hearthstone and implemented a dragging feature, where players can click and drag cards from their hand to the table or visa-versa.

The current status of the python client, with 4 players connected to the central server. You can see the main deck represented in the middle of the screen as the stack of non-visible cards, and the on table cards represented as the stack of visible cards. Each of the hands are also present, with only the current player’s hand being visible.

I still have much I want to achieve with this project. After an initial play test with friends we discussed a couple of features that would be good to include later down the line. For instance, the ability to show cards from one’s hand without having to place it on the table, being able to discretely trade cards between players, and the inclusion of a discard pile. I’m eager to continue optimizing and working on this to see where I am able to take the final product. If you’d like to see the code for this project, you can view it on github here.

Thanks for reading! If you have any questions or comments, feel free to write them below or email me at [email protected].

 

2018 Summer AWS Project – WordPress Hosted Through AWS

My summer of 2018 was spent interning with Cox Automotive (Atlanta) on the Enterprise Data Platform (EDP) team. Put simply, the EDP application serves as a managed data lake hosted through various AWS services. As I had previously no experience with AWS or Terraform, the language Cox uses to build infrastructure on AWS, I thought it would be fun and informative to go off on my own and play around with both subjects.

Honestly I’m surprised I waited this long to look into AWS. It’s really been blowing up in the tech world for a while now, and they continue to add new services on a regular basis. At this point they have over 50 services available to build any cloud application you could think of, from Cox’s interest in a managed data lake, to my interest in hosting a website. My original plan involved hosting the website out of an S3 bucket, but was eventually changed once I decided to stay with WordPress. I was rather surprised at how easy it was to set everything up manually – all that was required was an EC2 instance running a pre-defined image specifically used for WordPress (and a Route 53 entry pointing the domain name to the EC2 instance). Once up and running, it was simple enough to ssh into the instance and play around with the settings to get it the way I wanted (i.e. adding SSL/https support).

The original plan. It involved routing the domain using Route 53 through Cloudfront (for https) and to an S3 bucket hosting html files.

The final implementation. Instead of routing through Cloudfront and then to S3, it was routed directly to an EC2 instance running WordPress with LEGO (Let’s Encrypt) for SSL/https.

After settling on a routing strategy came building the infrastructure in terraform. For those unfamiliar with terraform, it’s used specifically for building/deploying to different cloud environments quickly and easily. It’s coded in HCL (Hashicorp Language) which is essentially a more human-friendly version of JSON. As a result of AWS’s convenient endpoint setup, its incredibly easy to link services together. After successfully deploying, all that was then required was setting up SSL/https. For this, I just used a free certificate service called LEGO.

This project was equally informative as to the kind of work I would be doing at Cox as it was fun to poke around all of the different services provided by Amazon. If you’d like to see the terraform code referenced to in this post, you can find it here.

2018 Winter AI Project – Connect 5 Minimax

After finishing my previous project, I still found myself with plenty of time in-between classes (thankfully I’m only taking 4 courses this semester as opposed to my usual 6, so hopefully this trend continues throughout the semester). Also, as I recently took up a UTA position for CS2505 at VT (Intro to Comp Org), I found myself with plenty of down time on-shift as the early assignments are easy and most students don’t need help as of yet. Thankfully, some friends come and spend time with me to make the time go by faster. One of these friends typically brings a Go board along with her and loves to play connect 5 with us (think tic-tac-toe, but on a Go board, and you have to connect 5 instead of 3). After countless games, I thought back to my minimax algorithm for tic-tac-toe (here), and wondered if it applied smoothly to connect 5. And so, I decided to start working on this project.

First was to create the game. I was drawn to Java because I’m most comfortable working with object-heavy projects in Java (as opposed to something like Python). Coding the basic game was simple. The board itself is basically an 18×18 tic-tac-toe board. As such, I just used a 2D integer array size 18×18 and used constants for black, white, and empty spaces. I used swing for rendering, and KeyListeners for user input. Arrow keys navigate and enter places a piece. Upon placing a piece, control is handed over to the AI to decide the move they are going to take.

Screen Shot 2018-02-05 at 2.24.53 PM.png
Empty gameboard. The cursor is indicated with the red square (moves with arrow key input). As you’ll see later, the blue cursor (not shown here) indicates the previous move.

Next came calculating the heuristics for scoring any given board. I used this post by Ofek Gila as a foundation and built on that. Essentially, the board is traversed in every direction (horizontal, vertical, topleft->bottomright diagonal, topright->bottomleft diagonal) and consecutive pieces are counted and scored, with the sum total being the overall score of the current board state. The scores for consecutive pieces are based on the perceived value of that shape (i.e. a 5 in a row is worth much more than a single piece). I wanted this version to play very defensively (an annoying strategy for veterans of the game), so there are noticeable score differences based on what the color of the consecutive pieces is. Afterward, I began writing the minimax algorithm. The basic jist of minimax is to look a set number of moves into the future, score the current board state, and play off of the assumption that your opponent is going to make the best move for them at their given board state (hence the name minimax — you’re trying to maximize your gains and the opponent is trying to minimize them). I settled on looking 2 moves into the future, as it fit the balance of running quickly and decent decision making. If you want to learn more about minimax, feel free to look at the code for this project (link at the bottom).

Screen Shot 2018-02-05 at 2.23.14 PM.png
Using minimax, the AI (white) was able to defeat the user (black) here, while also stopping a win for black (if the white piece at the upper-right was not placed, black would have won)

Using this method, I ran into a couple of speed bumps. The major issue was performance. Especially at the beginning of the game, even after the user’s move, there are still 323 possible moves (18^2=324, -1 for the placed piece). That in addition to looking n moves into the future, meant that there are about 323^n checks that the algorithm needs to make (the number is actually slightly less than 323^n, as it doesn’t factor in placing new pieces and repeating the process, but it is essentially that value for small values of n, so we will ignore it for this basic analysis). To solve this, I cropped the board down to only ‘relevant’ spaces (I defined relevant here as any space around all of the current pieces in play with a buffer of 2 spaces on every side). Using this method, I was able to reduce the number of checks for 2 moves from 323^2=104,329 to 25^2=625 (placing one piece and creating a buffer of size 2 on every side creates a 5×5 grid, resulting in the 25 seen there (5^2 = 25)). Other than that, there is a bug in which the AI would let the player win if it won later down the decision-tree (in other words, it detected a win but didn’t take into account the opponent winning sooner). I expect this to be an error with scoring, but as I want to continue working on other projects, I will leave this bug in for now.

Screen Shot 2018-02-05 at 2.21.13 PM.png
You can see that the AI (white) detected a win, so it ignored black’s 3 in a row, ensuring a win for black.

Testing this out on some of my friends, I found that it played fairly decently. However, due to some minor bugs in the score evaluation (detailed at the end of the previous paragraph), veterans could consistently beat the bot (albeit after hard, long-fought games). This project was a fun one that I could share with friends, so I definitely enjoyed working on it and seeing it get better along the way. I encourage you to download the project and try playing against it yourself. You can find the github for this project here.

2016 Spring AI Project – TicTacToe & Brute Search

As my senior year of high school began to slow down and the college hype began to increase, I looked for simple projects to work on while in the midst of the craziness. Looking at the history of Artificial Intelligence, I began to read up on the different methods AI developers used before modern AI existed (Neural Networks would be an example of a modern day technique). I also decided to code this project in Python in order to broaden my skills with other languages (and because Python is pretty fun to use).

Artificial Intelligence for games like TicTacToe and Minimax are prime examples of early stage AI – programs that brute search their way through an entire list of possible situations in order to find the best action to take. However, brute searching only works on games with a small amount of game boards. For instance, Minimax is a really simple game because the amount of choices and paths players can take is very limited. TicTacToe ramps it up a little (about 9! or 362,880 different ways to play the game), but is still feasible with a little bit of load time. Games like chess, however, are almost impossible to brute search just from the sheer amount of games possible (about 10^10^50 games, in fact, there are more games of chess than grains of sand on the Earth). This means that although brute searching is an alright method to use when creating game AI, it isn’t always the most efficient, and other options should be considered the more complex the game is.

One of the main roadblocks I hit along the way on this project was dealing with recursion. I am familiar with recursion and its usefulness, but for more complicated tasks like this, it can become confusing at times (especially writing in an unfamiliar language, might I add). For those who don’t know much about recursion, it’s essentially a function that calls itself in order to simplify a problem. It’s complicated in that its formation is very abstract and you have to keep some key issues in mind while creating recursive functions (i.e., making sure you don’t accidentally create a function that loops indefinitely). After some frustration / hair pulling out, I was able to overcome the challenge and write a program that performs pretty well. Basically, the AI looks at each possible choice it has and finds the probability it will win if it chooses that path taking into consideration all possible game boards extending from that board. After probabilities for each possible spot to play are calculated, the AI chooses the option with the highest probability of success.

Screen Shot 2016-03-31 at 10.24.41 PM

Here the AI is controlling Xs and I am controlling Os. You can see the AI was successfully able to perform a double attack, forcing a win for Xs.

This project was fun to make. Comparing it with the Neural Networks I’ve made this year, It’s amazing to see how far Computer Scientists have come in terms of Artificial Intelligence and the ability for computers to recognize patterns and solve problems. If you want to see the code for this project, you can get it here: https://github.com/mccloskeybr/tictactoe

2016 Spring Game Project (In Progress) – Adventures of Mark

A lot has happened since my previous update nearly a month ago. The main area of my focus has been switching from a top down view to something more isometric (think games like Earthbound), and the perspective challenges that are associated with that. I’ve also added a lot of new objects, tiles, and items (including various shops). Making this game has really opened my eyes to just how many assets and things of the like are required for not just indie-games like this, but professionally done AAA titles as well, and how difficult and tedious asset creation can be at times.

One of my more recent undertakings has been overhauling the way I create levels in the game. Before, I used a system of images where each pixel was a tile in the level, which was tedious and inefficient for a variety of reasons. Memory wise, it required a relatively large amount of effort to load each level. Making the levels themselves was also difficult because I had to use a specific set of colors with precise R, G, and B values to get the desired outcome, and didn’t get to see what the final outcome would look like until I loaded it into the game. Now, I use a level editor that I made myself that really facilitates level making because you can actually see the tiles you’re placing instead of just solid colored pixels.

Screen Shot 2016-03-15 at 12.47.26 PM

Although it is a simple editor, it has everything I need to make levels quickly and efficiently. The lighter tiles are floor tiles while the darker tiles are walls. The blank spaces are place holders while I create more tiles to be input into the game.

Screen Shot 2016-03-15 at 12.48.14 PM

The map I created inside the level editor loaded into game.

It did take a little while to complete the map editor, and I still have to add objects, but the benefits definitely outweigh the costs. Now, the tile IDs are saved to a text file that can be easily read and made into a tile map that’s loaded pretty quickly.

Screen Shot 2016-03-15 at 5.06.39 PM

The text file created by the editor to be loaded into the game. This particular text file creates the level shown above.

When I first thought of making a level editor, I thought the idea was a good one, but backed away because I wasn’t familiar with a lot of the window components needed to make one (for instance JButtons and JToolBars). However, I’m glad I worked through and figured out how everything meshes together because making it was fun and interesting, and I can make levels more efficiently from now on.

If you want to see the game as it progresses in detail, you can visit the github repo here: https://github.com/VolitionDevelopment/The-Adventures-of-Mark

2016 Spring Game Project – Plane Challenge

As my senior year of high school began to slow down, I began to look at more relaxing and laid-back  projects. Games, to me, are fairly low stress as there isn’t that much problem solving (at least at the early stages), so I decided to make a couple of games during my final semester of High School.

On my spring break trip to Grand Cayman, I decided I wanted to see how much of a game I could make on the plane ride down. This resulted in a fairly simple game that was completed in roughly 2 hours (give or take 10 minutes). Granted, I did start laying the ground work while I was waiting to board, but most of the work was done on the plane itself.

The game itself ended up being about planes. As I didn’t have too much time to work on it, I decided to make a simple endless runner in which the player dodged obstacles while trying to get as far as they could get without dying. The player, in my game, controls a plane that can move left and right, dodging debris while also picking up health packs.

Screen Shot 2016-03-06 at 11.38.42 AM

As you can see, I really whipped out my AP Drawing art skills on this one. In reality, I wanted to spend more time coding than on asset creation (which definitely shows in the final product).

One of the challenges of making this game was creating an endlessly looping background. The way I ended up doing it was having one image that was the size of the window (500 x 500 pixels) that was stacked on top of itself 3 times. The resulting picture scrolls down and when it hits a specific point (close to the end), it jumps back up exactly 1 image height and continues to scroll down, resulting in the illusion of an endlessly scrolling image.

If I had a bit more time to work on this project, I’d first add a menu, then a scoring system that went up the longer the player was alive.

I’m now going to start uploading all of my projects to Github, so exploring the code is a little bit easier. If you want to see the code for this project, you can see it here: https://github.com/mccloskeybr/PlaneProject

© 2024 Brendan McCloskey

Theme by Anders NorénUp ↑