Skip to content

Commit

Permalink
Merge pull request #1030 from FakeNameSE/master
Browse files Browse the repository at this point in the history
Add a new DynamicTwoTitsForTat strategy
  • Loading branch information
meatballs authored May 30, 2017
2 parents b43c81c + 1971111 commit 9edd676
Show file tree
Hide file tree
Showing 4 changed files with 71 additions and 3 deletions.
3 changes: 2 additions & 1 deletion axelrod/strategies/_strategies.py
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@
TitForTat, TitFor2Tats, TwoTitsForTat, Bully, SneakyTitForTat,
SuspiciousTitForTat, AntiTitForTat, HardTitForTat, HardTitFor2Tats,
OmegaTFT, Gradual, ContriteTitForTat, SlowTitForTwoTats, AdaptiveTitForTat,
SpitefulTitForTat, SlowTitForTwoTats2, Alexei, EugineNier)
SpitefulTitForTat, SlowTitForTwoTats2, Alexei, EugineNier, DynamicTwoTitsForTat)
from .verybad import VeryBad
from .worse_and_worse import (WorseAndWorse, KnowledgeableWorseAndWorse,
WorseAndWorse2, WorseAndWorse3)
Expand Down Expand Up @@ -263,4 +263,5 @@
ZDGen2,
ZDSet2,
e,
DynamicTwoTitsForTat,
]
36 changes: 36 additions & 0 deletions axelrod/strategies/titfortat.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
from axelrod.actions import Actions, Action
from axelrod.player import Player
from axelrod.strategy_transformers import TrackHistoryTransformer, FinalTransformer
from axelrod.random_ import random_choice

C, D = Actions.C, Actions.D

Expand Down Expand Up @@ -92,6 +93,41 @@ class TwoTitsForTat(Player):
def strategy(opponent: Player) -> Action:
return D if D in opponent.history[-2:] else C

class DynamicTwoTitsForTat(Player):
"""
A player starts by cooperating and then punishes its opponent's
defections with defections, but with a dynamic bias towards cooperating
based on the opponent's ratio of cooperations to total moves
(so their current probability of cooperating regardless of the
opponent's move (aka: forgiveness)).
Names:
- Dynamic Two Tits For Tat: Original name by Grant Garrett-Grossman.
"""

name = 'Dynamic Two Tits For Tat'
classifier = {
'memory_depth': 2, # Long memory, memory-2
'stochastic': True,
'makes_use_of': set(),
'long_run_time': False,
'inspects_source': False,
'manipulates_source': False,
'manipulates_state': False
}

@staticmethod
def strategy(opponent):
# First move
if not opponent.history:
# Make sure we cooporate first turn
return C
if D in opponent.history[-2:]:
# Probability of cooperating regardless
return random_choice(opponent.cooperations / len(opponent.history))
else:
return C

class Bully(Player):
"""A player that behaves opposite to Tit For Tat, including first move.
Expand Down
31 changes: 31 additions & 0 deletions axelrod/tests/strategies/test_titfortat.py
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,37 @@ def test_strategy(self):
self.versus_test(opponent, expected_actions=actions)


class TestDynamicTwoTitsForTat(TestPlayer):

name = 'Dynamic Two Tits For Tat'
player = axelrod.DynamicTwoTitsForTat
expected_classifier = {
'memory_depth': 2,
'stochastic': True,
'makes_use_of': set(),
'inspects_source': False,
'manipulates_source': False,
'manipulates_state': False
}

def test_strategy(self):
# First move is to cooperate
self.first_play_test(C)
# Test that it is stochastic
opponent = axelrod.MockPlayer(actions=[D, C, D, D, C])
actions = [(C, D), (D, C), (C, D), (D, D), (D, C)]
self.versus_test(opponent, expected_actions=actions, seed=1)
# Should respond differently with a different seed
actions = [(C, D), (D, C), (D, D), (D, D), (C, C)]
self.versus_test(opponent, expected_actions=actions, seed=2)

# Will cooperate if opponent cooperates.
actions = [(C, C), (C, C), (C, C), (C, C), (C, C)]
self.versus_test(axelrod.Cooperator(), expected_actions=actions)
# Test against defector
actions = [(C, D), (D, D), (D, D), (D, D), (D, D)]
self.versus_test(axelrod.Defector(), expected_actions=actions)

class TestBully(TestPlayer):

name = "Bully"
Expand Down
4 changes: 2 additions & 2 deletions docs/tutorials/advanced/classification_of_strategies.rst
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ strategies::
... }
>>> strategies = axl.filtered_strategies(filterset)
>>> len(strategies)
66
67

Or, to find out how many strategies only use 1 turn worth of memory to
make a decision::
Expand All @@ -69,7 +69,7 @@ range of memory_depth values, we can use the 'min_memory_depth' and
... }
>>> strategies = axl.filtered_strategies(filterset)
>>> len(strategies)
49
50

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

0 comments on commit 9edd676

Please sign in to comment.