-
Notifications
You must be signed in to change notification settings - Fork 267
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
3 New Strategies From the PRISON (http://www.lifl.fr/IPD/ipd.frame.html) #715
Changes from all commits
fd868be
00da984
a1f8534
32c228c
8f64b6a
7587d7a
00d7ea4
9ff5a9d
3b3730b
074b537
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
from axelrod import Actions, Player, init_args | ||
from axelrod.strategy_transformers import InitialTransformer | ||
|
||
C, D = Actions.C, Actions.D | ||
|
||
@InitialTransformer((D, D, D, D, D, C, C), name_prefix=None) | ||
class GradualKiller(Player): | ||
""" | ||
It begins by defecting in the first five moves, then cooperates two times. | ||
It then defects all the time if the opponent has defected in move 6 and 7, | ||
else cooperates all the time. | ||
Initially designed to stop Gradual from defeating TitForTat in a 3 Player | ||
tournament. | ||
|
||
Names | ||
|
||
- Gradual Killer: [PRISON1998]_ | ||
""" | ||
|
||
# These are various properties for the strategy | ||
name = 'Gradual Killer' | ||
classifier = { | ||
'memory_depth': float('Inf'), | ||
'stochastic': False, | ||
'makes_use_of': set(), | ||
'long_run_time': False, | ||
'inspects_source': False, | ||
'manipulates_source': False, | ||
'manipulates_state': False | ||
} | ||
|
||
def strategy(self, opponent): | ||
if opponent.history[5:7] == [D, D]: | ||
return D | ||
return C |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -171,3 +171,63 @@ def reset(self): | |
Player.reset(self) | ||
self.grudged = False | ||
self.grudge_memory = 0 | ||
|
||
|
||
|
||
class GrudgerAlternator(Player): | ||
""" | ||
A player starts by cooperating until the first opponents defection, | ||
then alternates D-C. | ||
|
||
Names: | ||
|
||
- c_then_per_dc: [PRISON1998]_ | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can you also add |
||
- Grudger Alternator: Original name by Geraint Palmer | ||
""" | ||
|
||
name = 'GrudgerAlternator' | ||
classifier = { | ||
'memory_depth': float('inf'), # Long memory | ||
'stochastic': False, | ||
'makes_use_of': set(), | ||
'long_run_time': False, | ||
'inspects_source': False, | ||
'manipulates_source': False, | ||
'manipulates_state': False | ||
} | ||
|
||
def strategy(self, opponent): | ||
"""Begins by playing C, then plays Alternator for the remaining rounds if the opponent ever plays D.""" | ||
if opponent.defections: | ||
if self.history[-1] == Actions.C: | ||
return Actions.D | ||
return Actions.C | ||
|
||
|
||
|
||
class EasyGo(Player): | ||
""" | ||
A player starts by defecting however will cooperate if at any point the opponent has defected. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. if the opponent There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ignore this. |
||
|
||
Names: | ||
|
||
- Easy Go [PRISON1998]_ | ||
""" | ||
|
||
name = 'EasyGo' | ||
classifier = { | ||
'memory_depth': float('inf'), # Long memory | ||
'stochastic': False, | ||
'makes_use_of': set(), | ||
'long_run_time': False, | ||
'inspects_source': False, | ||
'manipulates_source': False, | ||
'manipulates_state': False | ||
} | ||
|
||
@staticmethod | ||
def strategy(opponent): | ||
"""Begins by playing D, then plays C for the remaining rounds if the opponent ever plays D.""" | ||
if opponent.defections: | ||
return C | ||
return D |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,104 @@ | ||
"""Test for the gradual killer strategy.""" | ||
|
||
import axelrod | ||
from .test_player import TestHeadsUp, TestPlayer | ||
|
||
from hypothesis import given | ||
from hypothesis.strategies import integers | ||
from axelrod.tests.property import strategy_lists | ||
|
||
import random | ||
|
||
C, D = axelrod.Actions.C, axelrod.Actions.D | ||
|
||
|
||
class TestGradualKiller(TestPlayer): | ||
|
||
name = "Gradual Killer" | ||
player = axelrod.GradualKiller | ||
expected_classifier = { | ||
'memory_depth': float('Inf'), | ||
'stochastic': False, | ||
'makes_use_of': set(), | ||
'inspects_source': False, | ||
'manipulates_source': False, | ||
'manipulates_state': False | ||
} | ||
|
||
def test_strategy(self): | ||
"""Starts by Defecting.""" | ||
self.first_play_test(D) | ||
|
||
def test_effect_of_strategy(self): | ||
"""Fist seven moves.""" | ||
self.markov_test([D, D, D, D]) | ||
self.responses_test([], [], [D, D, D, D, D, C, C]) | ||
|
||
def test_effect_of_strategy_with_history_CC(self): | ||
"""Continues with C if opponent played CC on 6 and 7.""" | ||
P1 = axelrod.GradualKiller() | ||
P2 = axelrod.Player() | ||
P1.history = [D, D, D, D, D, C, C] | ||
P2.history = [C, C, C, C, C, C, C] | ||
self.assertEqual(P1.strategy(P2), 'C') | ||
P1.history = [D, D, D, D, D, C, C, C] | ||
P2.history = [C, C, C, C, C, C, C, C] | ||
self.assertEqual(P1.strategy(P2), 'C') | ||
P1.history = [D, D, D, D, D, C, C, C, C] | ||
P2.history = [C, C, C, C, C, C, C, C, C] | ||
self.assertEqual(P1.strategy(P2), 'C') | ||
P1.history = [D, D, D, D, D, C, C, C, C, C] | ||
P2.history = [C, C, C, C, C, C, C, C, C, C] | ||
self.assertEqual(P1.strategy(P2), 'C') | ||
|
||
def test_effect_of_strategy_with_history_CD(self): | ||
"""Continues with C if opponent played CD on 6 and 7.""" | ||
P1 = axelrod.GradualKiller() | ||
P2 = axelrod.Player() | ||
P1.history = [D, D, D, D, D, C, C] | ||
P2.history = [C, C, C, C, C, C, D] | ||
self.assertEqual(P1.strategy(P2), 'C') | ||
P1.history = [D, D, D, D, D, C, C, C] | ||
P2.history = [C, C, C, C, C, C, D, D] | ||
self.assertEqual(P1.strategy(P2), 'C') | ||
P1.history = [D, D, D, D, D, C, C, C, C] | ||
P2.history = [C, C, C, C, C, C, D, D, C] | ||
self.assertEqual(P1.strategy(P2), 'C') | ||
P1.history = [D, D, D, D, D, C, C, C, C, C] | ||
P2.history = [C, C, C, C, C, C, D, D, C, C] | ||
self.assertEqual(P1.strategy(P2), 'C') | ||
|
||
def test_effect_of_strategy_with_history_DC(self): | ||
"""Continues with C if opponent played DC on 6 and 7.""" | ||
P1 = axelrod.GradualKiller() | ||
P2 = axelrod.Player() | ||
P1.history = [D, D, D, D, D, C, C] | ||
P2.history = [C, C, C, C, C, D, C] | ||
self.assertEqual(P1.strategy(P2), 'C') | ||
P1.history = [D, D, D, D, D, C, C, C] | ||
P2.history = [C, C, C, C, C, D, C, C] | ||
self.assertEqual(P1.strategy(P2), 'C') | ||
P1.history = [D, D, D, D, D, C, C, C, C] | ||
P2.history = [C, C, C, C, C, D, C, C, D] | ||
self.assertEqual(P1.strategy(P2), 'C') | ||
P1.history = [D, D, D, D, D, C, C, C, C, C] | ||
P2.history = [C, C, C, C, C, D, C, C, D, C] | ||
self.assertEqual(P1.strategy(P2), 'C') | ||
|
||
def test_effect_of_strategy_with_history_CC(self): | ||
"""Continues with D if opponent played DD on 6 and 7.""" | ||
P1 = axelrod.GradualKiller() | ||
P2 = axelrod.Player() | ||
P1.history = [D, D, D, D, D, C, C] | ||
P2.history = [C, C, C, C, C, D, D] | ||
self.assertEqual(P1.strategy(P2), 'D') | ||
P1.history = [D, D, D, D, D, C, C, D] | ||
P2.history = [C, C, C, C, C, D, D, C] | ||
self.assertEqual(P1.strategy(P2), 'D') | ||
P1.history = [D, D, D, D, D, C, C, D, D] | ||
P2.history = [C, C, C, C, C, D, D, C, C] | ||
self.assertEqual(P1.strategy(P2), 'D') | ||
P1.history = [D, D, D, D, D, C, C, D, D, D] | ||
P2.history = [C, C, C, C, C, D, D, C, C, D] | ||
self.assertEqual(P1.strategy(P2), 'D') | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,7 @@ | ||
"""Tests for grudger strategies.""" | ||
|
||
import axelrod | ||
from random import randint | ||
|
||
from .test_player import TestPlayer | ||
|
||
|
@@ -173,3 +174,84 @@ def test_reset(self): | |
p.reset() | ||
self.assertFalse(p.grudged) | ||
self.assertEqual(p.grudge_memory, 0) | ||
|
||
|
||
|
||
class TestGrudgerAlternator(TestPlayer): | ||
|
||
name = "GrudgerAlternator" | ||
player = axelrod.GrudgerAlternator | ||
expected_classifier = { | ||
'memory_depth': float('inf'), # Long memory | ||
'stochastic': False, | ||
'makes_use_of': set(), | ||
'long_run_time': False, | ||
'inspects_source': False, | ||
'manipulates_source': False, | ||
'manipulates_state': False | ||
} | ||
|
||
def test_initial_strategy(self): | ||
""" | ||
Starts by cooperating | ||
""" | ||
self.first_play_test(C) | ||
|
||
def test_strategy(self): | ||
""" | ||
If opponent defects at any point then the player will alternate D-C. | ||
""" | ||
self.responses_test([C, C, C, C, C], [C, C, C, C, C], [C]) | ||
self.responses_test([C, C, C, C, C, C], [C, C, C, C, C, D], [D]) | ||
self.responses_test([C, C, C, C, C, C, D], [C, C, C, C, C, D, D], [C]) | ||
self.responses_test([C, C, C, C, C, C, D, C], [C, C, C, C, C, D, D, C], [D]) | ||
self.responses_test([C, C, C, C, C, C, D, C, D], [C, C, C, C, C, D, D, C, C], [C]) | ||
|
||
def test_starategy_random_number_rounds(self): | ||
""" | ||
Runs test_strategy for a random number of rounds | ||
""" | ||
# Hasn't defected yet | ||
for _ in range(20): | ||
i = randint(1, 30) | ||
j = randint(1, 30) | ||
opp_hist = [C] * i | ||
my_hist = [C] * i | ||
self.responses_test(my_hist, opp_hist, [C]*j) | ||
|
||
# Defected at least once | ||
for _ in range(20): | ||
i = randint(1, 30) | ||
j = randint(1, 30) | ||
opp_hist = [C for r in range(i)] + [D] | ||
my_hist = [C] * (i + 1) | ||
expected_response = [D if r % 2 == 0 else C for r in range(j)] | ||
self.responses_test(my_hist, opp_hist, expected_response) | ||
|
||
|
||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can you get rid of the extra lines? Should be 2. |
||
class TestEasyGo(TestPlayer): | ||
|
||
name = "EasyGo" | ||
player = axelrod.EasyGo | ||
expected_classifier = { | ||
'memory_depth': float('inf'), # Long memory | ||
'stochastic': False, | ||
'makes_use_of': set(), | ||
'long_run_time': False, | ||
'inspects_source': False, | ||
'manipulates_source': False, | ||
'manipulates_state': False | ||
} | ||
|
||
def test_initial_strategy(self): | ||
""" | ||
Starts by cooperating | ||
""" | ||
self.first_play_test(D) | ||
|
||
def test_strategy(self): | ||
""" | ||
If opponent defects at any point then the player will cooperate forever | ||
""" | ||
self.responses_test([C, D, D, D], [C, C, C, C], [D]) | ||
self.responses_test([C, C, D, D, D], [C, D, C, C, C], [C]) |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -18,3 +18,4 @@ documentation. | |
.. [Stewart2012] Stewart, a. J., & Plotkin, J. B. (2012). Extortion and cooperation in the Prisoner’s Dilemma. Proceedings of the National Academy of Sciences, 109(26), 10134–10135. http://doi.org/10.1073/pnas.1208087109 | ||
.. [Szabó1992] Szabó, G., & Fáth, G. (2007). Evolutionary games on graphs. Physics Reports, 446(4-6), 97–216. http://doi.org/10.1016/j.physrep.2007.04.004 | ||
.. [Tzafestas2000] Tzafestas, E. (2000). Toward adaptive cooperative behavior. From Animals to Animals: Proceedings of the 6th International Conference on the Simulation of Adaptive Behavior {(SAB-2000)}, 2, 334–340. | ||
.. [PRISON1998] LIFL (1998) PRISON. Available at: http://www.lifl.fr/IPD/ipd.frame.html (Accessed: 19 September 2016). | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is there no academic reference? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could you add a sentence here saying that this is designed to stop
Gradual
from winning? (And possibly why?)