Back

Beat My Bot

Ever since I became the Game Development secretary, I had the idea of doing some sort of AI contest, where participants would create their AIs for some game, and they would battle it out in a tournament. Last December, while working on the Inter IIT submission, we came up with this idea of creating a Snake AI tournament. And since my college's flagship hackathon - Hackrush was coming up, we thought this would be the perfect time to host it.

Hackrush was initially supposed to happen in January, so some of my friends and I got to work creating the AI engine when the semester started. However, Hackrush got delayed :( So, since we had the entire engine and simulator ready, we decided to give it whirl anyway. We ran an independent event of Beat my Bot, and got positive feedback from the participants. So much so, that when we hosted it in Hackrush, I got motivated to start a YouTube channel and post a video about it.




The Engine


This was primarily handled by other team members, including Siddhesh, Hem and Nilay. The engine is primarily written in Go, and works as detailed here. The bots that the players make come with a config file, which identifies who they are. The engine communicates with the bots using IPC streams via stdin and stdout.


Now, every turn, the game state is serialised, and written to the bot's input. Cleverly, the engine automatically swaps the snake array order before sending the payload, so that from the receiving bot's perspective, they are always indexed 0. The engine then listens on stdout for a JSON response, which contains the direction the bot will move in, and a boolean "shed", which says if the bot will shed its skin or not.



Now feels like a good time to go over the rules.


The Rules

  1. The basic rule is the same as any old game of Snake. You, or in this case, your AI controls a snake. Every turn you specify which way your snake moves. There are apples, and you can eat them. You die if you hit yourself or the wall.
  2. But, of course, there is another snake here. Hitting the body of the other snake also kills you. If both snakes get into a head on collision, the longer one survives.
  3. Each snake has "energy", which goes down every turn. If it runs out, the snake dies. Eating any apple restores your energy.
  4. Speaking of apples, there are four types of apples in the game. Here is what they do:
    Image Apple Length change Status effect
    Apple Watch Apple +1 None
    Apple iMac Golden Apple +3 None
    iPhone 12 Speed Apple +1 Move two squares in one turn for 5 turns
    iPhone 12 Slowdown Apple +1 Freeze the other player for 5 turns
    iPhone 12 Poison Apple -1 None
  5. V2 addition: There are now trees that spawn apples. Green trees spawn regular apples around them, and golden trees spawn Golden, Speed and Slowdown apples. Hitting the trees kills the snake.
  6. V2 addition: Regular apples, if left out for too long (25 turns), will spoil to form poison apples.
  7. V2 addition: The snakes can choose to "shed" their skin at any turn. This is passed as a boolean, along with their movement direction for that turn. Shedding skin requires 5 energy. This shed skin can act as an obstacle.
  8. At the end of 500 turns, if both snakes are alive, then the longer one wins.

For every turn, the participant's script has a time limit of 500ms. If they exceed this turn, or submit an invalid move, then they keep moving in the direction they were previously. To ensure that the 500ms timeout is fair across varying hardware, the engine runs an automatic calibration, which benchmarks the host's machine.


Every state iteration, directional move, timeout instance, and execution time is appended to a record. Upon game completion, this data is compiled alongside timeout counts and error counts statistics into a "matchReplay" JSON file which is read by the simulator.


The Simulator


While the engine handles the game logic and bot execution, the simulator is a dedicated Unity environment built strictly for visualisation. We provided a simulator, or more of a rudimentary match status in the terminal itself, which looks like this:



To get more meaningful insights out of your matches, (and because frankly it looks terrible), I built an application in Unity, which will read the match replay JSON file, and acts as a playback client. The match replay JSON is loaded in, parsed into data structures, which hold sequential turn records, coordinates, and event triggers (timeouts or deaths). It iterates through the data step by step, and transforms grid coordinates into 3D movements.


According to the data, the simulator creates the appropriately sized grid board, then instantiates the obstacles, and on every turn, instantiates and removes prefabs for the player's bodies, apples, shed skin and trees. Also the UI displays the names of the competing bots, their lengths and their energies. Additionally, you can choose to load up any game file from the simulator itself, pause the simulation, take it step by step, and also change the speed of the match replay.



Building Beat My Bot from a simple idea discussed during our Inter IIT prep into a fully realized Hackrush tournament has been incredibly rewarding. This competition marks the final major project of my current term as DigiS Secretary, and seeing the participants push the engine to its limits was the absolute perfect way to wrap things up.


Between the late-night coding sessions, building out the simulator, and watching the final tournament unfold, I couldn't be prouder of what our team accomplished. And while this officially closes out my tenure, the club recently secured a brand-new, high-performance gaming PC. I’m already looking forward to seeing what we build next!