Skip to content

Commit cc60038

Browse files
committed
Added a new DynamicTwoTitsForTat strategy which modifies the preexisting TwoTitsForTat stategy by adding a probability of forgiveness based off of the ratio of the opponent's cooperations to total moves (so their rough probability of cooperation).
Signed-off-by: FakeNameSE <grantlycee@gmail.com>
1 parent b43c81c commit cc60038

File tree

4 files changed

+66
-2
lines changed

4 files changed

+66
-2
lines changed

axelrod/strategies/_strategies.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@
7676
TitForTat, TitFor2Tats, TwoTitsForTat, Bully, SneakyTitForTat,
7777
SuspiciousTitForTat, AntiTitForTat, HardTitForTat, HardTitFor2Tats,
7878
OmegaTFT, Gradual, ContriteTitForTat, SlowTitForTwoTats, AdaptiveTitForTat,
79-
SpitefulTitForTat, SlowTitForTwoTats2, Alexei, EugineNier)
79+
SpitefulTitForTat, SlowTitForTwoTats2, Alexei, EugineNier, DynamicTwoTitsForTat)
8080
from .verybad import VeryBad
8181
from .worse_and_worse import (WorseAndWorse, KnowledgeableWorseAndWorse,
8282
WorseAndWorse2, WorseAndWorse3)
@@ -263,4 +263,5 @@
263263
ZDGen2,
264264
ZDSet2,
265265
e,
266+
DynamicTwoTitsForTat,
266267
]

axelrod/strategies/titfortat.py

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
from axelrod.actions import Actions, Action
22
from axelrod.player import Player
33
from axelrod.strategy_transformers import TrackHistoryTransformer, FinalTransformer
4+
from axelrod.random_ import random_choice
5+
import random
46

57
C, D = Actions.C, Actions.D
68

@@ -92,6 +94,39 @@ class TwoTitsForTat(Player):
9294
def strategy(opponent: Player) -> Action:
9395
return D if D in opponent.history[-2:] else C
9496

97+
class DynamicTwoTitsForTat(Player):
98+
"""A player starts by cooperating and then mimics previous move by
99+
opponent with a dynamic bias based off of the opponents ratio of
100+
cooperations to total moves (so their current probability of
101+
cooperating towards cooporating regardless of the move
102+
(aka: forgiveness)."""
103+
104+
name = 'Dynamic Two Tits For Tat'
105+
classifier = {
106+
'memory_depth': 2, # Long memory, memory-2
107+
'stochastic': False,
108+
'makes_use_of': set(),
109+
'long_run_time': False,
110+
'inspects_source': False,
111+
'manipulates_source': False,
112+
'manipulates_state': False
113+
}
114+
115+
@staticmethod
116+
def strategy(opponent):
117+
# First move
118+
if len(opponent.history) == 0:
119+
# Make sure we cooporate first turn
120+
return C
121+
if D in opponent.history[-2:]:
122+
# Probability of turning the other cheek based off of
123+
# opponent's probability of defection
124+
if random.random() < (opponent.cooperations / len(opponent.history)):
125+
return C
126+
else:
127+
return D
128+
else:
129+
return C
95130

96131
class Bully(Player):
97132
"""A player that behaves opposite to Tit For Tat, including first move.

axelrod/tests/strategies/test_titfortat.py

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,34 @@ def test_strategy(self):
114114
self.versus_test(opponent, expected_actions=actions)
115115

116116

117+
class TestDynamicTwoTitsForTat(TestPlayer):
118+
119+
name = 'Dynamic Two Tits For Tat'
120+
player = axelrod.DynamicTwoTitsForTat
121+
expected_classifier = {
122+
'memory_depth': 2,
123+
'stochastic': False,
124+
'makes_use_of': set(),
125+
'inspects_source': False,
126+
'manipulates_source': False,
127+
'manipulates_state': False
128+
}
129+
130+
def test_strategy(self):
131+
self.first_play_test(C)
132+
self.second_play_test(rCC=C, rCD=D, rDC=C, rDD=D)
133+
134+
# Will cooperate if opponent cooperates/.
135+
actions = [(C, C), (C, C), (C, C), (C, C), (C, C)]
136+
self.versus_test(axelrod.Cooperator(), expected_actions=actions)
137+
# Will defect twice when last turn of opponent was defection.
138+
opponent = axelrod.MockPlayer(actions=[D, C, C, D, C])
139+
actions = [(C, D), (D, C), (D, C), (C, D), (D, C)]
140+
self.versus_test(opponent, expected_actions=actions)
141+
# Test against defector
142+
actions = [(C, D), (D, D), (D, D), (D, D), (D, D)]
143+
self.versus_test(axelrod.Defector(), expected_actions=actions)
144+
117145
class TestBully(TestPlayer):
118146

119147
name = "Bully"

docs/tutorials/advanced/classification_of_strategies.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ range of memory_depth values, we can use the 'min_memory_depth' and
6969
... }
7070
>>> strategies = axl.filtered_strategies(filterset)
7171
>>> len(strategies)
72-
49
72+
50
7373

7474
We can also identify strategies that make use of particular properties of the
7575
tournament. For example, here is the number of strategies that make use of the

0 commit comments

Comments
 (0)