Battlecode 2016 Puzzle Solution

The 2016 puzzle was the following:

5DB777
A34D45
1B330E
877A2B

The puzzle prize was won by Willie Zhu. Other solvers included Jeffrey Shen and the pair Daniel and Steven Keyes.

Solution

The Battlecode game engine is open source, and the Github repository is linked on the specs page. The string 5db777a35d451b330e877a2b is actually the hash of a commit within the battlecode-server repository (find it with git checkout 5db777). It's a relatively innocent-looking commit titled "Qualifying tournament maps, part 2" on a branch new-maps.

Looking over the contents of that commit, there is a file ZombieSignal.java hidden among a bunch of XML map files. Looking at the constructor for ZombieSignal.java, you'll see that it is nonsense and doesn't even compile.

public ZombieSignal() {

private final Map> loadedCache; // 19
public MapLocation(int x, int y) { // 64
NORTH_EAST(1, -1), // 49
private String popupVersion = null; // 491
int roundsAvailable = match.getRoundsAvailable(); // 184
public static URL getUrl(String resource) { // 61
this.engineVersion = Version.version; // 78
// at the end of it, the loop will iterate once per game round. // 174
RobotType typeToBuild = robotTypes[fate % 8]; // 179
public IndicatorString(IndicatorStringSignal iss) { // 36
private final Class messageClass; // 47
im.put(KeyStroke.getKeyStroke("SPACE"), "space"); // 73
CLEANSED // 32

}

Each line above appears in one of the public repositories within the Battlecode codebase (battlecode-client, battlecode-server, and battlecode-scaffold). We'll keep track of the line numbers on which these above lines appear in other files as well as the commented number associated with each line:

Line number Comment File name (repository)
4819IndividualClassLoader (server)
3364MapLocation (server)
1749Direction (server)
36491MatchDialog (client)
78184GameStateTimeline (client)
3761ResourceLoader (client)
4178StoredConstants (server)
37 and 169174examplefuncsplayer/RobotPlayer (scaffold)
67179examplefuncsplayer/RobotPlayer (scaffold)
4536RoundDelta (server)
5947JsonSerializerFactory (server)
5273BaseCanvas (client)
3432DominationFactor (server)

There is another suspicious line in ZombieSignal.java. The 17th line of that file reads:

private static final long serialVersionUID = -1397820162120189142085185L;

A Java long can't have that many digits. Using 1 as A, 2 as B, 3 as C, and so on, the above message decoded to read "MIGHTPUTAHINTHERE", or "might put a hint here". Surely enough, in a future commit, this line is modified to read:

private static final long serialVersionUID = -2119512914514211319119914493519L;

Decoding that new message, we get "USELINENUMSASINDICES" or "use line nums as indices".

The numbers in the middle column somewhat scale with the lengths of the associated file. It turns out these are the line numbers we should look at in each file. Using the hint decoded above, on each of those lines, we will record the character at the index denoted by the number in the left column. For example, we'll take the 48th character on the 19th line of IndividualClassLoader.java, then the 33rd character of the 64th line of MapLocation.java, and so on. This spells out SLOWESTZOMBIE. In Battlecode 2016, the slowest zombie is the BIG ZOMBIE, the answer to this year's puzzle.