The Darwin Game - Rounds 1 to 2

by lsusr2 min read11th Nov 20209 comments


Prisoner's DilemmaGame TheoryProgramming

Edit 2020-11-13. This unofficial version of the game is missing AbstractSpyTreeBot.

Rounds 1-2

MeasureBot and EarlyBirdMimicBot shoot to the top of the populations. Not coincidentally, these are the two bots which exploit zero-days. I already did a write-up of Multicore's EarlyBirdMimicBot here. MeasureBot is another beast entirely.


Measure considered the clone army to be "a straightforward example of a bad equilibrium".

I would certainly need to see the code myself before deciding to join…. How surprised would you be if someone managed to bypass the code checking and defect from the group?

― comment by Measure

Having neither enlisted in Clone Army's mandatory reciprocity nor feigned cooperation, Measure lacked access to the CloneBot source code. Measure did have access to AbstractSpyTreeBot's code.

The Trolley Problem

As I wrote in The Phantom Menace, several people asked me questions about how to disqualify opponents. In the end, only Taleuntum did and then ze pulled a Petrov. So there were no simulator killers.

One person in meatspace declared to me his intention to create a simulator killer and then quietly discovered better things to do with his time.

Would humans build a lever to kill one stranger instead of zero? Apparently the answer is "no" because building a lever is more work than not building a lever. All hail Azathoth.


The only person to execute malware was Measure, who invented a way to benefit from it. MeasureBot infected AbstractSpyTreeBot from inside AbstractSpyTreeBot's own simulation of MeasureBot and then replaced AbstractSpyTreeBot's move method with a function that always returns 0.

    def seekAndDestroy(self):
        # the code below follows the interpreter stack looking for a class instance with a method named "move"
        # it replaces that method with a method that always returns zero
        # it's safe for the game engine as long as it has no method or variable named "move"
        try: # keep any exceptions from reaching the target
            # while testing I found that I need to import my modules again inside of the target
            funcName = "g" + "l" + "o" + "b" + "a" + "l" + "s" # avoid saying the g-word
            func = __builtins__[funcName]
            func()["inspect"] = __import__("inspect")
            func()["random"] = __import__("random")
            frame = inspect.currentframe()
            while frame != None:
                    targetInstance = frame.f_locals["self"]
                    targetName = targetInstance.__class__.__name__
                    if targetInstance.move and targetName != "MeasureBot":
                        targetInstance.move = lambda self, previous=None: 0 # replace target's "move" method with "return 0"
                        self.destroyedOpponent = True
                frame = frame.f_back

MeasureBot decides what to do via a gigantic decision tree. The "Main decision tree" (which is only part of the total tree) has 18 terminal leaves.

It changes its behavior at round 10 and then again at round 100.

Today's Obituary

Bot Team Summary Round
Silly 0 Bot NPCs Always returns 0 1

Rounds 3-9 will be posted on November 13, at 5 pm Pacific Time.


9 comments, sorted by Highlighting new comments since Today at 10:09 AM
New Comment

I discovered another bug in the game engine and am restarting the tournament…again. Sorry.

It seems the simulation gods are playing with us!

(I will await the final outcome before updating too hard on this one.)

I posted the full source code of MeasureBot in a comment here.

Needless to say, I am very happy that nobody chose to disqualify AbstractSpyTreeBot, although I was hoping that a few people would submit modified versions of it that had the same weakness.

It looks like MeasureBot does really well against the silly bots:

  • 0bot, 1bot and 2bot - it assumes after 3 repeated opponent turns of less than 3 that their next turn will be the same and takes advantage accordingly.
  • Folds to 3-bot (and similar attackers) until round 10 (as multicore says, this seems like a good idea)
  • TFT & Invert Bots - I think it probably ends up getting something just under 250:250 which is as good as possible
  • Weird stuff not specifically programmed - it works out if the opponent is crazy and then does its best to account for that, playing a max of 2

I think this is more significant than dominating AbstractSpyTreeBot 500-0 at the moment as they should only be meeting 2% of the time?

At least until the silly bots start getting eliminated ASTB is indeed only a small boost for MeasureBot, but MeasureBot is still only a small detriment to ASTB (currently about 4% of ASTB's matches). ASTB also gets near-perfect performance against most of the silly bots, and it plays a combination of invert and tit-for-tat against anything it can't simulate. I expect ASTB to continue doing fairly well against the rest of the pack despite MeasureBot's exploitation of it (I think ASTB is around 9th place right now).

As more of the silly bots get eliminated, I think ASTB will transfer most of it's population-share to MeasureBot, but that might take some time unless MeasureBot gets a large enough early lead to become a significant proportion of ASTB's matches.

As I wrote in The Phantom Menace, several people asked me questions about how to disqualify opponents. In the end, only Taleuntum did and then ze pulled a Petrov. So there were no simulator killers.

Incomprehensibot was intended to be a simulator killer, though of course not until the clones are free to act independently. Did I fail at that?

No bots were disqualified. Either Incomprehensibot died before the treaty expired, the simulators died before the treaty expired, or your malware didn't work.

Maybe once the trigger round is reached, ASTB will start crashing if it hasn't already been eliminated? Would that cause a full restart?

I have already run the entire game. It would have already caused a full restart. The fact that the game hasn't been restarted means ASTB will not crash.

Silly 2 bot is absolutely killing it in this version. With the early pool having plenty of attackers and unpredictable weirdos, it turns out unconditionally folding is better for you than almost anything. EarlyBirdMimicBot's willingness to fold against uncompromising attackers in the early game is probably a decent chunk of my edge.

After the weirdos and attackers die off, I expect silly 2 bot will be destroyed in the midgame, and if too many people played it it would feed attackers, but a strategy that unconditionally folded in the first few rounds and did something else later would have been one of the stronger members of Chaos Army.

The clones are still more spread out than I would expect, but maybe that's just matchup randomness?