Writing the new strategy¶
Identify a new strategy¶
If you’re not sure if you have a strategy that has already been implemented, you can search the Strategy index to see if they are implemented. If you are still unsure please get in touch: via the gitter room or open an issue.
Several strategies are special cases of other strategies. For example, both
Cooperator
and Defector
are special cases of Random
,
Random(1)
and Random(0)
respectively. While we could eliminate
Cooperator
in its current
form, these strategies are intentionally left as is as simple examples for new
users and contributors. Nevertheless, please feel free to update the docstrings
of strategies like Random
to point out such cases.
The code¶
There are a couple of things that need to be created in a strategy.py file. Let
us take a look at the TitForTat
class (located in the
axelrod/strategies/titfortat.py
file):
class TitForTat(Player):
"""
A player starts by cooperating and then mimics previous move by
opponent.
Note that the code for this strategy is written in a fairly verbose
way. This is done so that it can serve as an example strategy for
those who might be new to Python.
Names
- Rapoport's strategy: [Axelrod1980]_
- TitForTat: [Axelrod1980]_
"""
# These are various properties for the strategy
name = 'Tit For Tat'
classifier = {
'memory_depth': 1, # Four-Vector = (1.,0.,1.,0.)
'stochastic': False,
'inspects_source': False,
'manipulates_source': False,
'manipulates_state': False
}
def strategy(self, opponent):
"""This is the actual strategy"""
# First move
if len(self.history) == 0:
return C
# React to the opponent's last move
if opponent.history[-1] == D:
return D
return C
The first thing that is needed is a docstring that explains what the strategy does:
"""A player starts by cooperating and then mimics previous move by opponent."""
Secondly, any alternate names should be included and if possible references provided (this helps when trying to identify if a strategy has already been implemented or not):
- Rapoport's strategy: [Axelrod1980]_
- TitForTat: [Axelrod1980]_
These references can be found in the Bibliography. If a required references is not there please feel free to add it or just get in touch and we’d be happy to help.
After that simply add in the string that will appear as the name of the strategy:
name = 'Tit For Tat'
Note that this is mainly used in plots by matplotlib
so you can use
LaTeX if you want to. For example there is strategy with \(\pi\) as a
name:
name = '$\pi$'
Following that you can add in the classifier
dictionary:
classifier = {
'memory_depth': 1, # Four-Vector = (1.,0.,1.,0.)
'stochastic': False,
'inspects_source': False,
'manipulates_source': False,
'manipulates_state': False
}
This helps classify the strategy as described in Classification of strategies.
After that the only thing required is to write the strategy
method
which takes an opponent as an argument. In the case of
TitForTat
the
strategy checks if it has any history (if len(self.history) == 0
). If
it does not (ie this is the first play of the match) then it returns C
.
If not, the strategy simply repeats the opponent’s last move (return
opponent.history[-1]
):
def strategy(opponent):
"""This is the actual strategy"""
# First move
if len(self.history) == 0:
return C
# Repeat the opponent's last move
return opponent.history[-1]
The variables C
and D
represent the cooperate and defect actions
respectively.
Some strategies make specific use of the variables of a match to create their
own attributes. In principle these attributes could change throughout a match
or tournament if the match properties (like the game matrix) change, so we
require that this logic live in the receive_match_attributes
method for
correct dynamic updating. Here is how this is done for Stalker
:
def receive_match_attributes(self)
R, P, S, T = self.match_attributes["game"].RPST()
self.very_good_score = R
self.very_bad_score = P
self.wish_score = (R + P) / 2
There are various examples of helpful functions and properties that make writing strategies easier. Do not hesitate to get in touch with the Axelrod-Python team for guidance.