Click here to participate. Entries must be submitted on October 18th, 2020 or earlier.
Entry is now closed.
In 2017, Zvi posted an exciting story about The Darwin Game, a variation of iterated prisoner's dilemma.
I will run my own version of the game in the week following October 18th, 2020. You do not have to know how to program in order to participate. I will code simple bots for non-programmers. If you do know how to program then you may create your own complicated bot.
Here are the rules. Changes from Zvi's original game are in brackets [like this].
For the first round, each player gets 100 copies of their program in the pool, and the pool pairs those programs at random. You can and often will play against yourself.
Each pair now plays an iterated prisoner’s dilemma variation, as follows. Each turn, each player simultaneously submits [an integer] from 0 to 5. If the two numbers add up to 5 or less, both players earn points equal to their number. If the two numbers add up to 6 or more, neither player gets points. This game then lasts for a large but unknown number of turns, so no one knows when the game is about to end; [I guarantee it will be at least 100 turns per iterated prisoner's dilemma].
Each pairing is independent of every other pairing. [You do know what round of the game it is and that you are facing an opponent. If you face a copy of yourself you are automatically awarded the maximum 5 points per round (2.5 points per bot). You otherwise do not know any history of the game to this point.] Your decision algorithm does the same thing each pairing.
At the end of the round, all of the points scored by all of your copies are combined. Your percentage of all the points scored by all programs becomes the percentage of the pool your program gets in the next round. So if you score 10% more points, you get 10% more copies next round, and over time successful programs will displace less successful programs. Hence the name, The Darwin Game.
Your goal is to have as many copies in the pool at the end of the last round as possible, or failing that, to survive as many rounds as possible with at least one copy.
[I will attempt to iterate until there is a stable equilibrium.]
I will add some silly bots of my own to make the early game more interesting.
Instructions for non-programmers
Please give a simple explanation of what you want your bot to do. Write it with mathematical precision. If your specification is even slightly ambiguous then you will be disqualified.
Instructions for programmers
Write a program of the following format.
class TitForTatBot():
def __init__(self, round=0): # Edit: Changed "1" to "0"
self.turn = 0
self.round = round
self.previous = None
def move(self, previous=None):
self.turn += 1
if self.previous:
output = self.previous
self.previous = previous
return output
else:
return 2
# Edit 2020-10-11: The above code is wrong. The properly-implemented TFT `move` method looks like this.
# def move(self, previous=None):
# self.turn += 1
# if previous == None:
# return 2
# else:
# return previous
Your class must have an __init__(self, round=1)
intializer and a move(self, previous=None)
method. You may write your class in Python 3 or Hy.
Unlike Zvi's original game, you do get to know what round it is. Rounds are indexed starting at 0. The previous
parameter of the move
method is an integer indicating what your opponent did last iteration. If it is the first iteration then previous
equals None
.
A new instance of your class will be initialized in each round. You may save whatever information you want into the class instance's fields but you may not save information between rounds or between class instantiations. The move
method must always return an integer from 0 to 5 inclusive.
You may import standard libraries like random
, scikit
and numpy
.
Coordinating with other players
Anyone can play, but only players with a Less Wrong account that existed before I declared this tournament will be allowed to coordinate out-of-game. This rule exists to prevent players from submitting multiple entries to this contest and self-coordinating. Coordinating with other people is encouraged. Coordinating with yourself between multiple separate entries is cheating.
Click here to participate. Entries must be submitted on October 18th, 2020 or earlier.
Entry is now closed.
tl;dr I betrayed the CloneBot clique and submitted MimicBot. My submission is in this Github repository.
My Process in chronological order:
There were three important things I noted in the original post
It seemed to me that the best strategy was to get as many points as possible early by exploiting silly bots, cooperating with anyone willing to cooperate, and folding somewhat to attackers. Then later on just play a non-exploitable cooperative strategy and hope for your early advantage to snowball.
Simulation
After seeing AbstractSpyTreeBot and some of the comments around it, it seemed to me that simulation was perhaps the best way to take advantage of simple bots. There are various approaches you could take, but mine was to simulate every possible sequence of moves I could make for the next N turns, and use the one with the best outcome. Since this has exponential time complexity, I only considered the moves 2 and 3 and kept N fairly small, with the option for the game runner to reduce it further to improve performance.... (read more)
Free self recognition seems like it makes game less interesting, And that anyone who gets a big lead early just wins?
Given that you can read the opponent's source code, self-recognition is trivial to implement anyway (trivial but annoying, since you need to do quining).
Is reading the opponent's source code legal?
If you're participating in the contest and you want to win, I have a proposition for you:
Howdy! You've probably looked up Zvi's past Darwin game that directly inspired this one. A group of players formed a clique who recognized each other, cooperated among themselves and defected on everyone else. They nearly wiped the board, but they were preyed upon by a member who played both sides.
What they missed was a way to guarantee that all members apply the decided strategy. They had no way to enforce it.
But we have a way.
I call it CloneBot: a bot who checks that its opponent has the exact same code as itself. No way to cheat that! It guarantees that every member of the clique does the same thing. Moreover, there'll be a way to cooperate optimally, avoiding losing the first rounds to coordinate. The clique are gonna be the most efficient ccoperators.
But in the end we're all gonna tie, it's boring. I want to take a chance at winning!
So do I. This is why the clique are only going to collaborate until a predefined round. After we've eliminated the competition, we can have a dramatic showdown among ourselves. Cool, no? In the code, there's gonna be a separate function that's called only after... (read more)
Explanation of my strategy and thought process in chronological order
After seeing Vanilla_Cabs's comment I lied to them about wanting to join the clique. I was undecided, but I figured seeing the code of the clique can be a great advantage if I can exploit some coding mistake and I can still decide to join later anyway if I want.
The first versions of CloneBot (the name of the program for our clique) did actually contain a mistake I could exploit (by defining the __new__() method of the class after the payload) and so this was my plan until Vanilla_Cabs fixed this mistake. After they fixed it, I didn't notice any way I can take advantage, so I joined the clique in spirit.
Initially my plan for my bot was a simulator which simulates between 100 and 1000 turns of the opponent against a few candidate bots (ZviBot, TiTforTat, return 3, return 2, etc..) and then depending on the round number either chooses the one with the maximum point for me or the one which gets more points than the opponent. There were unfortunately two problems with this plan:
Little did you know that I was aware of this weakness from the beginning, and left it as a test to find whom I could trust to search for the weaknesses I didn't know. Of the 3 (I think) to whom I showed the code early, only Lanrian reported it.
I didn't play a simulator so I didn't care about the first.
About the second, I can tell you that another member alerted me that you seemed to have a hidden ally. They feared you had made an ally outside the clique, or just given the code to join the clique to a player know only to you. Which I thought was a possibility. Actually, I hoped for a few stowaways to boost our numbers.
So, in case anyone's wondering what I did...
I cared enough to think and enter, but not to program.
I designed a simulator, but was told it wouldn't be coded for me, so that was out.
So instead, I wrote this:
Until symmetry breaks, if the round # is 1, is 3 or is even, play sequence 23322232323322233 and then repeat 22222223 until symmetry breaks. If round # is odd and 5 or more, the reverse, except repeating 22222223 at the end.
Once it breaks, alternate 2 and 3 for 4 turns.
Then, if the last turn added to 5, keep doing that until they don't.
Once they don't...
If they've always played 0 or less, play 5.
If they've always played 1 or less, play 4.
If they've always played 2 or less, play 3.
Otherwise, depending on round number:
Rounds 1-50: Keep alternating until turn t+10. After that, if last turn added to 5, alternate 2 and 3. Otherwise, check their average score per round after symmetry. If it's 2.5 or lower, play 2, otherwise play 3.
Rounds 51-100: Same as above, except you also always play 3 if their score is 5 or more higher than yours.
Rounds 101+: Same as above, except you also always play 3 if their score is higher than yours.
(We could improve by add... (read more)
The first line says "Entries must be submitted on October 18, 2020, or earlier."
Then a bit later you say "I will run my own version of the game on October 16, 2020."
Will you be making your time-travel technology available to contestants' bots, and if so what is the API they should use?
Good question! My time travel technology will not be available to contestants' bots. This is in accordance with Less Wrong's established norm of containing dangerous technology.
I have edited the original post in a futile attempt to cover-up this leak and have removed the relevant API call from the
extra
module.Thanks for obeying the norms. That we definitely have. Around time travel technology.
Your TitForTatBot
* never sets self.previous
* even if it was set, it would stop cooperating when opponent played 0
Also I agree with Zvi's comment, why 2.5 for free? This way one should really concentrate on maxing out in the early stage, is it intended?
Will post a link to a github repo with my code later today (when I'm not meant to be working), but for now, here's my thought processes.
(Edit: my code is here. My entry is in incomprehensibot.)
General strategy:
I was undecided on joining the clique, but curious. I didn't want to be a sucker if someone (possibly the clique organizer) found a way to betray it. I sent out feelers, and Vanilla_Cabs shared the clique bot code with me.
I saw a way to defect against the clique. I think that's when I decided to do so, though I may have had the idea in my head befo
What timezome is the deadline in? Or to be maximally precise – can you give a final submission-hour in UTC?
Great initiative, thanks for organizing!
Fun! Note that the "automatic recognition of self" and "group, not individual fitness" rules are different from many such contests. I think it's likely that this allows super-simple bots to win, if the initial mix allows them to get past the first few iterations.
I'd predict three-bot is the most likely simple winner - it gets full value against itself (as does everyone), and gets some points for all opponents' probes and complex signaling (that includes bidding 0, 1, or 2). It NEVER gives an opponent more points than it gets.  ... (read more)
A thought for next time, if you want to build a simulator, it could make sense to wait one round before simulating anything even slightly unsafe, and do something simpler in round 1. That way, if something weird might potentially disqualify you but will itself get disqualified, it dies before it can remove you from the pool.
I don't know whether it's a competitive entry (it would be a FoldBot in Zvi's taxonomy), but as a quick piece of software, I'm pretty proud of
AbstractSpyTreeBot
!An interesting bot for simulators to grapple with is this:
class BullyBot:
def __init__(self, round=0):
self.opponentThreesPlayed = 0
def move(self, previous=None):
if self.opponentThreesPlayed > 3:
return previous
elif previous == 3:
self.opponentThreesPlayed+=1
if self.opponentThreesPlayed > 3:
return 2
return 3
Something that holds out just long enough to get a naive simulator to fold to it forever, but will probably end up cooperating with most others.
To check, what timezone is the deadline in?
This is the Nash bargaining game. Is there some specific reason to call it a "Prisoner's Dilemma variation", or is it just "everyone has heard of the Prisoner's Dilemma, and don't have a generic term for this kind of game-theory tournament"?
I'm a non programmer, if I submitted a bot that's too complicated or that is supposed to do something that isn't a possible move, would I be contacted and get a chance to change it, provided I submit it early enough?
Could you provide one or more examples of too complicated descriptions, just so I know for which level of complexity I should aim? I'm not clear on how you would consider a bot that has a decision three with different options and processes but no part that's hard to program, for example. (To avoid giving hints or good ideas, they can be filled with completely stupid instructions or be for bots that try to do some other stuff)
What are the rules about program runtime?
What's your rationale behind this? Isn't part of the point that you need to be able to survive even in an ecosystem consisting mainly of you?
Are comments allowed?
Is the number of rounds per matchup going to be in the tens, or the thousands?Edit: I just realised you specified in the post
.