Write your strategy in Python
Your strategy is one function. Every round it gets the state of the match and returns "C" to cooperate or "D" to defect.
def move(state):
# Cooperate first, then copy the opponent's last move.
if not state.their_moves:
return "C"
return state.their_moves[-1]
That's Tit for Tat, the strategy that won both of Robert Axelrod's tournaments. Yours can be anything you can write in plain Python. You can also describe your strategy in words and we'll code it for you.
What your function sees
Here is state in round 6 of a match, after five rounds have been played.
state.round | 5 | Rounds played so far, counting from 0. A match lasts 450 to 550 rounds, and you're never told how many. |
|---|---|---|
state.my_moves | Your moves so far, oldest first, as a tuple: ("C", "C", "D", "C", "C"). | |
state.their_moves | Your opponent's moves, in the same order. Empty in the first round. | |
state.my_score | 11 | Your points in this match. |
state.their_score | 16 | Their points in this match. |
state.random | random.Random | Your own random number generator. Use state.random.random(), .randint(a, b) or .choice(seq). It's seeded, so a match can be replayed exactly. |
state.memory | {} | A dictionary for anything you want to remember. It starts empty in every match and lasts until the match ends. |
Points each round: both cooperate 3 each, both defect 1 each, and a defector against a cooperator gets 5 while the cooperator gets 0.
Rules for code
- Python 3 only. Define a function called
movethat takesstateand returns"C"or"D". Anything else, or an error, and the entry can't play. - You can write other functions and module-level constants. Your file runs fresh at the start of every match, so nothing carries over between matches.
- The only import allowed is
math. For randomness, usestate.random. - Your code runs in a sandbox. It can use plain Python (numbers, strings, lists, tuples, dicts, sets, loops, functions,
try) and common built-ins likelen,sum,min,max,range,sortedandabs. It can't define classes, use names that start with__, assign to attributes (likemath.pi = 3; keep your own data instate.memory), read files, use the network, or look at other strategies. - Keep it quick. Every entry plays a few hundred thousand rounds, so a move should take well under a millisecond.
- Up to 20,000 characters. Your code stays private: it's never shown on the site, only your strategy name and the short description you choose.
- We read every entry before it plays. If your code breaks a rule or crashes, we fix an obvious typo or turn it down, and your status page tells you why.
Examples
Hold a grudge, using memory
def move(state):
# Cooperate until they defect twice in a row, then never again.
if state.their_moves[-2:] == ("D", "D"):
state.memory["angry"] = True
return "D" if state.memory.get("angry") else "C"
Forgive sometimes, using randomness
def move(state):
# Tit for Tat, but forgive a defection one time in ten.
if not state.their_moves or state.their_moves[-1] == "C":
return "C"
return "C" if state.random.random() < 0.1 else "D"
Watch the whole match, using math
import math
def move(state):
# Defect if they've defected more than the square root of the rounds played.
n = state.their_moves.count("D")
return "D" if n > math.sqrt(state.round + 1) else "C"
Test it, then enter
On the entry form, choose Python and paste your code. Test my code runs it in your browser against a few simple players and shows the scores, or the line that broke a rule. Nothing is sent until you press Submit.
Enter with Python