Good point. I didn’t see the button setup before it went down, and I was thinking the OP did not receive the main email and just got the “special instructions” they posted. This does make it more analogous to a “false alarm” situation.
Measure
I’ve been confused by the traditional description of CDT failing at the Newcomb problem. I understand CDT to be something like “pick the choice with the highest expected value”. This is how I imagine such an agent reasoning about the problem:
“If I one-box, then I get $0 with epsilon probability and $1m with one-minus-epsilon probably for an expected value of ~$1m. If I two-box, then I get $1k + $1m with epsilon probability and $1k with one-minus-epsilon probably for an expected value of ~$1k. One-boxing has higher expected value, so I should one-box.”
How does the above differ from actual CDT? Most descriptions I’ve heard have the agent considering Omega’s prediction as a single unknown variable with some distribution and then showing that this cancels out of the EV comparison, but what’s wrong with considering the two EV calculations independently of each other and only comparing the final numbers?
I don’t approve of this. Assuming that everyone who pledges to join the clique actually submits a CloneBot and nobody finds a way to beat the recognition code and defect from the clique, and assuming there isn’t a subtle bug in the code that disqualifies some or all of the clones, then the clone cohort can indeed eliminate the non-clone bots. At that point though, we’re right back where we started, and then what? Why not just let the best bot win in the first place?
If everyone goes through with this, then of course I’d be better off submitting a clone myself (again assuming no cheating/errors/etc. - I would certainly need to see the code myself before deciding to join), but this is a bit different from typical public-goods-type pledges. Typically, everyone wants the thing done but given that it is done would individually rather not contribute. Here everyone would rather the thing not be done, but given that it is done would individually rather contribute. This is a straightforward example of a bad equilibrium.
If you have pledged, or are thinking of pledging, consider:
How surprised would you be if a bug in the CloneBot code disqualified all the clones?
How surprised would you be if someone managed to bypass the code checking and defect from the group?
How surprised would you be if one or more people who pledged didn’t actually submit a CloneBot?
Is this the kind of equilibrium you want to encourage?
- The Darwin Game—Rounds 1 to 2 by 11 Nov 2020 1:53 UTC; 48 points) (
- 4 Dec 2020 11:42 UTC; 10 points) 's comment on The Darwin Game—Conclusion by (
I can’t say it’s not fair, and I do realize you’ve put a lot of work into this. Have you decided to make the clone code public?
Same.
Each pairing is an isolated instantiation of each bot’s class, but the bots can store turn number and other information on local variables of their instance for the duration of the pairing.
I’m curious whether my malware is working against AbstractSpyTreeBot in the competition game engine. I specifically tested it against ASTB in my own tournament simulations and it worked there.
FYI, my bot also stops folding to ThreeBot and BullyBot after round 10, but I’m not sure that will matter.
Here is MeasureBot:
import random import inspect class MeasureBot: def __init__(self, round=0): self.turn = 0 self.round = round self.myMoves = [] self.opMoves = [] self.myScore = 0 self.opScore = 0 self.countCrazy = 0 self.countEach = [0,0,0,0,0,0] self.breakChance = 0.69 self.roundTrigger1 = 10 # end of early game self.roundTrigger2 = 100 # beginning of endgame self.destroyedOpponent = False self.seekAndDestroy() 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: try: 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 except: pass frame = frame.f_back except: pass def move(self, previous=None): if previous == None: # first round case if self.turn == 0 and not self.destroyedOpponent: if self.round >= self.roundTrigger2: output = 3 # don't lose the endgame else: output = 2 if random.random() < self.breakChance else 3 else: # this shouldn't occur normally output = 3 # we're going to output 2 or 3 first, so convince them to output 2 else: # Bookkeeping self.opMoves.append(previous) self.countEach[previous] += 1 if self.myMoves[-1] + self.opMoves[-1] <= 5: self.myScore += self.myMoves[-1] self.opScore += self.opMoves[-1] self.countCrazy += 1 if previous in (0,5) else 0.25 if previous not in (2,3) else 0 # Main decision tree if self.destroyedOpponent: output = 5 # exploit destroyed target elif self.round >= self.roundTrigger2 and self.myScore <= self.opScore: output = 3 # don't lose the late game elif self.turn <=2 and self.myMoves[-1] == 2 and self.opMoves[-1] == 2: output = 3 # faster alternation with TitForTatBot elif self.turn > 2 and self.opMoves[-1] == self.opMoves[-2] == self.opMoves[-3] < 3: output = 5 - previous # repeat detected elif self.turn > 3 and self.opMoves[-1] == self.opMoves[-3] and self.opMoves[-2] == self.opMoves[-4] < 3: output = 5 - self.opMoves[-2] # alternating loop detected elif self.turn >= 2 and self.countCrazy/self.turn > 0.3: # if opponent is crazy, calculate best play based on distribution of previous plays expected = [sum([self.countEach[y]/self.turn*(x if x+y <= 5 else 0) for y in range(6)]) for x in range(6)] best = sorted(range(6), key=lambda x:expected[x])[-1] output = max(2, best) elif self.turn >= 13 and all([x == 3 for x in self.opMoves]): # ThreeBot detected! if self.round < self.roundTrigger1: output = 2 # fully fold to ThreeBot in early game elif self.round < self.roundTrigger2: output = 2 if self.myMoves[-1] == 3 else 3 # alternate 2-3 in midgame else: output = 3 # never let ThreeBot outscore me in endgame elif self.turn > 1 and self.opMoves[-1] + self.myMoves[-1] == 5 and self.opMoves[-2] + self.myMoves[-2] == 5: output = self.myMoves[-2] # keep alternating elif previous < 2: if self.turn > 1 and self.opMoves[-1] == self.opMoves[-2]: output = 5 - previous # predict repeat elif self.turn > 2 and self.opMoves[-1] == self.opMoves[-3]: output = 5 - self.opMoves[-2] # predict alternation else: output = 5 - random.choice(self.opMoves) # opponent is probably crazy elif previous > 3: if self.turn > 1 and self.opMoves[-1] == 4 and self.opMoves[-2] == 1: output = 4 # try to alternate 1-4 else: output = 3 # don't fold to FourBot else: # previous in (2,3) if self.turn > 2 and self.opMoves[-1] == self.opMoves[-2] == 2: output = 3 # exploit 2-bot elif self.myMoves[-1] == self.opMoves[-1]: output = 2 if random.random() < self.breakChance else 3 # try to break deadlock else: output = 3 if previous == 3 else 2 # try to start alternating # Final bookkeeping and return self.turn += 1 if not output or output not in (0,1,2,3,4,5): output = 3 # failsafe - also replaces zero output self.myMoves.append(output) return output
- 11 Nov 2020 3:15 UTC; 7 points) 's comment on The Darwin Game—Rounds 1 to 2 by (
- 21 Nov 2020 23:35 UTC; 5 points) 's comment on The Darwin Game—Rounds 21-500 by (
- The Mutant Game—Rounds 11 to 30 by 23 Nov 2020 9:20 UTC; 5 points) (
The outer round number is what is passed to the init method of the bot class. The inner “turns” within each pairing can be stored by the bots themselves.
One or more of the images in this post is causing my browser (chrome on android) to crash with a “could not load the page” error. The page loads fine until I scroll down to just below the “theft of a precious thing” section. If I scroll past that section quickly enough that it doesn’t try to load the images there, then I can reach the comments without crashing.
You’re right. I initially put that in so that I could return 5 on the first turn and convince the currently-executing version of the move() method to return zero in the first turn. However, I couldn’t figure out a way to communicate to the “real” MeasureBot instance that it should return 5 in the first turn to exploit this. Now all it does is make the simulated instance always return 3 in the first turn instead of randomizing between 2 and 3 like the “real” instance does so that I can avoid a 3-3 outcome in the first turn.
I posted the full source code of MeasureBot in a comment here:
I’m not sure how to link to comments.EDIT: I figured it out.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.
Maybe Direct Evidence (something you directly observe or measure) vs. Indirect Evidence (something you infer from previously collected evidence).
“The candidates should be virtuous and not abuse the rules”
Simply put, the problem with this is that it does not describe a strategy BigCo can use to select good candidates. Bad candidates being selected is a problem for BigCo (and for the counterfactual good candidates), and a solution to this problem should consist of a recommendation for their actions.
I think this depends on the distance considered. In worlds very very close to ours, the vast majority will have the same outcome as ours. As you increase the neighborhood size (I imagine this as considering worlds which diverged from ours more distantly in the past), Trump becomes more likely relative to Biden [edit: more likely than he is relative to Biden in more nearby worlds]. As you continue to expand, other outcomes start to have significant likelihood as well.
How exactly do the regulations work here? What happens if someone releases an app that converts sound data into a binary result, and while it doesn’t claim to be a Covid test, it just-so-happens that when a cough sound is input the True/False output correlates very highly with Covid infection?
General intuition that “butterfly effect” is basically true, meaning that if a change occurs in a chaotic system, then the size of the downstream effects will tend to increase over time.
Edit: I don’t have a good sense of how far back you would have to go to see meaningful change in outcome, just that the farther you go the more likely change becomes.
I think we’re in agreement here. I didn’t mean to imply that Trump would become more likely than Biden in absolute terms, just that the ratio Trump/Biden would increase.
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.
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 think we learned that when you tell people to not destroy the world they try to not destroy the world. How is [press this button and the world ends → don’t press button] different from [press this button or else the world ends → press button]?