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.
Comments
PurpleWaveJadien on :
McRave on :
Jay Scott on :
Tully Elliston on :
There isn't enough cheesing bots in the SSCAI pool at the moment. I would probably be great and healthy for the meta if the main bot owners would each release an exclusively cheesing variations of their bot into the pool for a while, for everyone to adapt to.
MicroDK on :
krasi0 on :
MicroDK on :
PurpleWaveJadien on :
Jay Scott on :
krasi0 on :
Keep up the good work and looking forward to the next AI entry on the list.