archive by month
Skip to content

Steamhammer and stealing gas

Back in an early Steamhammer release, I tested stealing gas, concluded that it worked, and called it good. Since then I haven’t paid much attention.

Now I’m working through systematically to make sure that stealing gas always works when it should, and that it interacts correctly with scouting (which has grown more complicated since then). While I was looking away, the gas steal bitrotted as its surroundings changed and it did not keep up. For example, in testing with terran today I fixed a bug where the scout arrived at the enemy geyser, queued up a refinery on it... and then BuildingManager assigned a different worker to do the job, sending an SCV from the main. I even found and fixed a potential crashing bug, though it could only happen on very nonstandard maps.

Next: Steamhammer vs. PurpleWave games.

Steamhammer-tscmoo games

When I first promised Steamhammer-Tscmoo games, Steamhammer had been winning most games against Tscmoo terran, despite dangerously aggressive terran play. Some of the games were good. Since then, Tscmoo has been updated, and now most of the Tscmoo bots (all except protoss) are ranked just above Steamhammer. Games have gone both ways, but I think Tscmoo has the edge overall.

a September game

In this game on Roadrunner Steamhammer played a 3 hatch lurker build that was a direct counter to Tscmoo’s fast academy. If zerg had played accurately, it would have been an easy win. As it was, zerg was unclear on the concept of defense and narrowly held by accidentally making just enough zerglings in a hardscrabble game. If Steamhammer had played a mutalisk opening, it would have lost, because the muta openings make fewer lings. Here Tscmoo’s last attack has broken through and the small terran force is frying drones—most of the drones in the picture died.

Steamhammer loses drones

But lurkers were already out, and Steamhammer broke the attack with a hammer blow and then turned the hammer outward.

Tscmoo loses everything

a recent game

Lately, Tscmoo terran has been playing sequences of tricky tech switches. Tscmoo played random on Destination in this game and got terran. It’s a 2 player map, and terran started with a barracks on 6 hidden in the corner of the zerg natural out of sight of the scouting drone, an early proxy that could be deadly. Luckily, Steamhammer tries to be ready for anything against a random player, and it opened with a safe overpool. Tscmoo in turn scouted Steamhammer’s safe opening and opted not to train marines right away (they would have died uselessly), but to move on to the next tech.

Early zerglings still did not spot the barracks. Tscmoo made marines in time for Steamhammer’s expansion; it may be a coincidence, but maybe Tscmoo is smart enough to know the timing. In any case, as you can see from the unit counts, zerg was more than prepared.

Steamhammer finds the barracks

Most of Steamhammer’s lings went to the terran main, as you can see in the minimap above. Tscmoo has strong worker defense, and the fight was not entirely one-sided. And of course Tscmoo had been preparing its next tech, vultures. When they were done, the vultures chased the lings out. Steamhammer knew what was coming, though, and put down a sunken in its main for safety, and one in the natural a little later when the natural finished. The vultures also did not achieve much.

Meanwhile, Tscmoo started a starport, the next tech switch. Steamhammer saw that too and put down a hydra den while trying to catch up in workers; despite killing a few SCVs, zerg was behind because it had made too many combat units. But instead of putting on wraith pressure, Tscmoo made an extreme move while waiting for wraith cloak research to finish: It added a tank (without siege) and pulled almost all its SCVs across the map for an all-in attack.

Tscmoo pulls SCVs

Steamhammer knew how to defend this one. Zerg made an emergency switch to mass lings with a few hydras, and with the help of the sunken the attack was beaten back with heavy losses. Zerg went from behind to ahead, plus Steamhammer started a spire and was able to safely return to droning up. Zerg had wasted money on lurker research, but it no longer mattered.

Tscmoo finally pulled the wraith switch, but the long delay meant that Steamhammer was again ready. The first wraith was able to kill a couple drones before scourge hatched. The wraith instantly cloaked when it saw the danger, but cloak is no use when you have chosen to fly right next to an overlord.

Steamhammer realized, more slowly than it should have, that mutas were the right choice, and brought pressure back to the terran. Tscmoo switched again, to valkyries for air defense, but zerg scourged most of them and terran could not hold the line long enough to build a stable force. (If it had, Steamhammer was still ahead and I think it would have switched to hydras and won anyway. It knows how.) Here scourge are intercepting the first valkyrie—by coincidence, the scourge were waiting by the starport (someday I’ll add code to do that on purpose).

scourging a valkyrie

I think Tscmoo showed greater ability, but it took big risks which did not pay off in this game. The SCV pull in particular was not a smart plan. Even so, you can see how easily zerg could have made a mistake and lost; Tscmoo earned its high place in the ranking.

Here’s a human game with a similar sequence of terran tricks: July vs Firebathero from 21 September, on the map Hitchhiker. Firebathero’s sequence of bunker to vultures to wraiths is 100% standard. July was ready and had some zerg tricks in response. Even if you don’t have much Starcraft expertise, it should be easy to see that this game is on a way higher level than the bot game.

Steamhammer’s devourers are almost OK now

A quick note: I finally got devourers working sort of OK in the development Steamhammer. They are no longer horrible and useless as in the live version. Of course this means that I instantly get new items on my to-do list, like “teach other units to target enemies that carry acid spores” and “teach FAP about the effects of acid spores.” One step at a time!

As a side effect, corsairs and valkyries are also better. The corsair-dark templar opening is improved to the point that it is... not good, but within shouting distance of acceptable. The work was a combination of bug fixes, improved tactics, and adding a new MicroAirToAir unit controller for the air-to-air splash units.

AIIDE 2017 AILien does not learn

AILien’s learning turned out to be non-existent in the AIIDE 2017 version. It writes files but does not read them back in.

Here is AILien’s recorded data from AIIDE 2017 for the opponent XIMP.

lingScore=24.4783
hydraScore=-4762.48
lurkerScore=0
mutaScore=-904.381
ultraScore=-1757.08
guardScore=0
macroHeavyness=0
supplyISawAir=149
strategy=17
victory=false

The first six lines are information about what units to make, as updated during the game. macroHeavyness and supplyISawAir are updated but I didn’t find any sign that they are used for anything; I think they were used in a former version. strategy likely used to be an index into the unused GameCommander::strategyMap, but no matter what it originally was, now it is a constant. And victory is the result of the most recent game. As I said at the start, the information is written out but is never read back in.

Next: Those tscmoo games I promised last month.

AIIDE 2017 what AIUR learned

Here is what AIUR learned about each opponent over the course of the tournament. I did this mostly because it’s easy; I already had the script from last year. But it’s also informative—AIUR’s reactions tell us how each bot played, and may tell bot authors what they need to work on.

The data is generated from files in AIUR’s final read directory. AIUR recorded 111 games against some opponents even though the tournament officially ran for 110 rounds; that is presumably because the tournament did run longer but was cut back to a multiple of 10 rounds for fairness (since there are 10 maps). On the other hand, AIUR’s total game count according to itself is 2938 and according to the tournament results is 2965, so it may have been unable to record some games (it is listed with 53 crashes, so that’s not a surprise). First an overall view, totalling the data for all opponents. We can see that all 6 of AIUR’s strategies (“moods” it calls them) were widely valuable: Every strategy has win rate over 50% on some map size. AIUR’s overall win rate in the tournament was 50.46%.

overall234total
 nwinsnwinsnwinsnwins
cheese15955%5937%16144%37947%
rush13466%8755%18550%40656%
aggressive10756%10843%15530%37041%
fast expo6945%8433%19751%35046%
macro4628%6952%21137%32639%
defensive35260%18558%57055%110757%
total86757%59249%147948%293850%
  • 2, 3, 4 - map size, the number of starting positions
  • n - games recorded
  • wins - winning percentage over those games
  • cheese - cannon rush
  • rush - dark templar rush
  • aggressive - fast 4 zealot drop
  • fast expo - nexus first
  • macro - aim for a strong middle game army
  • defensive - be safe against rushes (not entirely successful)
#1 zzzkbot234total
 nwinsnwinsnwinsnwins
cheese1612%10%40%2110%
rush50%10%10%70%
aggressive30%10%50%90%
fast expo40%10%50%100%
macro30%20%30%80%
defensive30%1631%3724%5625%
total346%2223%5516%11114%

AIUR struggled against the tournament leader but was not entirely helpless. Its cannon rush had a chance on 2 player maps and its anti-rush strategy on the others. We see how AIUR gains by taking the map size into account.

#2 purplewave234total
 nwinsnwinsnwinsnwins
cheese10%10%20%40%
rush2879%333%4055%7163%
aggressive10%333%10%520%
fast expo10%1136%1060%2245%
macro10%20%10%40%
defensive10%10%10%30%
total3367%2129%5551%10951%

AIUR upset #2 PurpleWave, a surprising outcome. The DT rush and the fast expand were both somewhat successful—rather unrelated strategies.

#3 iron234total
 nwinsnwinsnwinsnwins
cheese50%10%70%130%
rush50%20%70%140%
aggressive30%20%120%170%
fast expo80%147%90%313%
macro60%10%100%170%
defensive50%20%100%170%
total320%225%550%1091%

Learning can’t help if nothing you try wins....

#4 cpac234total
 nwinsnwinsnwinsnwins
cheese10%10%10%30%
rush40%00%20%60%
aggressive20%10%10%40%
fast expo10%10%10%30%
macro20%333%20%714%
defensive2438%1669%4850%8850%
total3426%2255%5544%11141%

Cpac was configured to play 5 pool against AIUR. It worked, but AIUR was able to compensate to an extent by playing its anti-rush build.

#5 microwave234total
 nwinsnwinsnwinsnwins
cheese20%20%40%80%
rush10%10%40%60%
aggressive2020%1513%110%4613%
fast expo10%20%60%90%
macro10%10%40%60%
defensive10%10%2612%2811%
total2615%229%555%1039%

Microwave was successful but showed a little vulnerability to surprise zealots dropped in its main. I suspect it’s a tactical reaction issue.

#6 cherrypi234total
 nwinsnwinsnwinsnwins
cheese10%10%10%30%
rush10%10%10%30%
aggressive20%20%10%50%
fast expo20%10%10%40%
macro20%10%911%128%
defensive264%1612%4212%8410%
total343%229%5511%1118%


#7 mcrave234total
 nwinsnwinsnwinsnwins
cheese26100%560%4562%7675%
rush367%967%450%1662%
aggressive10%450%10%633%
fast expo10%250%250%540%
macro10%10%10%30%
defensive10%10%20%40%
total3385%2255%5556%11065%

AIUR upset McRave with its cannon rush, and the dark templar rush did well too. AIUR executes the best cannon rush of any bot, in my opinion. It is a sign that McRave’s play was not robust enough against tricks.

#8 arrakhammer234total
 nwinsnwinsnwinsnwins
cheese20%20%30%70%
rush10%10%40%60%
aggressive10%560%30%933%
fast expo10%10%20%40%
macro00%1250%3837%5040%
defensive2966%10%425%3459%
total3456%2241%5428%11039%


#9 tyr234total
 nwinsnwinsnwinsnwins
cheese667%10%10%850%
rush20100%10%20%2387%
aggressive333%1020%10%1421%
fast expo10%729%4935%5733%
macro10%10%10%30%
defensive250%20%10%520%
total3379%2218%5531%11043%

The DT rush won 100% of the time on 2 player maps and was tried only a few times on larger maps, losing. Was it only unlucky on the 3 and 4 player maps, or is there a real difference? With only 3 games total, we can’t tell from the numbers. It is a weakness of AIUR’s learning: It’s slow because there is so much to learn. The flip side of the slowness is that, over a long tournament, it learns a lot.

#10 steamhammer234total
 nwinsnwinsnwinsnwins
cheese20%10%10%40%
rush250%10%20%520%
aggressive10%10%10%30%
fast expo10%10%10%30%
macro00%10%10%20%
defensive2781%1788%4967%9375%
total3370%2268%5560%11065%

I was surprised to see Steamhammer upset by AIUR. I had thought that AIUR was a solved problem. On SSCAIT too, Steamhammer started to show losses against AIUR in September for the first time in months. I may have introduced a weakness in some recent version and AIUR’s learning took that long to find it on SSCAIT. In AIIDE, the tournament was easily long enough.

#11 ailien234total
 nwinsnwinsnwinsnwins
cheese10%10%10%30%
rush30%10%20%60%
aggressive10%20%10%40%
fast expo10%250%00%333%
macro450%875%10%1362%
defensive2458%888%4937%8148%
total3447%2264%5433%11044%


#12 letabot234total
 nwinsnwinsnwinsnwins
cheese743%10%20%1030%
rush333%1354%4340%5942%
aggressive540%10%10%729%
fast expo1346%333%10%1741%
macro10%10%633%825%
defensive10%333%10%520%
total3040%2241%5435%10638%

I suspect that fast expo was the best strategy on 4 player maps, but how was AIUR to know? A weakness of AIUR’s epsilon-greedy learning, compared to UCB, is that it doesn’t realize that a less-explored option is more likely to be misevaluated.

#13 ximp234total
 nwinsnwinsnwinsnwins
cheese3435%00%10%3534%
rush00%00%10%10%
aggressive00%138%522%653%
fast expo00%90%00%90%
macro00%00%10%10%
defensive00%00%00%00%
total3435%225%552%11113%


#14 ualbertabot234total
 nwinsnwinsnwinsnwins
cheese00%00%1100%1100%
rush00%00%00%00%
aggressive00%00%1100%1100%
fast expo00%00%00%00%
macro00%00%00%00%
defensive3432%215%5227%10724%
total3432%215%5430%10926%

What’s up with all those zeroes? AIUR is coded to try each strategy once before it starts making decisions, and that did not happen here. It turns out that AIUR has pre-learned data for Skynet, XIMP, and UAlbertaBot, so its learning in those cases looks different.

#16 icebot234total
 nwinsnwinsnwinsnwins
cheese10%20%10%40%
rush10%250%333%633%
aggressive3100%367%450%1070%
fast expo14100%367%4493%6193%
macro475%250%10%757%
defensive989%1080%250%2181%
total3288%2264%5582%10980%


#17 skynet234total
 nwinsnwinsnwinsnwins
cheese1392%00%00%1392%
rush2195%2190%5188%9390%
aggressive00%00%00%00%
fast expo00%1100%00%1100%
macro00%00%00%00%
defensive00%00%450%450%
total3494%2291%5585%11189%


#18 killall234total
 nwinsnwinsnwinsnwins
cheese10%30%10%50%
rush10%20%10%40%
aggressive10%20%10%40%
fast expo10%30%10%50%
macro00%20%250%425%
defensive3080%1070%4976%8976%
total3471%2232%5569%11162%


#19 megabot234total
 nwinsnwinsnwinsnwins
cheese367%10%20%633%
rush20%1436%50%2124%
aggressive667%425%40%1436%
fast expo250%10%40%714%
macro10%10%3625%3824%
defensive1776%10%20%2065%
total3165%2227%5317%10633%


#20 xelnaga234total
 nwinsnwinsnwinsnwins
cheese9100%683%10%1688%
rush19100%475%10%2492%
aggressive10%333%10%520%
fast expo10%475%10%650%
macro20%250%5036%5435%
defensive250%367%10%650%
total3485%2268%5533%11156%

Against Xelnaga, AIUR found solutions on 2 and 3 player maps but not on 4 player maps. Is it another case of underexploration?

#21 overkill234total
 nwinsnwinsnwinsnwins
cheese10%10%367%540%
rush250%00%00%250%
aggressive8100%4100%786%1995%
fast expo367%3100%7100%1392%
macro475%367%1292%1984%
defensive1493%11100%2696%5196%
total3284%2291%5593%10990%


#22 juno234total
 nwinsnwinsnwinsnwins
cheese50%1436%3315%5219%
rush30%10%10%50%
aggressive20%10%20%50%
fast expo20%10%1612%1911%
macro10%10%10%30%
defensive1921%425%20%2520%
total3212%2227%5513%10916%

Juno’s cannon contain upset AIUR. Learning didn’t help much, because the problem wasn’t in any of the strategies, it was in AIUR’s poor reactions to cannons appearing in front of its base. It is amusing to watch 2 bots cannon each other when sometimes both get cannons up.

#23 garmbot234total
 nwinsnwinsnwinsnwins
cheese10%10%10%30%
rush250%10%00%333%
aggressive1794%17100%367%3795%
fast expo00%10%2383%2479%
macro00%10%10%20%
defensive580%10%2781%3379%
total2584%2277%5578%10279%


#24 myscbot234total
 nwinsnwinsnwinsnwins
cheese10%10%250%425%
rush20%367%250%743%
aggressive333%2100%978%1471%
fast expo10%250%10%425%
macro450%4100%367%1173%
defensive2361%10100%3879%7176%
total3450%2286%5575%11169%


#25 hannesbredberg234total
 nwinsnwinsnwinsnwins
cheese580%3100%367%1182%
rush250%3100%250%771%
aggressive250%250%20%633%
fast expo8100%3100%989%2095%
macro250%4100%1191%1788%
defensive15100%7100%28100%50100%
total3488%2295%5589%11190%


#26 sling234total
 nwinsnwinsnwinsnwins
cheese250%10%333%633%
rush250%00%10%333%
aggressive12100%00%2396%3597%
fast expo10%5100%10%771%
macro367%580%1275%2075%
defensive580%11100%1580%3187%
total2580%2291%5580%10282%

Here is another possible case of insufficient exploration. The 4 zealot drop won 100% of the time on 2 player maps and 96% of the time on 4 player maps, but was never tried on 3 player maps (I guess due to a crash, since AIUR tries to play each strategy once). It’s not a severe problem, though, because 3 player maps did have 2 strategies that scored 100%.

#27 forcebot234total
 nwinsnwinsnwinsnwins
cheese10%10%10%30%
rush00%10%10%20%
aggressive367%20%10%633%
fast expo00%10%10%20%
macro00%978%367%1275%
defensive29100%875%4894%8594%
total3394%2259%5585%11083%


#28 ziabot234total
 nwinsnwinsnwinsnwins
cheese12100%786%3686%5589%
rush10%1100%475%667%
aggressive6100%888%683%2090%
fast expo10%10%20%40%
macro30%10%10%50%
defensive667%475%683%1675%
total2976%2277%5580%10678%

Next: AILien’s learning.

AIIDE 2017 the learning bots

In March 2016 I analyzed which bots learned during the AIIDE 2015 tournament by looking at the data files. Here’s a similar analysis for AIIDE 2017.

I looked at the “write” directory for each bot, to see if it wrote files there, and if so, what the files looked like. Writing data doesn’t mean that the bot actually learned anything—it may not have used the data. Bots not listed in the table did not write anything interesting (maybe log files, nothing more). The table includes 15 bots of the 28 entrants, over half of them.

#botinfo
1ZZZKBotvaried info about each game, including tidbits like the time zone and the processor it was played on
2PurpleWavefor each opponent, a log of games with info including the sequence of strategies followed
5Microwavesame format as UAlbertaBot (Microwave has more strategies)
6CherryPiopening data for each opponent
9Tyrfor each opponent, seems to save info only about the previous game: win or loss, and a flag or two like "FLYERS" or "CANNONS"
11AILien10 values per opponent: scores for zerg unit types, a few odds and ends like macroHeavyness and supplyISawAir
12LetaBotone file which records a log of games, with opponent, race, map, and 3 numbers per game
14UAlbertaBota file for each opponent, giving for each strategy the count of wins and losses; learning was turned on this year
15Aiur91 values per opponent: strategy x map size
17Skyneta file for each opponent, with lines like "build_0_2 14 12"
19MegaBotmany files; the important ones seem to be "MegaBot-vs-[bot name].xml" which give scores for each bot MegaBot can imitate: Skynet, NUSBot, Xelnaga
20Xelnagaa file for each opponent with a single number: -1, 0, 2, or 3
21Overkillmany files with neural network data, reinforcement learning data, and opening learning data for each opponent (more than I thought!)
24Myscbotsame format as UAlbertaBot, but only 1 strategy was played for each opponent; nothing was learned
25HannesBredberg2 numbers per opponent, approximately (not exactly) the win and loss counts

LetaBot seems worth looking into, to see whether its log is learning data and, if so, how it is used. PurpleWave also recorded data essentially as a log, which could be used for a wide range of purposes. And AILien has a unique learning method that I should spend some time on.

UAlbertaBot had learning turned on this year. It has sometimes left learning off because its default strategies were dominant. It’s also notable that Ziabot skipped learning this year. In the past it has learned. Ziabot also finished last.

Next: What AIUR learned.

Overkill’s games

In September I looked into the source of Overkill AIIDE 2017. It has much more extensive and ambitious learning than Overkill 2016. But at the time, no replays were available, so I didn’t know how well the learning worked.

Overkill 2017 has 2 kinds of learning. One is online opening learning, which of 3 openings to play against each opponent. This is the same simple method as many other bots. The other is strategy learning, what to build/research/etc. next; I think this learning is offline, done ahead of time. The graph of win rate over time shows a modest increase in score throughout the tournament, consistent with the opening learning. The modest increase was enough to pull Overkill ahead of 5 different opponents that started out better.

Here is Overkill’s tournament history. I believe these tournaments represent 3 different versions of Overkill. The 2017 version played only in AIIDE 2017.

tournament#%
CIG 2015381%
AIIDE 2015381%
CIG 2016 qualifier471%
CIG 2016 final551%
AIIDE 2016762%
CIG 2017760%
AIIDE 20172133%

It’s safe to say that the learning was not successful.

What did the games look like? In every game I looked at, Overkill played sunken defense and then seemed hesitant and uncertain what to do next. It researched tech that it did not use, or did not use until much later; it made scourge when the opponent had shown no sign of air units; it added more hatcheries than its income could feed. The sunken defense worked especially poorly when the opponent went air. The basic mistakes caused weak results. I don’t know the training procedure; I can only guess that maybe the neural networks were not trained enough, or were trained on crummy data, or were misled by bugs. Or something.

Oh well. :-( Learning is hard.

Overkill-McRave is one of Overkill’s better games. #21 Overkill scored 50% against #7 McRave, which you could count as an upset. Overkill-IceBot is a more typical game with some OK action. Overkill-Juno is a sad, sad game that ran the full hour due to suicidal play by both sides.

Next: Catalog of bots which wrote learning files.

looking at cpac

Cpac is a Steamhammer fork, so it’s easier for me to evaluate. On the other hand, the code has been reformatted, so a diff only says “everything’s different.”

Overall, cpac is very similar to Steamhammer, but corrects critical weaknesses. I think the author chose accurately which weaknesses were important to correct, and cpac should play clearly better than Steamhammer in many situations. It implements a number of ideas that I thought of or planned, always in a completely different way than I would have. It also removes some, but not all, code to support terran and protoss.

The most interesting changes are to the strategy.

strategy changes

The headline change is that, when cpac is out of book, it chooses the next unit to build using a neural network which was learned offline. It replaces Steamhammer’s long list of strategy rules with 2 calls, to extract the features of the game situation and feed them through the network to choose the next unit to make. Well, it makes an exception of the opponent is rushing; then it chooses an emergency unit by a set of emergency rules.

BuildOrder & StrategyBossZerg::freshProductionPlan()
{
	_latestBuildOrder.clearAll();
	updateGameState();
	// We always want at least 9 drones and a spawning pool.
	if (rebuildCriticalLosses())
	{
		return _latestBuildOrder;
	}
	ExtractFeature();
	predictUnit();

	return _latestBuildOrder;
}

According to the readme file, it was trained against the dataset of the paper A Dataset for StarCraft AI & an Example of Armies Clustering. The data comes from replays of expert human games. The network can choose a unit of one of 8 types, and the drone is not included. (Whether to make a drone or something else is the most important zerg macro decision, if you ask me.)

I suspect that the readme may not give the full picture. In games where cpac gets zealot rushed, I notice that it plays sunken defense into lurkers, which works against bots but does not happen in expert human play. I think either the database includes some extra data to cover that case, or else there is an exception that I didn’t notice which applies different rules.

Cpac is able to recover from some setbacks after the opening by applying emergency rules. Other mishaps leave it helpless. For example, in this horrible game versus Overkill, cpac lost most of its drones and never rebuilt beyond 9, because if you have 9 drones it’s “not an emergency.” In general, cpac’s play becomes blander and more predictable as the game continues.

Here’s a funny game against HannesBredberg showing good and bad unit mix decisions.

tactical and micro changes

I don’t think I found all the tactical and micro changes. Here are a few of the things I did find.

Cpac adds a new file MicroFlyers which is responsible for mutalisks and scourge. Among other things, it greatly improves on Steamhammer’s scourge micro and helps mutalisks fly around cannons.

Cpac hardcodes mutalisk targets for specific maps in StateManager. The idea seems to be that if the opponent is protoss and has cannoned up one base, the mutas should fly specific paths to find other bases that may be undefended. It fixes a critical Steamhammer weakness (“Cannons! My way is blocked, I can’t get past them!”) in a quick and dirty way.

Cpac can position sunkens toward the enemy, a longstanding Steamhammer weakness that most forks fix on their own. (I’m waiting for the future building placement planner.)

the openings

Cpac plays fixed openings against 9 opponents. Some of the openings are general purpose, and some (you can tell by the names alone) are custom tailored.

  • UAlbertaBot - OverpoolSpeedDave
  • Steamhammer - 5PoolHard
  • Aiur - 5PoolHard
  • Ximp - 2HatchMutaXimp
  • Skynet - 5PoolHard
  • MegaBot - 5PoolHard
  • Microwave - ZvZ_Overpool9Gas
  • ZZZKBot - 9PoolSpeedExpo
  • McRave - 2HatchMutaMcRave

The ZZZKBot setting backfired when ZZZKBot did not play as expected. The other settings successfully exploited weaknesses. The prepared openings made a major contribution to cpac’s #4 finish. Opponent modeling, I can’t possibly forget, is critical for long tournaments.

Against other opponents, cpac played randomly chosen openings in the Steamhammer style. Cpac trimmed out weaker openings, but otherwise made not too many changes to the random weights and the build orders—except that against terran it chose a 1 hatch lurker opening 90% of the time, instead of occasionally.

Cpac also includes special case strategy code that specifically recognizes UAlbertaBot’s marine rush and zealot rush.

bool StateManager::beingZealotRushed()
{
	auto enemyName = BWAPI::Broodwar->enemy()->getName();
	if (enemyName == "UAlbertaBot")
	{
...

conclusion

Cpac is the highest-placing bot with a fancy machine learning feature. ZZZKBot and PurpleWave have, as far as I know, only simple learning. And... I think it’s a reminder of how hard it is to get machine learning to work well in Starcraft. I’m not convinced that the network adds much to cpac’s skill.

If you ask me, network trained on human games is not appropriate for a bot. When you train a system to copy human play without understanding it, it doesn’t matter what the game is—the system will learn a shallow imitation of human play, not the real thing. It will make a lot of mistakes. AlphaGo trained on human games only as a speedup trick; the real smarts came from the followup training by self-play, which forces the system to understand its own moves in relation to its abilities.

If you also train the network to play only part of the game, only choosing from among 8 combat units and skipping over drones and buildings and research, then its understanding of what it is doing must be paper thin.

Most of cpac’s skill, I think, came from fixing important Steamhammer weaknesses and from manual special case coding and configuration for maps and opponents.

By the way, cpac comes with an MIT license, so its code is legally available to copy. To comply with the license is simple.

Next: Overkill.

CherryPi’s games

I watched some CherryPi games to see how it plays.

versus terran

CherryPi scored 92% against the 4 terrans. How did that happen?

Well, only 2 of the terrans are strong by CherryPi’s standard, and it pre-learned openings against both of them. Against #3 Iron, CherryPi played a mass zergling opening. In games where Iron did not wall, game over. What made it work is that, if Iron did build a wall, CherryPi understood when the wall was open or closed. That’s good cleverness. The zerglings formed a concave so they themselves were safe from the defenders behind the wall and nothing of Iron’s could sneak through, then when the barracks lifted to open the wall, rushed in and rampaged. Against #12 LetaBot, CherryPi played the same zergling opening and won by sheer persistence in attacking.

Both Iron and LetaBot could have won with little risk by playing more cautiously.

Against the weaker terrans, #16 IceBot and #25 HannesBredberg, CherryPi’s learning quickly found winning builds. Against IceBot it settled on a slow-moving mutalisk build with too many hatcheries, powering drones while IceBot delayed moving out. It’s the only case I found where CherryPi tries to win eventually instead of quickly. The games are consistent wins but are not impressive. Against HannesBredberg it was the mass lings again.

the learning sequence

Except against the 5 opponents for which it pre-learned openings, CherryPi opened the first game versus each opponent with 4 pool. It succeeded against refreshingly few of them. If that didn’t work, it tried another opening, and another, and so on. Most of the openings are of the low econ “I’ll just run you over in 6 minutes” kind.

CherryPi apparently tries all its openings without worrying whether they are appropriate to the matchup. It tried a lurker opening in this game versus Microwave. It made no sense to me, but maybe some zerg bots are vulnerable to lurkers.

CherryPi’s favorite unit is the zergling. Occasionally mutalisks or lurkers do something essential, but most of the time, early game or late, it wants to win with lings.

the Steamhammer family

#10 Steamhammer upset #6 CherryPi 72-32. The random openings worked as intended and baffled CherryPi’s learning. CherryPi has openings that could have won the majority of games (it won 7 of the first 10), but it could not find them (it won 3 of the last 10). It could not hear the learning signal over the noise.

Steamhammer forks cpac, Microwave, and Arrakhammer also had plus scores versus CherryPi. I doubt they were all for the same reason.

Next: Cpac.

looking at CherryPi

There’s a ton of code in CherryPi, more than I can read in a day. I tried to pick out key parts to look at.

blackboard architecture

This comment from the file CherryPi/src/upc.h explains an important part of CherryPi’s high-level architecture.

/**
 * Who, where, what action tuple (unit, position, command).
 *
 * UPCTuples are used for module-to-module communication (via the Blackboard).
 * Posting a UPCTuple to the Blackboard is akin to requesting a specific action
 * from another module, and consuming a UPCTuple from the Blackboard implies
 * that the consumer implements this action. The implementation can also consist
 * of refining the UPCTuple so that a more lower-level module can actually
 * execute it.
 *
 * For example, a build order module might post a UPCTuple to create a certain
 * unit type, a builder module might wait until their are sufficient resources
 * before consuming it and then select a worker and a location. The
 * UPCToCommandModule takes care of translating executable UPCTuples (with sharp
 * unit, position and command entries) to actual game commands.
 */

I think it’s an excellent architectural choice, especially for a project carried out by a team rather than an individual. Communication between modules is managed in large part automatically by software rather than manually through the calling conventions of each module. It’s flexible and easy to modify and extend.

relation to Tscmoo

People have speculated that CherryPi may borrow a lot from Tscmoo the bot, since Tscmoo the person is on the team. The speculation even made it into ZZZKBot’s source code, as we saw a couple days ago. I compared 2 slices of code that do similar jobs in CherryPi and the CIG 2017 version of Tscmoo. I looked at the combat simulator in both, and code implementing the 1 hatch lurker opening in both.

Note well: If I had looked at different code, I might have drawn different conclusions. I deliberately selected code with related purposes that might be connected. In some places, CherryPi uses ideas from the old BroodwarBotQ that was written up in Gabriel Synnaeve’s PhD thesis.

1. I think CherryPi directly copied nothing from Tscmoo. I didn’t expect it to. The overall architecture was likely decided before Tscmoo the person joined the team. Besides, an academic usually wants credit to be clear, and a corporation usually wants ownership to be clear. The code in detail looks quite different.

2. In the parts I looked at for this comparison, some structure and ideas in Tscmoo were carried over and seemingly reimplemented in CherryPi, with (I should repeat) great differences in detail. It’s clear that somebody familiar with Tscmoo wrote this CherryPi code. For example, in the combat simulator one has addUnit() and run() in that order, and the other add_unit() and run() in that order. They both refer to “teams”, both count up frames from 0 (I would have counted up from the current frame, some would have counted down to 0), and other shallow similarities.

3. CherryPi, in the parts I compared, seems to be simpler and more cleanly written. In the lurker opening in particular, I think CherryPi encodes the opening a little more abstractly. Sometimes Tscmoo has more features. Tscmoo’s combat simulator simulates splash damage, and CherryPi’s does not.

4. OpenBW is another source of ideas, and it is of course also connected with Tscmoo the person. For example, the FogOfWar class says it is based on OpenBW. It calculates visibility depending on ground height and so on.

the openings

I always want to know, “what openings does it play?” In the directory CherryPi/src/buildorders I see 16 classes that look like they could be build orders. The opening learning files include 15 build orders. The in_use.txt file lists these 8 build orders as active or possibly active:

  • 12hatchhydras
  • zvp10hatch
  • 5pool
  • 2basemutas
  • 3basepoollings
  • 1hatchlurker
  • meanlingrush (9 pool speed)
  • ximptest (it says this one is “unknown status”)

I will watch games and find out what openings it plays in practice. Come back tomorrow!

As a sample of how openings are defined, here is a snip from the file CherryPi/src/buildorders/meanlingrush.cpp showing the basic definition of 9 pool speed:

    buildN(Zerg_Drone, 9);
    buildN(Zerg_Extractor, 1);
    buildN(Zerg_Spawning_Pool, 1);
    if (countPlusProduction(st, Zerg_Hatchery) == 1) {
      build(Zerg_Hatchery, nextBase);
      buildN(Zerg_Drone, 9);
    }

It writes on the blackboard: Make drones until you have 9, extractor and spawning pool, then add a second hatchery at an expansion and rebuild the drones to 9. Simple and concise. Details like spawning the overlord and figuring out exactly when to start the second hatchery are left for other code to fill in (in Steamhammer, you have to specify it explicitly). On the other hand, here is how it says to collect only 100 gas to research zergling speed:

    if (hasOrInProduction(st, Metabolic_Boost) || st.gas >= 100.0) {
      state->board()->post("GathererMinGasGatherers", 0);
      state->board()->post("GathererMaxGasGatherers", 0);
    } else {
      state->board()->post("GathererMinGasGatherers", 3);
      state->board()->post("GathererMaxGasGatherers", 3);
    }

More writing on the blackboard. That’s a complicated test, where in Steamhammer you’d simply specify "go gas until 100". It’s fixable. They could, for example, write goals to the blackboard like “collect 100 gas for zergling speed” and have another module collect only enough gas to meet the goals.

machine learning

I’ll take two cases, online learning during the tournament, and offline learning before the tournament starts, producing data that can be fed to or compiled into the bot.

For online learning, the win rate over time graph for CherryPi shows a rapid increase in win rate from .4 to .7 within the first 10 rounds, then a gradual slight decline to the end of the tournament. It looks as though CherryPi rapidly learned how to play against each opponent, then more or less froze its decisions and allowed slower-learning bots to catch up a tiny bit. (Though swings in score in early rounds can also be due to statistical noise.) The readme file says:

CherryPi is a TorchCraft Zerg bot developed by Facebook AI Research.
It uses bandits to select learn strategies that work against a given
opponent.

“Bandits” refers to the n-arm bandit problem, which is behind most bots with opening learning. Looking at the file CherryPi/src/models/bandit.cpp, I see that that is exactly what CherryPi is doing too. It uses the classic UCB1 algorithm to learn which opening to play against each opponent, just like many other bots.

I looked at the opening learning files, one for each opponent. They are in JSON format and are written by a general-purpose serializer that leaves the data a little hard to interpret by eye. It looks like value2 maps between the 15 opening names and 15 opening index numbers. value3 is 15 zeroes, and value4 and value5 are the learned data for the 15 indexes 0 through 14.

The only offline learning that I found is the same opening learning, performed for certain opponents ahead of time.

  • Iron
  • LetaBot
  • Skynet
  • Xelnaga
  • ZZZKBot

I can’t guess how they came up with that set of 5 opponents to pre-learn openings against. For these opponents, CherryPi relied on its offline learning exclusively; it did not write new learning data for these opponents. It’s such a strange decision that I have to wonder whether it’s a bug. In any case, we saw yesterday that it backfired against ZZZKBot, which did not play as expected: Unable to learn, CherryPi played the same unsuccessful opening every time, and lost over and over. Both ZZZKBot and CherryPi had incorrect prior knowledge about each other, and only ZZZKBot adapted.

conclusion

It is clear to me that CherryPi the project is not far along compared to where they are aiming. There are plenty of TODOs in the code. The big machine learning ideas that (if successful) could make CherryPi superhuman are not there yet; only some foundations are laid. CherryPi is still a scripted bot like others, not a machine learning bot. Even so, with (as I understand it) 8 people on the team, they have done a tremendous amount of work. They implemented ideas—most of which I didn’t write about—that I wish I had time to do myself. If they can maintain the rate of progress, then within a few years individual coders won’t be able to keep up. On the other hand, progress may slow when they get to the hard part. We’ll have to stay tuned!

Next: Games by CherryPi.

ZZZKBot’s games

The AIIDE 2017 win rate over time graph shows #1 ZZZKBot slowly and steadily learning throughout the tournament. It’s easiest to see if you turn off most of the lines of the graph (click on the bots in the legend). #2 PurpleWave shows a different pattern: Without prior knowledge, it starts lower, learns fast at first, then more slowly, and seems to level off before the end of the tournament (though it might be only a temporary plateau).

McRave

McRave upset ZZZKBot 64-46, so watching the games versus McRave lets us see the learning algorithm in action. ZZZKBot does not have a prior strategy versus McRave, possibly because none of its 4 strategies can win reliably against the early cannons. (There are ways to bust the cannons, so it is a limitation of ZZZKBot.)

There are 10 maps in the tournament, and they are played one map per round, so it takes 10 round robins to play all maps once. ZZZKBot played its 4 pool against McRave for the first 10 rounds to see how it did on each map. The answer: It won some and lost some, depending on whether it scouted protoss quickly and whether McRave pulled probes in time to shield the cannons when necessary.

On maps where the 4 pool won, ZZZKBot repeated it when the map came up again. On maps where the 4 pool lost, ZZZKBot switched to its next strategy, the overpool speedlings. The speedlings did not usually do well, because McRave had 3 cannons up in time. ZZZKBot tried to follow up with mutalisks, but McRave scouted that coming and was more than prepared.

I watched the sequence of games on Benzene. The speedlings mostly lost, except for occasional games where zerg managed to kill the scout probe and leave McRave in the dark and unable to react in time. But ZZZKBot kept trying the strategy, only occasionally switching back to 4 pool. I didn’t watch every game, but ZZZKBot’s other 2 strategies didn’t seem to come into play at all.

Iron

Versus Iron, ZZZKBot mostly stuck with its 1 hatch hydralisk strategy, an unusual opening. One odd point is that ZZZKBot researched hydralisk range before speed, which is rare and usually seen only when attacking a protoss wall. As we see in the per-map crosstables, ZZZKBot scored poorly against Iron on 2 player maps and tended to win on 3 and 4 player maps. The difference was that on 2 player maps, Iron was expecting to be rushed and was more willing to build a bunker, which held the hydras.

ZZZKBot sometimes fell back to its sunken defense into mutalisks, but that was less effective. Iron could stop the mutalisks, and its vultures were able to find gaps in the sunken defense.

Iron is the only opponent configured for the hydralisk build order. ZZZKBot doesn’t seem to use it at all, otherwise. I think the build must have been specially developed for Iron.

XIMP

ZZZKBot chose to bust XIMP’s cannons with its speedling build. The zerglings commonly arrived when XIMP had 2 cannons, versus McRave’s 3, and XIMP is not as skilled with probes. It didn’t help that XIMP likes to leave its gateway units in its main “to defend against drops.”

XIMP won only 4 games out of 110. In 3 of its wins, it got its first zealot into the fight in time to save the day. In the fourth, XIMP expanded to another base rather than its natural. ZZZKBot brilliantly scouted the undefended nexus and chose to attack it first, which allowed XIMP’s third cannon time to finish.

CherryPi

CherryPi is an interesting case because ZZZKBot’s “prior knowledge” was guesswork, “Guessing it is like tscmooz.” CherryPi consistently played a sunken defense into mutalisk build against ZZZKBot, with 2 to 4 sunkens. Where did this trend come from? In any case, Tscmoo doesn’t play any such build as far as I’ve seen.

ZZZKBot’s learning kicked in. It tried the 4 pool; no good. It tried the speedlings; no good. It tried its own sunken defense into mutalisks, building only 1 sunken, and that worked perfectly. The sunken was often poorly placed so ZZZKBot tended to lose a few drones, but its mutalisks were out faster.

the Steamhammer forks

ZZZKBot chose its sunken defense into mutalisks versus Steamhammer (with 5 sunkens), Microwave (3 sunkens), Arrakhammer (9 sunkens, because Arrakhammer likes to bust with zerglings), and KillAll (1 sunken), with great success. The sunken count is hand-configured for each opponent. I found it frustrating, because Steamhammer knows in principle how to respond: It makes drones instead of zerglings and goes air. Unfortunately, Steamhammer’s strategy adjustments are sloppy, and it almost always got its own mutalisks too late. It did things like start another hatchery when the spire finished, and then a queen’s nest, and then—well, then it was irretrievable. I knew all along that opponent modeling is crucial for tournaments.

conclusion

Watching games, I was struck that ZZZKBot’s builds are not tight. It doesn’t expand, and in the middle game (when it gets that far) it ends up with more drones than its hatcheries can support. It suffers mineral excess that it can’t spend, and gas shortage because it has only 1 geyser.

Its micro is not tight either. ZZZKBot doesn’t have a combat simulator (well, it would probably be in a subroutine, and as the ancient Greeks declared, only straight lines and circles will do). If the 4 pool leaves cannons alive, then the next 2 followup zerglings will die to the cannons, accomplishing nothing. Then the next 2, etc., until protoss moves out and wins. Followup is minimal; the bot is about winning right away.

ZZZKBot has a lot of clever little skills, but it is missing some big ones. The weaknesses mean that stronger cheese bots are possible. I don’t think the cheese era is over yet.

Next: CherryPi.

looking at ZZZKBot

I read the source of the AIIDE 2017 version of ZZZKBot. It comes with a github repository but at the moment the repo is 2 years out of date.

As a reminder, #1 ZZZKBot was upset by McRave and Tyr which open with cannons to stop most cheeses, and by LetaBot which has extensive work to recognize and respond to different cheeses. ZZZKBot had a plus score against every other opponent, including #2 PurpleWave and #3 Iron. Interestingly, ZZZKBot scored only a little better than even against #26 Slin.

coding style

ZZZKBot is written in a straight-line style, as if subroutines had not been invented. Most of the code is in the onFrame() method. It’s kind of hard to read.

At one point, ZZZKBot checks the name that it is running under using Broodwar->self()->getName(), and if it is not exactly “ZZZKBot” it sets transitionOutOf4PoolFrameCountThresh to 0. The effect depends on the strategy, but it looks as though it usually switches out of its cheese build into late-game play. I have to suppose it is an obfuscation. [Update: Comments suggest that the reason is to avoid lazy copying.] Anyway, be aware that the bot may behave differently depending on the name it is playing under.

strategies and learning

This version of ZZZKBot has 4 strategies.

  • its old standard 4 pool
  • 9 pool speedlings
  • a 1-hatchery hydralisk rush with 11 drones
  • sunken defense into mutalisks

Besides the basic strategy choice, ZZZKBot keeps a few variables that control details of the strategy’s execution.

        bool isSpeedlingPushDeferred;
        bool isEnemyWorkerRusher;
        bool isNumSunkensDecidedAfterScoutEnemyRace;
        int numSunkens;

ZZZKBot also has hardcoded default strategy data for specific opponents, so that against a known bot it can choose a presumed good strategy on the first game. It has values for 17 of the 28 bots in AIIDE 2017, including itself (so 16 of the 27 possible opponents). Considering how thorough the list is, I suspect that Chris Coxe tested against every available bot and manually chose strategies against the ones that ZZZKBot did not defeat on the first attempt. (Against itself it sets all strategy variables to false—I didn’t check what that does.)

  • UAlbertaBot
  • ZZZKBot itself
  • XIMP
  • GarmBot
  • Overkill
  • CherryPi (comment “Guessing it is like tscmooz...”)
  • Ziabot
  • Skynet
  • MegaBot (considered the same as Skynet)
  • Steamhammer
  • Arrakhammer
  • Microwave
  • KillAll
  • ForceBot
  • Juno
  • Iron
  • HannesBredberg

After each game, ZZZKBot may update its strategy data and save the result to a file. The algorithm is long and includes random choices, and I didn’t try to puzzle it out. There are special provisions for playing against random; it checks when the opponent’s race was discovered to see whether the stored info will be useful for the current game. It also, oddly, saves information about the processor it is running on.

scouting a zerg opponent

When your opponent is zerg, a couple tricks can make scouting easier. One is that if you spot the enemy’s first overlord, you may be able to infer the location of the enemy base. I added this knowledge to Steamhammer for the next version, and it frequently helps. Another is that you do not have to scout the enemy hatchery itself. The base is found when you see the creep, and a scouting unit can turn aside as soon as it sees bare ground where creep would be if the base were there. I didn’t add this knowledge to Steamhammer (yet), because it’s tricky. For one thing, I’m not sure of the exact rules for creep spreading; the way unbuildable ground blocks creep is not obvious (commonly creep extends beyond the geyser on both sides but not around it, leaving a notch). For another, a map could have neutral zerg buildings that spread static creep, and BWAPI won’t tell you where the static creep is; an example is Colosseum (though on that map the static creep doesn’t affect scouting). The complications were enough to keep the idea off the top of my priority list.

ZZZKBot implements both of these tricks. How does ZZZKBot know where the creep spreads to for each base location? Simple: It hardcodes the data for each starting position of all 10 maps!

ZZZKBot also tries to guess the location of the enemy base from other enemy units it sees. As a cheeser, ZZZKBot scouts early, so it has a good chance of guessing right.

a comment from the code

            // TODO: support making more than one building of a particular type.

Waste no time on the unimportant!

conclusion

ZZZKBot is very specific and narrowly coded. Its sole purpose is to defeat other bots, especially opponent bots that it knows playing on maps that it knows. Everything possible is hardcoded, above all prior knowledge about opponents and maps. ZZZKBot teaches strict lessons to its opponents, but there are not many lessons in the bot itself. It’s about the cheesiest, most exploitative bot possible.

If ZZZKBot had stuck with its classic 4 pool, I’m convinced that it would have finished in 4th place or worse rather than first. Too many of its opponents in this tournament were ready for the 4 pool (I know Steamhammer was). Next year, I expect that top bots will be prepared for all 4 of ZZZKBot’s strategies this year (it won’t be difficult), and ZZZKBot will have to go to even greater lengths if it is to finish strongly. I see it as a sign of progress: Even the most exploitative bot is forced to play multiple strategies and to rely on machine learning—it is forced to use smart methods to play better. The space for cheap exploits is gradually narrowing.

Next: Looking at how ZZZKBot played against different opponents.

AIIDE 2017 crosstables per map

The AIIDE 2017 official results include a table of how each bot performed on each map. Some bots performed evenly across maps, and some liked or disliked particular maps. The left “overall” column of each table corresponds to one column in the official bot-map table; the rest of the table breaks it down by opponent. With 10 maps and 110 rounds, each cell ideally represents 11 games, so the tables are noisy. Some games are missing, so some cells represent fewer games.

First, the complete crosstable for reference. Its contents are the same as the official crosstable, but shown as percentages rather than as wins/games.

complete

overallZZZKPurpIroncpacMicrCherMcRaArraTyrSteaAILiLetaXimpUAlbAiurIceBSkynKillMegaXelnOverJunoGarmMyscHannSlinForcZiab
ZZZKBot83.11%67%60%66%87%89%42%85%37%96%83%45%96%99%86%97%96%96%92%100%100%99%100%72%100%52%100%100%
PurpleWave82.35%33%65%93%88%78%75%95%81%86%55%61%91%92%49%93%94%56%91%90%98%75%100%94%98%95%100%99%
Iron81.52%40%35%67%68%7%42%94%96%87%100%63%99%84%98%100%100%61%93%85%98%99%97%98%100%99%97%91%
cpac71.01%34%7%33%95%55%99%36%5%70%85%77%99%99%58%97%67%83%82%64%83%80%100%69%85%83%74%100%
Microwave70.86%13%12%32%5%72%28%67%49%55%47%84%58%83%92%92%85%99%91%83%96%77%100%95%100%99%98%100%
CherryPi69.08%11%22%93%45%28%54%29%89%35%42%89%50%53%92%92%50%66%67%98%93%100%99%79%95%99%97%100%
McRave67.07%58%25%58%1%72%46%83%63%77%70%51%67%55%36%76%64%75%67%77%50%85%96%100%96%67%95%98%
Arrakhammer65.95%15%5%6%64%33%71%17%93%27%68%60%75%59%62%94%68%99%64%47%96%100%100%64%98%96%99%100%
Tyr65.91%63%19%4%95%51%11%37%7%84%60%55%96%65%58%65%81%90%80%76%89%95%95%85%86%64%95%75%
Steamhammer64.14%4%14%13%30%45%65%23%73%16%89%49%86%80%35%89%54%93%55%72%95%99%100%85%76%100%92%100%
AILien58.29%17%45%0%15%53%58%30%32%40%11%13%40%39%55%82%84%87%74%87%76%60%99%92%95%97%94%99%
LetaBot56.92%55%39%37%23%16%11%49%40%45%51%87%68%45%57%5%77%87%72%44%78%56%80%98%47%98%85%87%
Ximp54.19%4%9%1%1%42%50%33%25%4%14%60%32%51%88%10%99%65%86%75%59%86%99%86%93%100%95%99%
UAlbertaBot53.40%1%8%16%1%17%47%45%41%35%20%61%55%49%75%74%67%54%65%100%58%91%59%61%87%65%89%100%
Aiur50.46%14%51%2%42%8%8%64%38%42%65%45%43%12%25%81%89%62%33%56%89%22%74%70%92%75%86%75%
IceBot45.62%3%7%0%3%8%8%24%6%35%11%18%95%90%26%19%62%75%53%35%62%85%68%87%97%98%67%88%
Skynet43.78%4%6%0%33%15%50%36%32%19%46%16%23%1%33%11%38%28%17%67%92%70%99%55%100%96%95%96%
KillAll43.04%4%44%39%17%1%34%25%1%10%7%13%13%35%46%38%25%72%77%89%45%100%89%64%78%44%61%94%
MegaBot42.83%8%9%7%18%9%33%33%36%20%45%26%28%14%35%67%47%83%23%37%75%44%75%66%92%71%86%77%
Xelnaga37.10%0%10%15%36%17%2%23%53%24%28%13%56%25%0%44%65%33%11%63%87%45%1%75%80%75%80%45%
Overkill32.69%0%2%2%17%4%7%50%4%11%5%24%22%41%42%11%38%8%55%25%13%75%67%66%36%87%83%87%
Juno29.57%1%25%1%20%23%0%15%0%5%1%40%44%14%9%78%15%30%0%56%55%25%4%42%95%68%50%85%
GarmBot27.09%0%0%3%0%0%1%4%0%5%0%1%20%1%41%26%32%1%11%25%99%33%96%79%6%97%77%73%
Myscbot25.94%28%6%2%31%5%21%0%36%15%15%8%2%14%39%30%13%45%36%34%25%34%58%21%61%9%68%44%
HannesBredberg21.26%0%2%0%15%0%5%4%2%14%24%5%53%7%13%8%3%0%22%8%20%64%5%94%39%75%66%29%
Sling21.09%48%5%1%17%1%1%33%4%36%0%3%2%0%35%25%2%4%56%29%25%13%32%3%91%25%71%9%
ForceBot17.97%0%0%3%26%2%3%5%1%5%8%6%15%5%11%14%33%5%39%14%20%17%50%23%32%34%29%85%
Ziabot17.21%0%1%9%0%0%0%2%0%25%0%1%13%1%0%25%12%4%6%23%55%13%15%27%56%71%91%15%

(2) Benzene

overallZZZKPurpIroncpacMicrCherMcRaArraTyrSteaAILiLetaXimpUAlbAiurIceBSkynKillMegaXelnOverJunoGarmMyscHannSlinForcZiab
ZZZKBot74.07%36%9%55%91%82%27%82%9%100%91%0%100%100%91%100%91%100%91%100%100%100%100%18%100%27%100%100%
PurpleWave84.85%64%64%100%100%73%82%91%82%100%82%73%82%100%18%91%73%73%100%100%100%82%100%100%91%82%100%91%
Iron85.86%91%36%82%82%9%45%100%100%100%100%36%91%100%100%100%100%100%82%73%100%100%100%100%100%100%100%91%
cpac71.28%45%0%18%91%82%100%36%0%55%100%73%100%100%45%100%82%91%90%45%64%91%100%27%100%91%100%100%
Microwave72.30%9%0%18%9%82%18%82%55%27%82%82%64%82%73%91%100%100%100%91%100%100%100%91%100%100%100%100%
CherryPi66.67%18%27%91%18%18%45%18%82%36%36%91%64%64%100%73%73%73%64%100%91%100%91%55%100%91%82%100%
McRave72.05%73%18%55%0%82%55%91%55%82%91%55%82%73%36%64%82%100%82%100%36%100%100%100%100%36%100%100%
Arrakhammer63.85%18%9%0%64%18%82%9%100%36%91%73%64%36%18%100%73%100%70%64%100%100%100%18%91%91%100%100%
Tyr66.67%91%18%0%100%45%18%45%0%100%64%36%100%73%27%55%91%100%73%73%100%100%91%100%73%55%100%73%
Steamhammer62.63%0%0%0%45%73%64%18%64%0%100%45%91%82%36%73%45%82%45%64%100%100%100%64%100%100%100%100%
AILien48.48%9%18%0%0%18%64%9%9%36%0%0%18%45%18%73%91%55%82%82%73%45%100%100%82%91%100%91%
LetaBot60.68%100%27%64%27%18%9%45%27%64%55%100%27%27%55%0%91%82%100%55%100%18%100%100%82%100%82%91%
Ximp46.60%0%18%9%0%36%36%18%36%0%9%82%73%55%0%9%100%73%88%55%36%0%100%73%64%100%100%100%
UAlbertaBot53.54%0%0%0%0%18%36%27%64%27%18%55%73%45%73%73%55%82%73%100%55%100%73%55%91%73%82%100%
Aiur60.27%9%82%0%55%27%0%64%82%73%64%82%45%100%27%91%91%55%55%82%91%18%73%36%91%91%82%64%
IceBot49.32%0%9%0%0%9%27%36%0%45%27%27%100%91%27%9%82%82%80%27%55%100%73%82%82%100%91%73%
Skynet38.31%9%27%0%18%0%27%18%27%9%55%9%9%0%45%9%18%0%0%82%100%91%91%9%100%100%91%82%
KillAll35.69%0%27%0%9%0%27%0%0%0%18%45%18%27%18%45%18%100%82%100%36%100%73%0%73%18%55%73%
MegaBot35.02%9%0%18%10%0%36%18%30%27%55%18%0%12%27%45%20%100%18%11%45%45%75%18%100%55%88%80%
Xelnaga31.19%0%0%27%55%9%0%0%36%27%36%18%45%45%0%18%73%18%0%89%82%45%0%55%73%36%64%0%
Overkill33.67%0%0%0%36%0%9%64%0%0%0%27%0%64%45%9%45%0%64%55%18%82%73%64%0%91%100%64%
Juno29.63%0%18%0%9%0%0%0%0%0%0%55%82%100%0%82%0%9%0%55%55%18%0%0%100%73%64%82%
GarmBot26.53%0%0%0%0%0%9%0%0%9%0%0%0%0%27%27%27%9%27%25%100%27%100%64%0%100%100%64%
Myscbot46.46%82%0%0%73%9%45%0%82%0%36%0%0%27%45%64%18%91%100%82%45%36%100%36%73%9%100%100%
HannesBredberg24.24%0%9%0%0%0%0%0%9%27%0%18%18%36%9%9%18%0%27%0%27%100%0%100%27%100%100%18%
Sling25.25%73%18%0%9%0%9%64%9%45%0%9%0%0%27%9%0%0%82%45%64%9%27%0%91%0%91%0%
ForceBot8.50%0%0%0%0%0%18%0%0%0%0%0%18%0%18%18%9%9%45%12%36%0%36%0%0%0%9%0%
Ziabot24.66%0%9%9%0%0%0%0%0%27%0%9%9%0%0%36%27%18%27%20%100%36%18%36%0%82%100%100%

(2) Destination

overallZZZKPurpIroncpacMicrCherMcRaArraTyrSteaAILiLetaXimpUAlbAiurIceBSkynKillMegaXelnOverJunoGarmMyscHannSlinForcZiab
ZZZKBot82.83%36%9%73%100%82%27%91%55%100%91%27%100%100%100%100%100%100%82%100%100%100%100%91%100%73%100%100%
PurpleWave78.38%64%64%91%55%73%91%91%91%73%27%36%91%73%36%100%100%91%80%91%82%55%100%91%100%73%100%100%
Iron84.51%91%36%55%64%0%27%100%91%100%100%55%100%100%100%100%100%100%100%82%100%100%100%100%100%100%100%82%
cpac73.90%27%9%45%100%82%100%55%18%91%82%100%100%100%82%91%27%82%89%82%64%82%100%18%100%100%73%100%
Microwave74.32%0%45%36%0%100%73%73%82%64%82%100%27%73%100%82%73%100%100%55%91%91%100%82%100%91%91%100%
CherryPi62.96%18%27%100%18%0%55%0%82%55%9%73%55%45%91%100%36%64%64%100%82%100%100%36%91%100%100%100%
McRave62.63%73%9%73%0%27%45%73%91%73%64%55%45%64%9%64%73%45%64%73%27%100%100%100%100%45%100%100%
Arrakhammer63.64%9%9%0%45%27%100%27%100%27%73%18%73%45%64%82%82%100%100%45%73%100%100%36%100%91%91%100%
Tyr52.36%45%9%9%82%18%18%9%0%36%45%27%64%55%45%64%73%64%70%73%82%91%91%100%100%27%45%73%
Steamhammer66.33%0%27%0%9%36%45%27%73%64%100%55%100%73%36%91%55%100%64%91%100%91%100%73%91%100%91%100%
AILien60.27%9%73%0%18%18%91%36%27%55%0%18%55%27%82%82%82%91%64%82%64%91%100%82%100%100%82%100%
LetaBot65.31%73%64%45%0%0%27%45%82%73%45%82%64%64%82%0%100%91%91%45%100%100%91%100%18%100%91%100%
Ximp59.26%0%9%0%0%73%45%55%27%36%0%45%36%73%100%18%100%73%100%91%27%100%100%100%100%100%91%100%
UAlbertaBot53.54%0%27%0%0%27%55%36%55%45%27%73%36%27%64%64%64%36%64%100%45%91%82%64%91%82%91%100%
Aiur41.16%0%64%0%18%0%9%91%36%55%64%18%18%0%36%73%91%64%62%100%55%9%18%27%82%0%91%36%
IceBot52.88%0%0%0%9%18%0%36%18%36%9%18%100%82%36%27%91%73%73%73%67%100%100%100%100%100%73%91%
Skynet39.39%0%0%0%73%27%64%27%18%27%45%18%0%0%36%9%9%36%18%73%82%45%100%9%100%73%82%91%
KillAll41.55%0%9%0%18%0%36%55%0%36%0%9%9%27%64%36%27%64%90%100%45%100%82%45%91%27%64%91%
MegaBot38.03%18%20%0%11%0%36%36%0%30%36%36%9%0%36%38%27%82%10%18%82%60%70%55%70%55%100%90%
Xelnaga34.80%0%9%18%18%45%0%27%55%27%9%18%55%9%0%0%27%27%0%82%100%91%0%64%100%64%82%18%
Overkill36.90%0%18%0%36%9%18%73%27%18%0%36%0%73%55%45%33%18%55%18%0%64%50%45%36%82%82%91%
Juno23.31%0%45%0%18%9%0%0%0%9%9%9%0%0%9%91%0%55%0%40%9%36%0%27%100%55%9%100%
GarmBot24.41%0%0%0%0%0%0%0%0%9%0%0%9%0%18%82%0%0%18%30%100%50%100%9%27%100%91%18%
Myscbot41.41%9%9%0%82%18%64%0%64%0%27%18%0%0%36%73%0%91%55%45%36%55%73%91%73%0%100%100%
HannesBredberg18.24%0%0%0%0%0%9%0%0%0%9%0%82%0%9%18%0%0%9%30%0%64%0%73%27%64%64%36%
Sling29.29%27%27%0%0%9%0%55%9%73%0%0%0%0%18%100%0%27%73%45%36%18%45%0%100%36%82%9%
ForceBot19.87%0%0%0%27%9%0%0%9%55%9%18%9%9%9%9%27%18%36%0%18%18%91%9%0%36%18%100%
Ziabot17.57%0%0%18%0%0%0%0%0%27%0%0%0%0%0%64%9%9%9%10%82%9%0%82%0%64%91%0%

(2) Heartbreak Ridge

overallZZZKPurpIroncpacMicrCherMcRaArraTyrSteaAILiLetaXimpUAlbAiurIceBSkynKillMegaXelnOverJunoGarmMyscHannSlinForcZiab
ZZZKBot81.82%91%36%64%82%91%9%91%9%100%64%36%100%100%100%100%100%100%100%100%100%100%100%91%100%45%100%100%
PurpleWave85.52%9%45%100%91%91%82%91%91%100%64%73%100%100%55%91%91%82%82%91%100%82%100%100%100%100%100%100%
Iron84.18%64%55%64%55%18%36%100%100%82%100%36%100%100%100%100%100%100%91%91%100%100%100%100%100%100%100%82%
cpac72.73%36%0%36%91%36%100%18%9%73%73%73%100%100%82%100%73%82%73%73%91%91%100%91%100%73%91%100%
Microwave71.62%18%9%45%9%82%36%82%55%55%36%73%55%82%91%100%73%100%90%64%100%82%100%100%100%100%100%100%
CherryPi70.71%9%9%82%64%18%64%36%91%18%55%100%27%55%100%91%55%73%82%100%100%100%100%91%91%100%100%100%
McRave66.67%91%18%64%0%64%36%73%55%100%91%55%73%0%9%91%64%55%73%45%45%100%100%100%100%100%100%100%
Arrakhammer68.01%9%9%0%82%18%64%27%100%9%64%91%82%82%55%82%73%100%73%64%100%100%100%73%100%82%100%100%
Tyr68.92%91%9%0%91%45%9%45%0%91%64%27%100%64%0%91%82%100%100%82%91%100%100%91%100%100%100%91%
Steamhammer64.65%0%0%18%27%45%82%0%91%9%91%45%64%91%27%82%73%91%55%73%100%100%100%100%82%100%100%100%
AILien56.90%36%36%0%27%64%45%9%36%36%9%9%9%27%64%64%100%82%82%64%91%55%100%100%91%100%100%100%
LetaBot55.44%64%27%64%27%27%0%45%9%73%55%91%82%18%18%9%100%64%50%18%91%18%82%100%64%100%100%100%
Ximp60.88%0%0%0%0%45%73%27%18%0%36%91%18%91%100%36%100%100%89%91%36%91%100%100%100%100%100%100%
UAlbertaBot54.05%0%0%0%0%18%45%100%18%36%9%73%82%9%64%64%82%55%70%100%64%100%73%73%91%45%91%100%
Aiur60.94%0%45%0%18%9%0%91%45%100%73%36%82%0%36%91%100%91%82%73%100%9%100%91%100%82%100%91%
IceBot45.73%0%9%0%0%0%9%9%18%9%18%36%91%64%36%9%91%91%43%0%55%91%100%100%100%100%64%91%
Skynet43.00%0%9%0%27%27%45%36%27%18%27%0%0%0%18%0%9%36%43%64%100%91%100%91%100%91%100%100%
KillAll39.53%0%18%0%18%0%27%45%0%0%9%18%36%0%45%9%9%64%80%100%55%100%91%91%64%36%55%100%
MegaBot34.83%0%18%9%27%10%18%27%27%0%45%18%50%11%30%18%57%57%20%43%91%40%75%78%73%90%50%0%
Xelnaga38.91%0%9%9%27%36%0%55%36%18%27%36%82%9%0%27%100%36%0%57%100%36%0%82%91%100%45%36%
Overkill29.39%0%0%0%9%0%0%55%0%9%0%9%9%64%36%0%45%0%45%9%0%82%91%55%9%91%80%100%
Juno29.05%0%18%0%9%18%0%0%0%0%0%45%82%9%0%91%9%9%0%60%64%18%0%36%100%73%45%100%
GarmBot23.81%0%0%0%0%0%0%0%0%0%0%0%18%0%27%0%0%0%9%25%100%9%100%100%0%82%91%82%
Myscbot16.27%9%0%0%9%0%9%0%27%9%0%0%0%0%27%9%0%9%9%22%18%45%64%0%36%0%64%73%
HannesBredberg21.55%0%0%0%0%0%9%0%0%0%18%9%36%0%9%0%0%0%36%27%9%91%0%100%64%64%55%55%
Sling18.24%55%0%0%27%0%0%0%18%0%0%0%0%0%55%18%0%9%64%10%0%9%27%18%100%36%45%0%
ForceBot19.11%0%0%0%9%0%0%0%0%0%0%0%0%0%9%0%36%0%45%50%55%20%55%9%36%45%55%100%
Ziabot14.81%0%0%18%0%0%0%0%0%9%0%0%0%0%0%9%9%0%0%100%64%0%0%18%27%45%100%0%

(3) Aztec

overallZZZKPurpIroncpacMicrCherMcRaArraTyrSteaAILiLetaXimpUAlbAiurIceBSkynKillMegaXelnOverJunoGarmMyscHannSlinForcZiab
ZZZKBot84.12%91%91%55%100%91%9%91%0%100%91%73%91%91%82%100%100%100%90%100%100%100%100%91%100%36%100%100%
PurpleWave82.15%9%55%91%91%82%73%100%73%100%73%73%91%82%55%100%91%45%91%73%100%82%100%91%100%100%100%100%
Iron77.36%9%45%73%55%0%27%82%100%100%100%27%100%82%91%100%100%55%90%82%100%100%100%91%100%100%100%82%
cpac73.06%45%9%27%100%64%100%45%0%55%82%82%100%100%73%100%73%91%82%55%82%82%100%82%73%91%82%100%
Microwave70.03%0%9%45%0%91%27%73%27%45%27%82%27%91%91%100%91%91%100%82%100%91%100%100%100%100%100%100%
CherryPi70.27%9%18%100%36%9%36%36%91%64%45%91%64%45%91%90%45%55%91%100%100%100%100%91%91%100%100%100%
McRave70.51%91%27%73%0%73%64%91%73%91%91%55%55%64%36%73%45%73%89%82%45%91%82%100%100%45%100%100%
Arrakhammer65.54%9%0%18%55%27%64%9%100%0%55%64%82%64%73%100%64%100%70%36%100%100%100%91%91%100%100%100%
Tyr66.55%100%27%0%100%73%9%27%0%91%45%64%100%64%73%55%91%100%80%100%91%91%91%64%73%45%100%45%
Steamhammer65.08%0%0%0%45%55%36%9%100%9%91%45%100%82%27%100%73%100%56%82%82%100%100%91%73%100%100%100%
AILien60.34%9%27%0%18%73%55%9%45%55%9%0%64%36%36%73%91%100%67%100%91%82%91%100%100%100%100%100%
LetaBot57.43%27%27%73%18%18%9%45%36%36%55%100%82%45%55%0%100%91%70%9%91%73%73%100%64%91%64%100%
Ximp51.85%9%9%0%0%73%36%45%18%0%0%36%18%27%91%0%100%73%91%64%55%100%100%73%91%100%91%100%
UAlbertaBot54.88%9%18%18%0%9%55%36%36%36%18%64%55%73%91%64%64%82%55%100%73%91%64%36%91%55%91%100%
Aiur47.47%18%45%9%27%9%9%64%27%27%73%64%45%9%9%55%91%27%18%64%91%27%73%82%100%82%64%73%
IceBot43.05%0%0%0%0%0%10%27%0%45%0%27%100%100%36%45%91%64%40%45%27%100%9%73%100%100%18%100%
Skynet42.03%0%9%0%27%9%55%55%36%9%27%9%0%0%36%9%9%0%0%91%91%82%100%82%100%100%91%100%
KillAll42.76%0%55%45%9%9%45%27%0%0%0%0%9%27%18%73%36%100%82%45%36%100%82%64%100%45%55%91%
MegaBot44.48%10%9%10%18%0%9%11%30%20%44%33%30%9%45%82%60%100%18%64%80%55%91%64%100%73%82%55%
Xelnaga38.05%0%27%18%45%18%0%18%64%0%18%0%91%36%0%36%55%9%55%36%100%27%0%91%82%91%73%36%
Overkill33.78%0%0%0%18%0%0%55%0%9%18%9%9%45%27%9%73%9%64%20%0%91%82%73%36%91%82%91%
Juno25.93%0%18%0%18%9%0%9%0%9%0%18%27%0%9%73%0%18%0%45%73%9%9%73%100%36%45%100%
GarmBot31.65%0%0%0%0%0%0%18%0%9%0%9%27%0%36%27%91%0%18%9%100%18%91%100%18%100%91%91%
Myscbot20.88%9%9%9%18%0%9%0%9%36%9%0%0%27%64%18%27%18%36%36%9%27%27%0%73%9%55%27%
HannesBredberg17.23%0%0%0%27%0%9%0%9%27%27%0%36%9%9%0%0%0%0%0%18%64%0%82%27%73%27%18%
Sling22.90%64%0%0%9%0%0%55%0%55%0%0%9%0%45%18%0%0%55%27%9%9%64%0%91%27%82%0%
ForceBot22.22%0%0%0%18%0%0%0%0%0%0%0%36%9%9%36%82%9%45%18%27%18%55%9%45%73%18%91%
Ziabot18.52%0%0%18%0%0%0%0%0%55%0%0%0%0%0%27%0%0%9%45%64%9%0%9%73%82%100%9%

(3) Tau Cross

overallZZZKPurpIroncpacMicrCherMcRaArraTyrSteaAILiLetaXimpUAlbAiurIceBSkynKillMegaXelnOverJunoGarmMyscHannSlinForcZiab
ZZZKBot83.84%82%91%73%82%91%0%82%73%82%91%9%100%100%73%100%91%82%91%100%100%100%100%73%100%100%100%100%
PurpleWave80.07%18%64%73%82%73%64%100%36%73%82%27%91%91%91%82%100%45%90%100%100%91%100%91%100%100%100%100%
Iron83.16%9%36%100%64%18%45%100%100%100%100%91%100%73%100%100%100%36%91%100%100%100%100%100%100%100%82%100%
cpac67.00%27%27%0%91%82%100%36%0%73%82%64%91%100%18%100%27%73%73%45%91%82%100%91%73%82%82%100%
Microwave70.03%18%18%36%9%82%9%36%45%82%55%82%55%82%91%91%82%100%82%82%100%73%100%82%100%100%100%100%
CherryPi67.34%9%27%82%18%18%55%36%100%9%55%100%45%45%91%91%27%73%64%100%100%100%100%82%91%100%100%100%
McRave71.62%100%36%55%0%91%45%100%45%91%55%36%36%82%55%73%55%91%80%73%55%91%100%100%100%91%100%100%
Arrakhammer64.86%18%0%0%64%64%64%0%100%55%82%64%55%64%45%100%91%100%30%27%100%100%100%27%100%100%100%100%
Tyr69.59%27%64%0%100%55%0%55%0%91%55%55%100%55%91%55%82%64%80%100%91%91%100%100%100%82%100%91%
Steamhammer62.16%18%27%0%27%18%91%9%45%9%100%36%82%55%36%82%45%82%60%73%100%100%100%100%91%100%91%100%
AILien54.21%9%18%0%18%45%45%45%18%45%0%0%27%45%27%91%82%82%73%91%91%36%100%100%91%91%91%100%
LetaBot62.29%91%73%9%36%18%0%64%36%45%64%100%73%55%55%9%100%91%45%64%91%64%91%100%27%100%82%100%
Ximp57.77%0%9%0%9%45%55%64%45%0%18%73%27%36%100%18%100%64%80%73%55%91%100%100%100%100%100%100%
UAlbertaBot57.58%0%9%27%0%18%55%18%36%45%45%55%45%64%100%55%55%82%82%100%73%100%55%91%82%73%91%100%
Aiur51.18%27%9%0%82%9%9%45%55%9%64%73%45%0%0%73%91%36%36%73%91%36%82%91%91%100%73%82%
IceBot46.28%0%18%0%0%9%9%27%0%45%18%9%91%82%45%27%100%73%10%36%91%73%64%91%100%100%27%100%
Skynet45.79%9%0%0%73%18%73%45%9%18%55%18%0%0%45%9%0%82%9%55%100%91%100%45%100%100%91%91%
KillAll45.79%18%55%64%27%0%27%9%0%36%18%18%9%36%18%64%27%18%82%73%73%100%100%64%55%64%82%100%
MegaBot49.30%9%10%9%27%18%36%20%70%20%40%27%55%20%18%64%90%91%18%36%64%67%73%90%100%100%64%100%
Xelnaga37.71%0%0%0%55%18%0%27%73%0%27%9%36%27%0%27%64%45%27%64%82%73%0%64%73%91%64%73%
Overkill27.95%0%0%0%9%0%0%45%0%9%0%9%9%45%27%9%9%0%27%36%18%82%55%64%55%73%82%91%
Juno25.42%0%9%0%18%27%0%9%0%9%0%64%36%9%0%64%27%9%0%33%27%18%9%45%100%82%0%91%
GarmBot26.60%0%0%0%0%0%0%0%0%0%0%0%9%0%45%18%36%0%0%27%100%45%91%91%9%100%64%82%
Myscbot20.27%27%9%0%9%18%18%0%73%0%0%0%0%0%9%9%9%55%36%10%36%36%55%9%36%55%18%18%
HannesBredberg21.21%0%0%0%27%0%9%0%0%0%9%9%73%0%18%9%0%0%45%0%27%45%0%91%64%64%27%55%
Sling14.19%0%0%0%18%0%0%9%0%18%0%9%0%0%27%0%0%0%36%0%9%27%18%0%45%36%91%36%
ForceBot25.93%0%0%18%18%0%0%0%0%0%9%9%18%0%9%27%73%9%18%36%36%18%100%36%82%73%9%100%
Ziabot10.77%0%0%0%0%0%0%0%0%9%0%0%0%0%0%18%0%9%0%0%27%9%9%18%82%45%64%0%

(4) Andromeda

overallZZZKPurpIroncpacMicrCherMcRaArraTyrSteaAILiLetaXimpUAlbAiurIceBSkynKillMegaXelnOverJunoGarmMyscHannSlinForcZiab
ZZZKBot81.82%55%100%45%82%91%91%91%18%91%73%9%100%100%82%82%91%100%91%100%100%91%100%73%100%55%100%100%
PurpleWave83.39%45%82%91%91%64%91%100%100%73%27%64%91%91%55%91%100%55%89%91%100%73%100%100%91%100%100%100%
Iron74.41%0%18%36%82%9%36%82%91%55%100%64%100%73%100%100%100%27%100%91%100%100%73%100%100%100%100%73%
cpac74.32%55%9%64%100%18%100%18%9%73%100%73%100%100%64%100%73%100%80%91%91%64%100%64%91%82%91%100%
Microwave70.03%18%9%18%0%64%18%82%45%55%45%82%73%64%100%100%64%100%91%91%100%73%100%100%100%100%100%100%
CherryPi73.40%9%36%91%82%36%73%36%100%36%73%91%18%64%91%100%91%45%45%100%82%100%100%82%100%100%100%100%
McRave64.86%9%9%64%0%82%27%91%45%82%45%9%73%45%45%73%64%91%60%82%82%82%100%100%100%91%100%100%
Arrakhammer67.91%9%0%18%82%18%64%9%91%18%73%45%73%55%91%100%55%100%90%64%100%100%100%82%100%100%100%100%
Tyr62.96%82%0%9%91%55%0%55%9%82%73%73%100%45%73%82%64%100%82%73%82%82%91%64%55%9%100%73%
Steamhammer69.02%9%27%45%27%45%64%18%82%18%64%27%73%91%64%100%55%100%73%100%91%100%100%91%100%100%100%100%
AILien63.30%27%73%0%0%55%27%55%27%27%36%18%45%55%100%100%64%91%91%100%73%73%100%82%100%100%91%100%
LetaBot63.64%91%36%36%27%18%9%91%55%27%73%82%91%64%45%0%82%100%100%91%82%45%73%100%45%100%91%64%
Ximp54.88%0%9%0%0%27%82%27%27%0%27%55%9%45%100%0%100%64%100%91%73%82%91%91%91%100%100%91%
UAlbertaBot53.20%0%9%27%0%36%36%55%45%55%9%45%36%55%73%82%73%73%45%100%64%91%27%64%82%55%100%100%
Aiur45.45%18%45%0%36%0%9%55%9%27%36%0%55%0%27%100%91%73%18%64%82%36%64%73%82%73%82%73%
IceBot46.28%18%9%0%0%0%0%27%0%18%0%0%100%100%18%0%55%91%90%73%73%64%82%91%100%91%82%73%
Skynet47.14%9%0%0%27%36%9%36%45%36%45%36%18%0%27%9%45%36%18%91%91%73%100%82%100%100%100%100%
KillAll43.05%0%45%73%0%0%55%9%0%0%0%9%0%36%27%27%9%64%100%100%36%100%82%64%100%55%82%100%
MegaBot36.01%9%11%0%20%9%55%40%10%18%27%9%0%0%55%82%10%82%0%36%64%20%64%73%90%9%90%82%
Xelnaga23.57%0%9%9%9%9%0%18%36%27%0%0%9%9%0%36%27%9%0%64%64%36%0%73%55%18%91%27%
Overkill33.67%0%0%0%9%0%18%18%0%18%9%27%18%27%36%18%27%9%64%36%36%82%73%100%27%100%64%91%
Juno33.78%9%27%0%36%27%0%18%0%18%0%27%55%18%9%64%36%27%0%80%64%18%0%45%100%82%64%91%
GarmBot29.97%0%0%27%0%0%0%0%0%9%0%0%27%9%73%36%18%0%18%36%100%27%100%73%0%100%82%73%
Myscbot22.22%27%0%0%36%0%18%0%18%36%9%18%0%9%36%27%9%18%36%27%27%0%55%27%55%9%82%18%
HannesBredberg22.64%0%9%0%9%0%0%0%0%45%0%0%55%9%18%18%0%0%0%10%45%73%0%100%45%55%91%27%
Sling25.93%45%0%0%18%0%0%9%0%91%0%0%0%0%45%27%9%0%45%91%82%0%18%0%91%45%73%9%
ForceBot12.84%0%0%0%9%0%0%0%0%0%0%9%9%0%0%18%18%0%18%10%9%36%36%18%18%9%27%100%
Ziabot19.87%0%0%27%0%0%0%0%0%27%0%0%36%9%0%27%27%0%0%18%73%9%9%27%82%73%91%0%

(4) Circuit Breaker

overallZZZKPurpIroncpacMicrCherMcRaArraTyrSteaAILiLetaXimpUAlbAiurIceBSkynKillMegaXelnOverJunoGarmMyscHannSlinForcZiab
ZZZKBot76.35%36%55%64%73%91%36%64%27%100%73%18%91%100%64%91%100%82%80%100%100%100%100%73%100%45%100%100%
PurpleWave83.45%64%64%91%100%73%100%82%91%82%73%64%91%100%18%100%100%18%90%91%100%73%100%91%100%100%100%100%
Iron80.13%45%36%9%27%9%45%100%91%73%100%64%100%91%100%100%100%100%100%82%100%100%100%91%100%100%100%100%
cpac72.64%36%9%91%100%36%100%36%0%64%91%91%100%91%45%100%82%91%90%55%100%91%100%82%82%64%36%100%
Microwave68.35%27%0%73%0%36%18%36%36%36%36%82%82%82%91%82%100%100%91%82%100%55%100%100%100%100%100%100%
CherryPi70.37%9%27%91%64%64%55%36%91%18%36%82%36%45%91%100%36%91%55%100%91%100%100%91%91%100%100%100%
McRave66.67%64%0%55%0%82%45%82%64%82%73%55%64%45%55%100%91%82%45%64%55%91%82%100%100%55%82%91%
Arrakhammer65.66%36%18%0%64%64%64%18%64%45%64%18%82%45%73%100%73%100%45%27%91%100%100%82%100%100%100%100%
Tyr68.01%73%9%9%100%64%9%36%36%91%73%64%100%64%45%55%91%91%82%64%82%100%100%73%82%91%100%55%
Steamhammer65.32%0%18%27%36%64%82%18%55%9%91%45%100%91%36%82%36%100%45%55%100%100%100%100%82%100%91%100%
AILien56.42%27%27%0%9%64%64%27%36%27%9%0%27%36%45%73%82%91%80%100%73%36%100%100%100%91%100%100%
LetaBot66.89%82%36%36%9%18%18%45%82%36%55%100%100%45%91%0%55%100%90%91%91%55%91%100%82%100%100%100%
Ximp54.88%9%9%0%0%18%64%36%18%0%0%73%0%45%100%0%100%64%91%91%91%100%100%91%91%100%91%100%
UAlbertaBot55.22%0%0%9%9%18%55%55%55%36%9%64%55%55%82%73%82%45%64%100%73%82%64%55%100%55%100%100%
Aiur53.22%36%82%0%55%9%9%45%27%55%64%55%9%0%18%91%91%64%22%27%100%18%82%91%100%82%100%100%
IceBot42.23%9%0%0%0%18%0%0%0%45%18%27%100%100%27%9%0%55%60%36%45%82%73%73%100%100%73%91%
Skynet44.26%0%0%0%18%0%64%9%27%9%64%18%45%0%18%9%100%27%20%64%73%64%100%64%100%100%100%100%
KillAll42.76%18%82%0%9%0%9%18%0%9%0%9%0%36%55%36%45%73%55%91%55%100%91%64%73%36%91%100%
MegaBot47.16%20%10%0%10%9%45%55%55%18%55%20%10%9%36%78%40%80%45%18%82%40%82%70%100%100%100%100%
Xelnaga43.10%0%9%18%45%18%0%36%73%36%45%0%9%9%0%73%64%36%9%82%82%45%0%82%100%100%100%91%
Overkill29.97%0%0%0%0%0%9%45%9%18%0%27%9%9%27%0%55%27%45%18%18%73%45%64%55%82%82%91%
Juno31.08%0%27%0%9%45%0%9%0%0%0%64%45%0%18%82%18%36%0%60%55%27%0%55%100%73%73%45%
GarmBot27.61%0%0%0%0%0%0%18%0%0%0%0%9%0%36%18%27%0%9%18%100%55%100%82%9%100%82%82%
Myscbot21.28%27%9%9%18%0%9%0%18%27%0%0%0%9%45%9%27%36%36%30%18%36%45%18%73%0%64%9%
HannesBredberg17.57%0%0%0%18%0%9%0%0%18%18%0%18%9%0%0%0%0%27%0%0%45%0%91%27%100%82%9%
Sling18.64%55%0%0%36%0%0%45%0%9%0%9%0%0%45%18%0%0%64%0%0%18%27%0%100%0%55%18%
ForceBot14.14%0%0%0%64%0%0%18%0%0%9%0%0%9%0%0%27%0%9%0%0%18%27%18%36%18%45%82%
Ziabot16.22%0%0%0%0%0%0%9%0%45%0%0%0%0%0%0%9%0%0%0%9%9%55%18%91%91%82%18%

(4) Empire of the Sun

overallZZZKPurpIroncpacMicrCherMcRaArraTyrSteaAILiLetaXimpUAlbAiurIceBSkynKillMegaXelnOverJunoGarmMyscHannSlinForcZiab
ZZZKBot84.46%73%64%73%100%91%73%82%45%91%73%91%82%100%73%100%91%100%90%100%100%100%100%64%100%27%100%100%
PurpleWave85.08%27%73%100%80%91%82%100%91%82%55%73%100%100%55%91%100%64%100%91%100%73%100%82%100%91%100%100%
Iron78.04%36%27%82%64%0%45%100%91%82%100%64%100%73%91%100%100%9%90%55%100%100%100%100%100%100%100%100%
cpac69.70%27%0%18%91%45%100%55%0%73%82%73%100%100%55%82%91%82%82%82%82%82%100%82%91%55%55%100%
Microwave70.95%0%20%36%9%45%27%82%45%45%45%82%73%91%82%91%100%100%82%82%91%82%100%100%100%100%100%100%
CherryPi68.35%9%9%100%55%55%45%27%82%27%27%82%55%45%82%100%45%73%45%91%100%100%100%91%100%100%100%100%
McRave62.29%27%18%55%0%73%55%55%73%45%55%64%91%55%36%82%45%55%45%100%91%55%100%100%73%45%91%100%
Arrakhammer66.78%18%0%0%45%18%73%45%91%45%55%64%91%64%64%91%55%100%44%64%100%100%100%73%100%100%100%100%
Tyr68.35%55%9%9%100%55%18%27%9%91%55%55%100%82%91%55%73%100%82%73%91%100%91%82%91%73%100%82%
Steamhammer61.15%9%18%18%27%55%73%55%55%9%73%45%91%73%27%91%27%91%50%64%100%100%100%55%64%100%82%100%
AILien60.81%27%45%0%18%55%73%45%45%45%27%0%64%36%55%82%91%100%70%82%64%36%100%100%100%100%82%100%
LetaBot54.42%9%27%36%27%18%18%36%36%45%55%100%73%45%55%9%64%91%50%36%64%55%91%100%36%100%91%100%
Ximp51.35%18%0%0%0%27%45%9%9%0%9%36%27%36%100%18%100%64%90%82%64%100%100%82%91%100%82%100%
UAlbertaBot48.82%0%0%27%0%9%55%45%36%18%27%64%55%64%73%91%64%18%55%100%64%82%27%27%73%55%91%100%
Aiur49.16%27%45%9%45%18%18%64%36%9%73%45%45%0%27%73%82%64%9%36%100%27%64%55%91%73%100%91%
IceBot41.89%0%9%0%18%9%0%18%9%45%9%18%91%82%9%27%27%82%40%0%82%91%27%82%100%91%91%73%
Skynet44.41%9%0%0%9%0%55%55%45%27%73%9%36%0%36%18%73%27%22%36%82%18%100%64%100%100%100%100%
KillAll47.14%0%36%91%18%0%27%45%0%0%9%0%9%36%82%36%18%73%82%91%45%100%100%82%100%36%64%91%
MegaBot50.18%10%0%10%18%18%55%55%56%18%50%30%50%10%45%91%60%78%18%70%91%30%55%91%100%78%89%82%
Xelnaga39.53%0%9%45%18%18%9%0%36%27%36%18%64%18%0%64%100%64%9%30%82%36%0%100%73%73%91%45%
Overkill29.97%0%0%0%18%9%0%9%0%9%0%36%36%36%36%0%18%18%55%9%18%82%45%55%36%91%100%91%
Juno34.12%0%27%0%18%18%0%45%0%0%0%64%45%0%18%73%9%82%0%70%64%18%0%73%82%82%73%64%
GarmBot31.31%0%0%0%0%0%0%0%0%9%0%0%9%0%73%36%73%0%0%45%100%55%100%100%0%100%73%73%
Myscbot22.90%36%18%0%18%0%9%0%27%18%45%0%0%18%73%45%18%36%18%9%0%45%27%0%64%0%64%27%
HannesBredberg22.90%0%0%0%9%0%0%27%0%9%36%0%64%9%27%9%0%0%0%0%27%64%18%100%36%91%73%18%
Sling23.05%73%9%0%45%0%0%55%0%27%0%0%0%0%45%27%9%0%64%22%27%9%18%0%100%9%73%9%
ForceBot16.27%0%0%0%45%0%0%9%0%0%18%18%9%18%9%0%9%0%36%11%9%0%27%27%36%27%27%100%
Ziabot16.84%0%0%0%0%0%0%0%0%18%0%0%0%0%0%9%27%0%9%18%55%9%36%27%73%82%91%0%

(4) Fortress

overallZZZKPurpIroncpacMicrCherMcRaArraTyrSteaAILiLetaXimpUAlbAiurIceBSkynKillMegaXelnOverJunoGarmMyscHannSlinForcZiab
ZZZKBot90.57%91%73%73%82%91%91%91%73%100%91%100%100%100%100%100%100%100%100%100%100%100%100%82%100%9%100%100%
PurpleWave78.45%9%55%91%91%82%36%100%73%82%27%55%91%91%55%82%91%55%100%91%100%73%100%91%100%100%100%100%
Iron83.84%27%45%100%100%0%27%91%100%82%100%100%100%64%100%100%100%45%100%100%82%100%100%100%100%100%100%100%
cpac69.15%27%9%0%91%55%100%27%9%64%82%91%100%100%64%100%82%64%89%55%82%73%100%73%82%91%64%100%
Microwave71.33%18%9%0%9%55%36%55%55%73%27%100%64%90%100%91%91%100%100%100%100%73%100%100%100%100%91%100%
CherryPi71.72%9%18%100%45%45%55%18%91%45%45%91%64%64%91%91%45%73%73%91%91%100%100%91%100%100%100%100%
McRave69.59%9%64%73%0%64%45%82%64%73%55%100%91%91%27%82%55%82%80%91%45%45%100%100%100%91%82%91%
Arrakhammer69.02%9%0%9%73%45%82%18%82%27%91%100%64%73%73%91%64%100%55%36%100%100%100%73%100%100%100%100%
Tyr70.71%27%27%0%91%45%9%36%18%100%82%100%100%64%100%55%100%100%91%64%91%91%100%82%100%55%100%82%
Steamhammer63.18%0%18%18%36%27%55%27%73%0%82%91%91%82%36%91%73%91%30%64%82%100%100%100%55%100%82%100%
AILien60.94%9%73%0%18%73%55%45%9%18%18%73%55%27%73%82%73%100%55%82%73%73%100%73%100%100%91%100%
LetaBot24.75%0%45%0%9%0%9%0%0%0%9%27%9%18%55%0%9%82%33%0%0%82%36%91%0%91%45%18%
Ximp53.20%0%9%0%0%36%36%9%36%0%9%45%91%55%100%0%100%36%55%82%82%100%100%64%100%100%91%100%
UAlbertaBot52.70%0%9%36%0%10%36%9%27%36%18%73%82%45%55%91%73%36%64%100%27%91%82%64%91%100%64%100%
Aiur48.15%0%45%0%36%0%9%73%27%0%64%27%45%0%45%82%82%73%9%27%91%36%100%73%100%100%82%73%
IceBot44.11%0%18%0%0%9%9%18%9%45%9%18%100%100%9%18%45%64%55%9%64%55%82%91%100%100%73%91%
Skynet46.13%0%9%0%18%9%55%45%36%0%27%27%91%0%27%18%55%9%27%55%100%64%100%73%100%100%100%100%
KillAll43.92%0%45%55%36%0%27%18%0%0%9%0%18%64%64%27%36%91%50%91%27%100%100%73%73%45%36%100%
MegaBot48.23%0%0%0%11%0%27%20%45%9%70%45%67%45%36%91%45%73%50%27%70%40%100%73%100%70%91%90%
Xelnaga41.75%0%9%0%45%0%9%9%64%36%36%18%100%18%0%73%91%45%9%73%91%27%9%64%100%91%91%18%
Overkill39.19%0%0%18%18%0%9%55%0%9%18%27%100%18%73%9%36%0%73%30%9%91%91%73%55%91%73%82%
Juno31.08%0%27%0%27%27%0%55%0%9%0%27%18%0%9%64%45%36%0%60%73%9%9%36%100%55%55%100%
GarmBot20.20%0%0%0%0%0%0%0%0%0%0%0%64%0%18%0%18%0%0%0%91%9%91%73%0%91%18%73%
Myscbot24.92%18%9%0%27%0%9%0%27%18%0%27%9%36%36%27%9%27%27%27%36%27%64%27%82%0%55%45%
HannesBredberg18.24%0%0%0%18%0%0%0%0%0%45%0%100%0%9%0%0%0%27%0%0%45%0%100%18%64%55%9%
Sling19.59%91%0%0%9%0%0%9%0%45%0%0%9%0%0%0%0%0%55%30%9%9%45%9%100%36%64%9%
ForceBot25.25%0%0%0%36%9%0%18%0%0%18%9%55%9%36%18%27%0%64%9%9%27%45%82%45%45%36%82%
Ziabot19.93%0%0%0%0%0%0%9%0%18%0%0%82%0%0%27%9%0%0%10%82%18%0%27%55%91%91%18%

(4) Python

overallZZZKPurpIroncpacMicrCherMcRaArraTyrSteaAILiLetaXimpUAlbAiurIceBSkynKillMegaXelnOverJunoGarmMyscHannSlinForcZiab
ZZZKBot91.22%82%73%91%82%91%55%91%64%100%91%82%100%100%100%100%100%100%100%100%100%100%100%64%100%100%100%100%
PurpleWave82.15%18%82%100%100%82%55%100%82%100%36%73%82%91%55%100%91%36%91%82%100%64%100%100%100%100%100%100%
Iron83.67%27%18%73%91%10%82%82%100%100%100%91%100%82%100%100%100%36%89%100%100%91%100%100%100%91%91%100%
cpac66.33%9%0%27%91%55%91%36%0%82%82%55%100%100%55%100%64%73%73%55%82%64%100%82%55%100%64%100%
Microwave69.70%18%0%9%9%82%18%73%45%73%36%73%64%100%100%91%73%100%82%100%82%55%100%100%100%100%100%100%
CherryPi69.05%9%18%90%45%18%55%45%82%36%36%91%73%55%91%82%45%45%90%100%91%100%100%80%100%100%91%100%
McRave63.85%45%45%18%9%82%45%91%64%55%82%27%64%36%55%64%64%82%60%64%18%91%100%100%91%73%100%100%
Arrakhammer64.19%9%0%18%64%27%55%9%100%9%36%64%91%64%64%91%55%91%60%45%100%100%100%82%100%100%100%100%
Tyr64.98%36%18%0%100%55%18%36%0%64%45%45%100%82%36%91%64%82%64%64%91%100%91%91%91%100%100%91%
Steamhammer61.82%0%0%0%18%27%64%45%91%36%100%55%73%82%27%100%55%91%70%55%100%100%100%73%27%100%82%100%
AILien61.28%9%64%0%18%64%64%18%64%55%0%9%36%55%55%100%82%82%73%91%73%73%100%82%91%100%100%100%
LetaBot58.25%18%27%9%45%27%9%73%36%55%45%91%82%64%64%18%73%82%82%27%73%55%73%91%55%100%100%100%
Ximp51.18%0%18%0%0%36%27%36%9%0%27%64%18%45%91%0%91%36%82%36%73%100%100%91%100%100%100%100%
UAlbertaBot50.51%0%9%18%0%0%45%64%36%18%18%45%36%55%73%82%64%27%82%100%45%82%45%82%82%64%91%100%
Aiur47.47%0%45%0%45%0%9%45%36%64%73%45%36%9%27%82%82%73%27%18%91%0%82%82%82%73%91%64%
IceBot44.41%0%0%0%0%9%18%36%9%9%0%0%82%100%18%18%36%82%33%55%64%91%73%91%91%100%82%100%
Skynet47.30%0%9%0%36%27%55%36%45%36%45%18%27%9%36%18%64%27%20%64%100%82%100%27%100%100%91%100%
KillAll48.15%0%64%64%27%0%55%18%9%18%9%18%18%64%73%27%18%73%73%100%45%100%91%91%55%73%27%91%
MegaBot44.64%0%9%11%27%18%10%40%40%36%30%27%18%18%18%73%67%80%27%45%78%45%70%50%90%91%100%100%
Xelnaga42.42%0%18%0%45%0%0%36%55%36%45%9%73%64%0%82%45%36%0%55%91%36%0%82%55%82%100%100%
Overkill32.54%0%0%0%18%18%9%82%0%9%0%27%27%27%55%9%36%0%55%22%9%27%64%73%55%82%91%82%
Juno32.32%0%36%9%36%45%0%9%0%0%0%27%45%0%18%100%9%18%0%55%64%73%9%27%73%73%73%73%
GarmBot28.72%0%0%0%0%0%0%0%0%9%0%0%27%0%55%18%27%0%9%30%100%36%91%100%0%100%82%91%
Myscbot22.71%36%0%0%18%0%20%0%18%9%27%18%9%9%18%18%9%73%9%50%18%27%73%0%45%9%82%18%
HannesBredberg28.72%0%0%0%45%0%0%9%0%9%73%9%45%0%18%18%9%0%45%10%45%45%27%100%55%73%91%45%
Sling13.80%0%0%9%0%0%0%27%0%0%0%0%0%0%36%27%0%0%27%9%18%18%27%0%91%27%55%0%
ForceBot15.49%0%0%9%36%0%9%0%0%0%18%0%0%0%9%9%18%9%73%0%0%9%27%18%18%9%45%100%
Ziabot12.88%0%0%0%0%0%0%0%0%9%0%0%0%0%0%36%0%0%9%0%0%18%27%9%82%55%100%0%

These tables surface tons of details, many of which are hard to interpret. For example, ZZZKBot shows different patterns of upsets on different maps, suggesting that ZZZKBot’s strategy selection was a little fragile and sometimes got exploited.

LetaBot hated the map Fortress, doing poorly against most opponents. It apparently failed to cope with something about the map. Myscbot liked the 2-player maps Benzene and Destination (but for some reason not Heartbreak Ridge). The tables reveal that it is because Myscbot upset specific opponents on these maps in particular. Something narrow and specific about the maps and strategies aligned for Myscbot.

I will poke at some of the bots to tease out their secrets. Maybe that will reveal the meaning behind some of the mysterious numbers.

Next: Looking at ZZZKBot.

AIIDE 2017 race balance

The race representation in AIIDE 2017 was very unbalanced, with 13 zergs and only 4 terrans. But the results were closely balanced by race. If the colors in the table look white, well, one of them is and the others nearly are.

racescore
terran51%
protoss50%
zerg49%
random53%

All races did equally well overall. At the top of the rankings too, the 3 winners represent each race and their scores are virtually equal. I take it to mean that there is no good reason for the preponderance of zergs. In a way, the balance is a coincidence; if one race had stronger entrants, maybe for reasons unrelated to Starcraft, there would be an imbalance. And yet the point is made: It doesn’t matter what race you choose for your bot.

Only 1 bot played random, UAlbertaBot. That leaves the vRandom statistics not very interesting, so I left them out of the other tables.

Since the overall balance is virtually level, I added a matchup table.

vTvPvZ
terran51%52%
protoss49%51%
zerg48%49%

Again, the balance is virtually level. Terran wasn’t balanced because terran did well against zerg and poorly against protoss or vice versa; everything was equal all around. Well, protoss did a smidge better versus zerg and a smidge worse versus terran, but it’s hardly noticeable.

#botraceoverallvTvPvZ
1ZZZKBotzerg83.11%75%79%88%
2PurpleWaveprotoss82.35%79%82%83%
3Ironterran81.52%88%85%78%
4cpaczerg71.01%73%63%75%
5Microwavezerg70.86%77%67%71%
6CherryPizerg69.08%92%70%62%
7McRaveprotoss67.07%70%65%68%
8Arrakhammerzerg65.95%65%59%72%
9Tyrprotoss65.91%52%70%68%
10Steamhammerzerg64.14%57%54%74%
11AILienzerg58.29%48%61%62%
12LetaBotterran56.92%30%61%61%
13Ximpprotoss54.19%34%63%55%
14UAlbertaBotrandom53.40%58%60%47%
15Aiurprotoss50.46%54%49%52%
16IceBotterran45.62%64%50%40%
17Skynetprotoss43.78%40%32%54%
18KillAllzerg43.04%39%55%34%
19MegaBotprotoss42.83%43%41%45%
20Xelnagaprotoss37.10%54%38%34%
21Overkillzerg32.69%25%30%37%
22Junoprotoss29.57%39%35%24%
23GarmBotzerg27.09%15%34%24%
24Myscbotprotoss25.94%19%25%27%
25HannesBredbergterran21.26%18%11%31%
26Slingzerg21.09%8%28%19%
27ForceBotzerg17.97%21%15%20%
28Ziabotzerg17.21%26%21%13%

Individual bots, of course, are not as balanced. Some of the table cells have striking numbers. First of all, with many zergs and few terrans, the vZ column carries the most weight. Sure enough, #3 Iron’s relative weakness versus zerg (“only” winning 3:1) allowed competitors to squeeze in front.

The largest number in any cell is #6 CherryPi’s 92% versus terran. CherryPi crushed the 4 terrans: #3 Iron, #12 LetaBot, #16 ICEbot, #25 HannesBredberg. #26 Sling, in contrast, rolled over and died for terrans but had some chance against other races. It makes sense that the matchup with the fewest participants, terran, would give us the most extreme numbers.

#12 LetaBot and #13 XIMP struggled against terran, while #16 ICEbot and #20 Xelnaga were happy to accept terran customers. #10 Steamhammer and #17 Skynet only played well against zerg, while #18 KillAll liked protoss victims.

Next: The per-map crosstables. Prepare for data overload.

AIIDE 2017 replays

1. Dave Churchill let me know: The AIIDE 2017 results now include replays. You can watch individual games from the html result listing (the page comes with other nice features too) or you can download bulky replay packs of each bot.

2. The race balance post will follow as soon as my parsing script can reproduce the official results. There seem to be subtle points I haven’t gotten quite right yet.