Skip to content

Commit 32baad1

Browse files
Merge pull request #686 from Axelrod-Python/mutual
Added strategies Desperate, Willing, Hopeless, Grim
2 parents efcaa2e + c543312 commit 32baad1

File tree

4 files changed

+177
-7
lines changed

4 files changed

+177
-7
lines changed

axelrod/strategies/_strategies.py

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@
4343
ZDGen2, ZDGTFT2, ZDSet2, WinStayLoseShift, WinShiftLoseStay)
4444
from .mindcontrol import MindController, MindWarper, MindBender
4545
from .mindreader import MindReader, ProtectedMindReader, MirrorMindReader
46+
from .mutual import Desperate, Hopeless, Willing
4647
from .oncebitten import OnceBitten, FoolMeOnce, ForgetfulFoolMeOnce, FoolMeForever
4748
from .prober import (Prober, Prober2, Prober3, HardProber,
4849
NaiveProber, RemorsefulProber)
@@ -92,6 +93,7 @@
9293
Davis,
9394
Defector,
9495
DefectorHunter,
96+
Desperate,
9597
DoubleCrosser,
9698
Eatherley,
9799
EventualCycleHunter,
@@ -115,21 +117,22 @@
115117
GoByMajority20,
116118
GoByMajority40,
117119
GoByMajority5,
120+
Golden,
121+
Gradual,
122+
Grofman,
123+
Grudger,
124+
Grumpy,
118125
Handshake,
119126
HardGoByMajority,
120127
HardGoByMajority10,
121128
HardGoByMajority20,
122129
HardGoByMajority40,
123130
HardGoByMajority5,
124-
Golden,
125-
Gradual,
126-
Grofman,
127-
Grudger,
128-
Grumpy,
129131
HardProber,
130132
HardTitFor2Tats,
131133
HardTitForTat,
132134
HesitantQLearner,
135+
Hopeless,
133136
Inverse,
134137
InversePunisher,
135138
Joss,
@@ -184,6 +187,7 @@
184187
TrickyDefector,
185188
Tullock,
186189
TwoTitsForTat,
190+
Willing,
187191
WinShiftLoseStay,
188192
WinStayLoseShift,
189193
ZDExtort2,

axelrod/strategies/mutual.py

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
from axelrod import Actions, Player, init_args
2+
from axelrod.random_ import random_choice
3+
4+
C, D = Actions.C, Actions.D
5+
6+
7+
class Desperate(Player):
8+
"""A player that only cooperates after mutual defection.
9+
10+
Names:
11+
12+
- Desperate: [Berg2015]_"""
13+
14+
name = "Desperate"
15+
classifier = {
16+
'memory_depth': 1,
17+
'long_run_time': False,
18+
'stochastic': True,
19+
'makes_use_of': set(),
20+
'inspects_source': False,
21+
'manipulates_source': False,
22+
'manipulates_state': False
23+
}
24+
25+
def strategy(self, opponent):
26+
if not opponent.history:
27+
return random_choice()
28+
if self.history[-1] == D and opponent.history[-1] == D:
29+
return C
30+
return D
31+
32+
33+
class Hopeless(Player):
34+
"""A player that only defects after mutual cooperation.
35+
36+
Names:
37+
38+
- Hopeless: [Berg2015]_"""
39+
40+
name = "Hopeless"
41+
classifier = {
42+
'memory_depth': 1,
43+
'long_run_time': False,
44+
'stochastic': True,
45+
'makes_use_of': set(),
46+
'inspects_source': False,
47+
'manipulates_source': False,
48+
'manipulates_state': False
49+
}
50+
51+
def strategy(self, opponent):
52+
if not opponent.history:
53+
return random_choice()
54+
if self.history[-1] == C and opponent.history[-1] == C:
55+
return D
56+
return C
57+
58+
59+
class Willing(Player):
60+
"""A player that only defects after mutual defection.
61+
62+
Names:
63+
64+
- Willing: [Berg2015]_"""
65+
66+
name = "Willing"
67+
classifier = {
68+
'memory_depth': 1,
69+
'long_run_time': False,
70+
'stochastic': True,
71+
'makes_use_of': set(),
72+
'inspects_source': False,
73+
'manipulates_source': False,
74+
'manipulates_state': False
75+
}
76+
77+
def strategy(self, opponent):
78+
if not opponent.history:
79+
return random_choice()
80+
if self.history[-1] == D and opponent.history[-1] == D:
81+
return D
82+
return C

axelrod/tests/unit/test_mutual.py

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
"""Tests for strategies Desperate, Hopeless, Willing, and Grim"""
2+
import axelrod
3+
4+
from axelrod.random_ import seed
5+
6+
from .test_player import TestPlayer
7+
8+
C, D = axelrod.Actions.C, axelrod.Actions.D
9+
10+
class TestDesperate(TestPlayer):
11+
12+
name = "Desperate"
13+
player = axelrod.Desperate
14+
expected_classifier = {
15+
'memory_depth': 1,
16+
'long_run_time': False,
17+
'stochastic': True,
18+
'makes_use_of': set(),
19+
'inspects_source': False,
20+
'manipulates_source': False,
21+
'manipulates_state': False
22+
}
23+
24+
def test_strategy(self):
25+
seed(1)
26+
self.first_play_test(C)
27+
seed(2)
28+
self.first_play_test(D)
29+
30+
def test_responses(self):
31+
self.responses_test([C] * 4, [D] * 4, [D])
32+
self.responses_test([D, D, C], [C, C, D], [D])
33+
self.responses_test([D, D, D], [C, C, D], [C])
34+
35+
36+
class TestHopeless(TestPlayer):
37+
38+
name = "Hopeless"
39+
player = axelrod.Hopeless
40+
expected_classifier = {
41+
'memory_depth': 1,
42+
'long_run_time': False,
43+
'stochastic': True,
44+
'makes_use_of': set(),
45+
'inspects_source': False,
46+
'manipulates_source': False,
47+
'manipulates_state': False
48+
}
49+
50+
def test_strategy(self):
51+
seed(1)
52+
self.first_play_test(C)
53+
seed(2)
54+
self.first_play_test(D)
55+
56+
def test_responses(self):
57+
self.responses_test([C] * 4, [D] * 4, [C])
58+
self.responses_test([D] * 5, [C] * 5, [C])
59+
self.responses_test([C, D, C], [C, C, C], [D])
60+
61+
class TestWilling(TestPlayer):
62+
63+
name = "Willing"
64+
player = axelrod.Willing
65+
expected_classifier = {
66+
'memory_depth': 1,
67+
'long_run_time': False,
68+
'stochastic': True,
69+
'makes_use_of': set(),
70+
'inspects_source': False,
71+
'manipulates_source': False,
72+
'manipulates_state': False
73+
}
74+
75+
def test_strategy(self):
76+
seed(1)
77+
self.first_play_test(C)
78+
seed(2)
79+
self.first_play_test(D)
80+
81+
def test_responses(self):
82+
self.responses_test([C] * 4, [D] * 4, [C])
83+
self.responses_test([D] * 5, [C] * 5, [C])
84+
self.responses_test([C, C, D], [C, C, D], [D])

docs/tutorials/advanced/classification_of_strategies.rst

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,13 +24,13 @@ This allows us to, for example, quickly identify all the stochastic
2424
strategies::
2525

2626
>>> len([s for s in axl.strategies if s().classifier['stochastic']])
27-
40
27+
43
2828

2929
Or indeed find out how many strategy only use 1 turn worth of memory to
3030
make a decision::
3131

3232
>>> len([s for s in axl.strategies if s().classifier['memory_depth']==1])
33-
21
33+
24
3434

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

0 commit comments

Comments
 (0)