Battlecode 2016 Project for anim0l
My build order - 8 soldiers: 2 scouts: 1 viper: 1 turret.
Attack, in order - zombie dens, zombies, enemy non-(archon/turrets), enemy archons/turrets.
Archons do, in order - avoid enemies, activate close-by neutrals, spawn, look for parts and far-away neutrals.
Micro - generally the idea here was to try to maintain a local advantage, in addition to some special cases (vipers, zombies, etc.). Basically, you look at units that only have you in its attack range, and try to make this number as small as possible (ideally 1 or 0). Generally this ensures that your unit never gets into a 2 on 1 situation, where you allow two more enemies to attack, but only one more of your units.
Pathing - I had some leftover bug algorithm code from last year, which has always been pretty robust, but the terrain was destructible and dynamic this year, which screws things up badly. Eventually, I just settled on:
- Move in one of the three directions (dir, left, right) towards the goal with the least amount of rubble, if possible.
- Otherwise, start a bug towards the goal, and stop bugging if you can do 1.
Cool technical things: There's some cool bit-hacking for looking up how enemies can attack each of the directions around you. The code is in AttackerLookups.java, with a giant switch case as a lookup table (auto-generated by PreAttackerLookups.java). It gives up to an 8-9 times speed up in step 2:
- for each enemy (range, x-offset, y-offset), return an packed integer that has which directions it can attack
- add up all these integers
- unpack these integers into an array of ints (and use dir.ordinal() as the index)
Most of my bot didn't come together until literally the last day (just look at my commits, if you don't believe me), and it really goes to show how important iterating quickly is, which I didn't do for the first n-1 days. I probably went from rank 64 to around 16 in the last day alone, and still had a lot of things that I didn't implement (have infected soldiers run at enemies, better archon avoiding code, probably better turret positioning, having low hp soldiers run back to archons). My last day's cycle went like: upload bot and scrim against as many people as possible, identify something concrete that I don't have that makes me lose, then add it in and repeat.
A couple other lessons that I had:
- Try to avoid strategies that require a lot of complex coordination from all your bots, it'll just introduce lots of bad failure modes.
- Infrastructure-wise, it's probably best to just have a separate controller for each unit type, and utility classes for common functions that you need to abstract away (I tried to make some number of behaviors and combine them all in one controller class, but that never really worked well.)