Every couple of weeks, there is a contest hosted by the folks at codingame.com. This time around it was a game of Quidditch from the Harry Potter world and was named Fantastic Bits after the Fantastic Beasts and Where To Find Them
If you just want to look at my statistics for this contest, you can just scroll to the bottom but, then you would miss seeing all the things I did wrong :)‚
For the contest, you played a game of Quidditch and controlled 2 wizard to score points using a Snaffle (Snitch + Quaffle). Like all other codingame contest, the game was turn based, where each turn consisted of you reading the world state information from stdin and outputting your action to stdout. This would be repeated till either 200 turns had passed or as soon as one player has scored more than half of the possible points. You also had a maximum of 100 ms to submit your action before you would timeout and lose.
There are multiple leagues : Wood 2, Wood 1, Bronze, Silver, Gold and Legend. To pass each league, you need to beat the boss of that league. Everyone starts from Wood 2 and depending on how good their bot fares, they move to the higher leagues. Also, as you move to the higher leagues, extra rules might apply. For example, in wood 1, Bludgers made their entrance and you could start casting spells from the Bronze league.
There are multiple languages that you can use to submit your solution but for obvious reasons C++ is was what I went for.
What Went Right
- I had already participated in a previous contest at codingame which gave me a base to start from. For other postmortems click here.
- Working with web IDE (especially with C++)is a bit clunky but on the forums, I found a google chrome plugin that allowed my to sync a local file to the web IDE. This allowed me to work in Visual Studio which made for a much faster workflow. The plugin can be found here.
- I found another tool on the codingame forums which allowed me to test my ide code against other players without actually submitting my code. The code also allows to compare the ide code with the submitted code. The plugin can be found here.
- I already had a setup which allowed me to combine multiple files into a single cpp file which codingame requires. If you would like a copy of the tool, let me know in the comments and I can make it available.
- I spent the first day setting up the framework for the game. This included classes to encapsulate the Wizards, Snaffle etc. This allowed me to quickly tweak my algorithms and throwaway pieces of code that I felt were not working.
- I started with a very simple algorithm which was able to get me into the gold league. I reached the bronze league with just chasing after the closest snaffle and trying to throw it in the opponents goal. For silver and gold, as soon as I had enough mana, I used an Accio if the snaffle was behind a wizard or a Flippendo if the snaffle was in front of a wizard and was aligned with the goal.
- I was able to simulate a portion of the game except for the collisions. I did write some collision code but it is untried and untested.
- From earlier contests, I had a python script to help download the game data, parse it and put it into a txt file which would be consumed by my program. This allowed me to step through and debug the AI, when I could see that my AI was failing to win because of some bug instead of just rely on the stderr stream. f you would like a copy of the script, let me know in the comments and I can make it available.
- Continuous refactoring enabled me to keep my code readable and isolated the areas that I had to work on.
- Working iteratively and using the tools above meant that I could see the impact almost immediately.
- Using source control to keep track of the AI. I cannot even stress how helpful it was to go back a version or two, because the new logic was performing even worse than the one a few iterations before. This was especially true when I tried to add support for the spells ‘Petrificius’ and ‘Obliviate‘.
- I made it to the Gold League, which was one of the goals I had set for myself.
What Went Wrong
- Being in New Zealand for the contest from a timezone perspective sucks. The contest starts and ends when you are sleeping.
- I did not get to spend as much time as I would have liked on this. With work and other personal commitments, I was only able to spend a few hours on the problem. I was also unable to work on the weekend just before the contest ended which dropped my rank from the early 400’s to below 600 by the time I ended the contest.
- I wasted a lot of time in trying to get the 2 spells ‘Petrificius‘ and ‘Obliviate‘ to work. In retrospect, I should not have even tried this without having a robust simulation and probably a Genetic Algorithm.
- I read the Magus’s postmortem and implementation of CSB quite late. Having implemented parts of it would have helped considerably for this contest. Although, other than trolling the chat/forums, I don’t see how I could have found this earlier. It might be worthwhile for Codingame to give a reference of which bot contest can be used to practice on a few days before the competitions starts.
- My knowledge and interest in physic systems is quite low. In order to have a robust simulation, a good knowledge of collision avoidance was required.
- I did not get time to implement a Genetic Algorithm or a MCTS which would have probably helped me gain ranks much faster.
- When I was around the 300 mark, I decided to resubmit the existing code. Big Mistake. Even though my code was the same, my rank dropped like a stone under water. This was probably because other players had submitted improved code and a submit causes a test against all of them. The lesson learnt here is that gain ranks early and submit only if you relatively sure of gaining more ranks.
- There was lot of information that had to be simulated such as mana, collisions, and some inputs for the opponent. It was just a lot of work to do along with writing an AI. I guess it would have been easier if I had code that I could reuse from one of the earlier contests
- I did not take into consideration that the spells take 1 frame to take effect.
- The way I had written the code, the 1st first wizard would always end up using all the mana. This was in retrospect inefficient and I could have improved this without too much effort.
What would I do differently
- Being better at deciding which feature to implement and when to give up and move to some other feature.
- Try to simulate the game so that I could test everything locally before submitting my code and also be able to use more complex AI techniques.
- This was a fun contest with amazing visuals and complexity.
- The twitch stream helped me get familiar with the spells.
- If you want a copy of any of my tools, let me know in the comments and I can make it available.
- It would be great, if once the contest has ended, links could be provided to tutorials for the various AI techniques that were successful. An example of this would be Magus’s implementation of CSB
Global Rank: 642/2399
New Zealand: 13/18
Feel free to follow me at codingame using this url.