It began in Singapore, where the top young coders sent thousands of soldiers to destroy one another. It then spread worldwide, turning innocent game developers into sorcerous warlords. The sky darkened with arrows, spears, artillery shells, and clouds made of solid gold. Freed from eternal imprisonment by countless reckless targeting algorithms, the mountain yetis charged into the fray, causing a worldwide bone shortage. The Zero Sum programming tournament was upon us.
The #1 ogre king is the returning champion Wizard Dude (Michael Heasell) with 162 wins and 1 loss across all human opponents. In second is xxx9877654321, with nemoyatpeace in third.
The #1 human king is the unstoppable NoJuice4u (Wayne Chen) with 105 wins and 3 losses, trailed by Qenf in second, with Stofflon and Driphter tied for third.
We’ve posted the full rankings here for all 193 players.
When two kings of code go head to head, mountains shake and widowers wail. Watch the climactic battle between human NoJuice4u and ogre Wizard Dude to see who won the ultimate matchup.
Wizard Dude won our first tournament, Greed, and so the mere sight of him on the battlefield terrified his hapless Zero Sum opponents, not least because he had won a custom CodeCombat hero in the last event. He has posted his full code on GitHub and written a detailed blog post about the strategy behind his 1034-line solution.
Wizard Dude optimized for winning the first fight, which usually decided the game as well. He relied on his superior coin collecting (using the forces-based approach he invented in Greed) to play defensively and build up a numbers advantage, only fighting when necessary.
To maintain a strong army, he delayed summoning units until the last moment and only griffin-riders and soldiers for a simple balance of damage and tanking, including targeting ranged attackers and kiting soldiers. He used a prioritized list of actions to control his hero, including tactics like:
- Cast fear on a yeti targeting his hero, or on the enemy sorcerer
- Flee the yeti and collect coins if it's nearby
- Cast raise dead if there are two corpses in range that aren't artillery
- Sort enemy troops into bins across the level, find the bin with the most enemies, find the centroid of those enemies, and run there to mana blast them
- Use the hero to attack any artillery the enemy has summoned
- Cast goldstorm if the enemy hero is too far away to steal the loot
- Jump long distances whenever jump is ready
- Reset cooldown on mana blast, raise dead, and fear if those actions are needed but not ready
- (e.g. do not bump into the Yeti, if nothing to do then collect coins).
Read Wizard Dude's full post for more details on his strategy. He describes his experience participating in the tournament:
CodeCombat imposes an upper limit on the amount of code you can execute in a given game. This limit is normally never hit, since I think this is intended to prevent problems with newer programmers accidentally writing very inefficient code. For Zero Sum however it was easy to hit this limit amidst all the chaos. For a while, the battle was more about fitting smart logic in under the limit than actually coming up with it! To help me with optimizations I started using sweet.js macros to automatically generate some of the more boring boilerplate code. I used a gulp task to have it auto-rebuild my output every time I hit save in my editor so I could copy and paste it straight into CodeCombat. I also ended up splitting things into multiple files as my code got longer.
Quite near the end of the tournament, in response to feedback on the forum, the hard execution limit was tripled. This suddenly made a lot of ideas more practical to implement, so a lot of my final AI sprang up over the last weekend as I raced to make use of all the extra statements.
Up until about Saturday afternoon I didn’t really think I had a hope of winning. The previous version of my AI used a system of utility values to decide which action to take, but tuning how the utility scaled for each action was basically guess work and made it impossible to understand the resulting behaviour. I was only at about 20-30th with this code and I had no idea how to fix it. On Saturday I threw it all out and started back with the simpler fixed ordering and suddenly things were a lot more promising. Coincidentally, this was also the first day that my custom surfer dude sprite, one of the prizes from my Greed tournament victory, showed up in my Zero Sum games. I did it for you, little buddy.
My strategy largely tries to ignore the yeti. However, I did have a problem with my hero trying to go through the yeti cage to get to things on the other side. I ended up writing some special case logic to steer me around the cage if I am trying to get to the other side.
Zero Sum was, as always, a fun tournament to be in. I think CodeCombat really outdid themselves with the level of chaos in this latest arena and have provided a good framework for implementing clever strategies. I’m sure the next tournament will be even better! Be sure to watch out for the wizard with the surfboard and drink, I hear he’s quite a feisty opponent.
NoJuice4u is a strategic mastermind. He took the top human spot with just 291 lines of code in his deadly, dense solution.
NoJuice4u used a vector-based coin collection algorithm that would tell his hero to move in a direction rather than to a specific coin’s location. He broke his battle strategy into three phases:
- Get ready for combat: engage in controlled formation
- Skirmish: use advanced tactics to overwhelm the opponent's forces and gain a gold advantage
- When the yeti appears, abandon all decorum to kill the enemy sorcerer, while using fear to avoid it, and using friendly troops to lure the yeti closer to the enemy hero.
NoJuice4u’s hero ability use was more situational rather than a simple prioritized list executing against cooldowns. For example, his first mana Blast was used to run in and scatter opponents during the first engagement, while following blasts were based on enemy clusters and current move destination. He prioritized casting fear on the enemy hero over all else. He also used griffin-riders and soldiers, but found that keeping an archer back in the ranks away from his griffin-riders often helped him dish out additional damage.
For a detailed explanation of NoJuice4u's strategy, check out his detailed writeup.
Though the Zero Sum tournament is over, the arena will stay open, so have fun grabbing gold and working on your micro AI. (Anyone want to take advantage of artillery's insane power and add missile dodging to avoid friendly fire? I do!) See you on the ladder.