-
Notifications
You must be signed in to change notification settings - Fork 264
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
Implement SpitefulTitForTat strategy from PRISON #749
Changes from 7 commits
b178c34
ac2ffe1
592535b
ae52591
9f19671
d1014a2
99ab8f2
27d02b2
71492a6
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 |
---|---|---|
|
@@ -34,7 +34,7 @@ class TitForTat(Player): | |
def strategy(self, opponent): | ||
"""This is the actual strategy""" | ||
# First move | ||
if len(self.history) == 0: | ||
if not self.history: | ||
return C | ||
# React to the opponent's last move | ||
if opponent.history[-1] == D: | ||
|
@@ -295,7 +295,7 @@ def __init__(self, deadlock_threshold=3, randomness_threshold=8): | |
|
||
def strategy(self, opponent): | ||
# Cooperate on the first move | ||
if len(self.history) == 0: | ||
if not self.history: | ||
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. 👍 Again |
||
return C | ||
# TFT on round 2 | ||
if len(self.history) == 1: | ||
|
@@ -554,3 +554,50 @@ def reset(self): | |
def __repr__(self): | ||
|
||
return "%s: %s" % (self.name, round(self.rate, 2)) | ||
|
||
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. PEP8 - Should be two blank lines before a class definition |
||
class SpitefulTitForTat(Player): | ||
""" | ||
A player starts by cooperating and then mimics the previous action of the | ||
opponent until opponent defects twice in a row, at which point player always defects | ||
|
||
Names: | ||
|
||
- Spiteful Tit For Tat [PRISON1998]_ | ||
""" | ||
|
||
name = 'Spiteful Tit For Tat' | ||
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 __init__(self): | ||
Player.__init__(self) | ||
self.retaliating = False | ||
|
||
def strategy(self, opponent): | ||
# First move | ||
if not self.history: | ||
return C | ||
|
||
if opponent.history[-2:] == [D,D]: | ||
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. PEP8: |
||
self.retaliating=True | ||
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. Could we have some space around the '=' (PEP8)? 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. PEP8: |
||
|
||
if self.retaliating: | ||
return D | ||
else: | ||
# React to the opponent's last move | ||
if opponent.history[-1] == D: | ||
return D | ||
return C | ||
|
||
def reset(self): | ||
Player.reset(self) | ||
self.retaliating = False | ||
|
||
|
||
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. PEP8: Should be one blank line at the end of file, not two. |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -497,4 +497,32 @@ def test_world_rate_reset(self): | |
self.assertEqual(p2.rate, 0.5) | ||
|
||
|
||
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. There are whitespace characters in these two lines that shouldn't be there. |
||
class TestSpitefulTitForTat(TestPlayer): | ||
name = "Spiteful Tit For Tat" | ||
player = axelrod.SpitefulTitForTat | ||
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 cooperating.""" | ||
self.first_play_test(C) | ||
|
||
def test_effect_of_strategy(self): | ||
"""Repeats last action of opponent history until 2 consecutive defections, then always defects""" | ||
self.markov_test([C, D, C, D]) | ||
self.responses_test([C] * 4, [C, C, C, C], [C], attrs = {"retaliating": False}) | ||
self.responses_test([C] * 5, [C, C, C, C, D], [D], attrs = {"retaliating": False}) | ||
self.responses_test([C] * 5, [C, C, D, D, C], [D], attrs = {"retaliating": True}) | ||
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. PEP8 The three lines above have spaces around the '=' which shouldn't be there. |
||
|
||
def test_reset_retaliating(self): | ||
player = self.player() | ||
player.retaliating = True | ||
player.reset() | ||
self.assertFalse(player.retaliating) | ||
|
||
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. There is an extra blank line at the end of the file which shouldn't be there |
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.
👍 Thanks for spotting that one!