Skip to content

Commit df150d3

Browse files
yohmmarcharper
authored andcommitted
added test cases for CAPRI
1 parent 8de17ab commit df150d3

File tree

3 files changed

+134
-0
lines changed

3 files changed

+134
-0
lines changed

axelrod/strategies/_strategies.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,7 @@
143143
OppositeGrudger,
144144
SoftGrudger,
145145
SpitefulCC,
146+
CAPRI,
146147
)
147148
from .grumpy import Grumpy
148149
from .handshake import Handshake

axelrod/strategies/grudger.py

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -342,3 +342,70 @@ def strategy(opponent: Player) -> Action:
342342
elif opponent.defections:
343343
return D
344344
return C
345+
346+
347+
class CAPRI(Player):
348+
"""
349+
CAPRI is a strategy whose behavior is defined by the following five rules.
350+
C: Cooperate at mutual cooperation
351+
A: Accept punishmentl
352+
P: Punish
353+
R: Recover
354+
I: In all ohter cases, defect.
355+
356+
Names:
357+
358+
- CAPRI: Original Name by Y. Murase et al. [Murase 2020]
359+
"""
360+
361+
name = "CAPRI"
362+
classifier = {
363+
"memory_depth": 3,
364+
"stochastic": False,
365+
"long_run_time": False,
366+
"inspects_source": False,
367+
"manipulates_source": False,
368+
"manipulates_state": False,
369+
}
370+
371+
def strategy(self, opponent: Player) -> Action:
372+
hist = [[C,C],[C,C],[C,C]]
373+
for i in range(min(len(self.history), 3)):
374+
hist[-i-1][0] = self.history[-i-1]
375+
hist[-i-1][1] = opponent.history[-i-1]
376+
377+
if hist == [[C,C],[C,C],[C,C]]: # Rule: C
378+
return C
379+
elif hist == [[C,C],[C,C],[D,C]]: # Rule: A
380+
return C
381+
elif hist == [[C,C],[D,C],[C,D]]:
382+
return C
383+
elif hist == [[D,C],[C,D],[C,C]]:
384+
return C
385+
elif hist == [[C,D],[C,C],[C,C]]:
386+
return C
387+
elif hist == [[C,C],[C,C],[C,D]]: # Rule: P
388+
return D
389+
elif hist == [[C,C],[C,D],[D,C]]:
390+
return C
391+
elif hist == [[C,D],[D,C],[C,C]]:
392+
return C
393+
elif hist == [[D,C],[C,C],[C,C]]:
394+
return C
395+
elif hist == [[D,D],[D,D],[D,C]]: # Rule: R1
396+
return C
397+
elif hist == [[D,D],[D,C],[C,C]]:
398+
return C
399+
elif hist == [[D,C],[C,C],[C,C]]:
400+
return C
401+
elif hist == [[D,D],[D,D],[C,D]]: # Rule: R2
402+
return C
403+
elif hist == [[D,D],[C,D],[C,C]]:
404+
return C
405+
elif hist == [[C,D],[C,C],[C,C]]:
406+
return C
407+
elif hist == [[D,D],[D,D],[C,C]]: # Rule: R3
408+
return C
409+
elif hist == [[D,D],[C,C],[C,C]]:
410+
return C
411+
return D

axelrod/tests/strategies/test_grudger.py

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -336,3 +336,69 @@ def test_strategy(self):
336336
opponent = axl.MockPlayer(actions=opponent_actions)
337337
actions = [(C, D)] * 2 + [(D, D)] * 18 + [(D, C)] * 20
338338
self.versus_test(opponent, expected_actions=actions)
339+
340+
341+
class TestCAPRI(TestPlayer):
342+
343+
name = "CAPRI"
344+
player = axl.CAPRI
345+
expected_classifier = {
346+
"memory_depth": 3,
347+
"stochastic": False,
348+
"makes_use_of": set(),
349+
"long_run_time": False,
350+
"inspects_source": False,
351+
"manipulates_source": False,
352+
"manipulates_state": False,
353+
}
354+
355+
def assert_prescription(self, player_history, opponent_history, prescription):
356+
player = self.player()
357+
player._history = player_history
358+
opponent = axl.MockPlayer()
359+
opponent._history = opponent_history
360+
self.assertEqual(player.strategy(opponent=opponent), prescription)
361+
362+
def test_strategy(self):
363+
# cooperate at mutual cooperation
364+
opponent = axl.Cooperator()
365+
actions = [(C, C)] * 20
366+
self.versus_test(opponent, expected_actions=actions)
367+
368+
# defect against defectors
369+
opponent = axl.Defector()
370+
actions = [(C, D)] + [(D, D)] * 20
371+
self.versus_test(opponent, expected_actions=actions)
372+
373+
# punishment co-players for his/her mistake
374+
opponent_actions = [C] * 10 + [D] + [C] * 10
375+
opponent = axl.MockPlayer(actions=opponent_actions)
376+
actions = [(C, C)] * 10 + [(C, D)] + [(D, C)] + [(C,C)] * 9
377+
self.versus_test(opponent, expected_actions=actions)
378+
379+
# never allow the defection more than once
380+
opponent_actions = [C] * 10 + [D] * 2 + [C] * 10
381+
opponent = axl.MockPlayer(actions=opponent_actions)
382+
actions = [(C, C)] * 10 + [(C, D)] + [(D, D)] + [(D,C)] * 9
383+
self.versus_test(opponent, expected_actions=actions)
384+
385+
# accept punishment when making a mistake
386+
self.assert_prescription([C,C,D], [C,C,C], C)
387+
self.assert_prescription([C,D,C], [C,C,D], C)
388+
self.assert_prescription([D,C,C], [C,D,C], C)
389+
self.assert_prescription([C,C,C], [D,C,C], C)
390+
391+
# recover the cooperation
392+
self.assert_prescription([D,D,C], [D,D,D], C)
393+
self.assert_prescription([D,C,C], [D,D,C], C)
394+
395+
self.assert_prescription([D,D,D], [D,D,C], C)
396+
self.assert_prescription([D,D,C], [D,C,C], C)
397+
self.assert_prescription([D,C,C], [C,C,C], C)
398+
399+
self.assert_prescription([D,D,C], [D,D,C], C)
400+
self.assert_prescription([D,C,C], [D,C,C], C)
401+
402+
# in other cases, defect
403+
self.assert_prescription([D,C,C], [D,D,D], D)
404+
self.assert_prescription([C,D,C], [C,C,C], D)

0 commit comments

Comments
 (0)