Skip to content

Commit 0dde6e2

Browse files
committed
Revise Tideman and Cheruzzi.
As noted by @id428 we were not giving a "true" fresh start so I've implemented that. I also added the two final defections (when the game length is known).
1 parent 061e7f2 commit 0dde6e2

File tree

4 files changed

+51
-23
lines changed

4 files changed

+51
-23
lines changed

axelrod/strategies/_strategies.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
RevisedDowning,
1616
FirstByShubik,
1717
FirstBySteinAndRapoport,
18-
TidemanAndChieruzzi,
18+
FirstByTidemanAndChieruzzi,
1919
FirstByTullock,
2020
FirstByAnonymous,
2121
)
@@ -424,7 +424,7 @@
424424
ThueMorse,
425425
ThueMorseInverse,
426426
Thumper,
427-
TidemanAndChieruzzi,
427+
FirstByTidemanAndChieruzzi,
428428
TitForTat,
429429
TitFor2Tats,
430430
SecondByTranquilizer,

axelrod/strategies/axelrod_first.py

Lines changed: 31 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -764,12 +764,26 @@ def strategy(self, opponent: Player) -> Action:
764764
return opponent.history[-1]
765765

766766

767-
# TODO Need to check this one, a MoreTidemanAndChieruzzi existed in
768-
# axelrod_second
769-
class TidemanAndChieruzzi(Player):
767+
@FinalTransformer((D, D), name_prefix=None)
768+
class FirstByTidemanAndChieruzzi(Player):
770769
"""
771-
This strategy begins by playing Tit For Tat and then follows the following
772-
rules:
770+
Submitted to Axelrod's first tournament by Nicolas Tideman and Paula
771+
Chieruzzi.
772+
773+
The description written in [Axelrod1980]_ is:
774+
775+
> "This rule begins with cooperation and tit for tat. However, when the
776+
> other player finishes his second run of defec- tions, an extra punishment is
777+
> instituted, and the number of punishing defections is increased by one with
778+
> each run of the other's defections. The other player is given a fresh start
779+
> if he is 10 or more points behind, if he has not just started a run of
780+
> defections, if it has been at least 20 moves since a fresh start, if there
781+
> are at least 10 moves remaining, and if the number of defections differs
782+
> from a 50-50 random generator by at least 3.0 standard deviations. A fresh
783+
> start involves two cooperations and then play as if the game had just
784+
> started. The program defects automatically on the last two moves."
785+
786+
This is interpreted as:
773787
774788
1. Every run of defections played by the opponent increases the number of
775789
defections that this strategy retaliates with by 1.
@@ -782,8 +796,10 @@ class TidemanAndChieruzzi(Player):
782796
- and the total number of defections differs from a 50-50 random sample
783797
by at least 3.0 standard deviations.
784798
785-
A ‘fresh start’ is a sequence of two cooperations followed by an assumption
786-
that the game has just started (everything is forgotten).
799+
A ‘fresh start’ is a sequence of two cooperations followed by an assumption
800+
that the game has just started (everything is forgotten).
801+
802+
3. The strategy defects on the last two moves.
787803
788804
This strategy came 2nd in Axelrod’s original tournament.
789805
@@ -792,7 +808,7 @@ class TidemanAndChieruzzi(Player):
792808
- TidemanAndChieruzzi: [Axelrod1980]_
793809
"""
794810

795-
name = "Tideman and Chieruzzi"
811+
name = "First tournament by Tideman and Chieruzzi"
796812
classifier = {
797813
"memory_depth": float("inf"),
798814
"stochastic": False,
@@ -812,6 +828,7 @@ def __init__(self) -> None:
812828
self.opponent_score = 0
813829
self.last_fresh_start = 0
814830
self.fresh_start = False
831+
self.remembered_number_of_opponent_defectioons = 0
815832

816833
def _decrease_retaliation_counter(self):
817834
"""Lower the remaining owed retaliation count and flip to non-retaliate
@@ -826,6 +843,7 @@ def _fresh_start(self):
826843
self.is_retaliating = False
827844
self.retaliation_length = 0
828845
self.retaliation_remaining = 0
846+
self.remembered_number_of_opponent_defectioons = 0
829847

830848
def _score_last_round(self, opponent: Player):
831849
"""Updates the scores for each player."""
@@ -840,6 +858,9 @@ def strategy(self, opponent: Player) -> Action:
840858
if not opponent.history:
841859
return C
842860

861+
if opponent.history[-1] == D:
862+
self.remembered_number_of_opponent_defectioons += 1
863+
843864
# Calculate the scores.
844865
self._score_last_round(opponent)
845866

@@ -867,7 +888,8 @@ def strategy(self, opponent: Player) -> Action:
867888
std_deviation = (N ** (1 / 2)) / 2
868889
lower = N / 2 - 3 * std_deviation
869890
upper = N / 2 + 3 * std_deviation
870-
if opponent.defections <= lower or opponent.defections >= upper:
891+
if (self.remembered_number_of_opponent_defectioons <= lower or
892+
self.remembered_number_of_opponent_defectioons >= upper):
871893
# Opponent deserves a fresh start
872894
self.last_fresh_start = current_round
873895
self._fresh_start()

axelrod/tests/strategies/test_axelrod_first.py

Lines changed: 17 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -553,10 +553,10 @@ def test_strategy(self):
553553
)
554554

555555

556-
class TestTidemanAndChieruzzi(TestPlayer):
556+
class TestFirstByTidemanAndChieruzzi(TestPlayer):
557557

558-
name = "Tideman and Chieruzzi"
559-
player = axelrod.TidemanAndChieruzzi
558+
name = "First tournament by Tideman and Chieruzzi: (D, D)"
559+
player = axelrod.FirstByTidemanAndChieruzzi
560560
expected_classifier = {
561561
"memory_depth": float("inf"),
562562
"stochastic": False,
@@ -570,9 +570,15 @@ class TestTidemanAndChieruzzi(TestPlayer):
570570
def test_strategy(self):
571571
# Cooperator Test
572572
opponent = axelrod.Cooperator()
573-
actions = [(C, C), (C, C), (C, C), (C, C)]
573+
actions = [(C, C), (C, C), (D, C), (D, C)]
574574
self.versus_test(opponent, expected_actions=actions)
575575

576+
# Cooperator Test does noot defect if game length is unknown
577+
opponent = axelrod.Cooperator()
578+
actions = [(C, C), (C, C), (C, C), (C, C)]
579+
self.versus_test(opponent, expected_actions=actions,
580+
match_attributes={"length": float("inf")})
581+
576582
# Defector Test
577583
opponent = axelrod.Defector()
578584
actions = [(C, D), (D, D), (D, D), (D, D)]
@@ -589,7 +595,7 @@ def test_strategy(self):
589595
(D, C),
590596
(D, D),
591597
(D, C),
592-
(C, D),
598+
(D, D),
593599
(D, C),
594600
]
595601
self.versus_test(
@@ -743,7 +749,7 @@ def test_strategy(self):
743749
(D, D),
744750
(D, D),
745751
(D, C),
746-
(C, D),
752+
(D, D),
747753
(D, D),
748754
]
749755

@@ -753,7 +759,7 @@ def test_strategy(self):
753759

754760
# Check the fresh start condition
755761
opponent = axelrod.TitForTat()
756-
actions = [(C, C), (C, C), (C, C), (C, C)]
762+
actions = [(C, C), (C, C), (D, C), (D, D)]
757763
self.versus_test(
758764
opponent, expected_actions=actions, attrs={"fresh_start": False}
759765
)
@@ -794,16 +800,16 @@ def test_strategy(self):
794800
(D, C),
795801
(D, C),
796802
(C, C),
797-
(C, C),
798-
(C, D),
803+
(D, C),
804+
(D, D),
799805
]
800806
self.versus_test(
801807
opponent,
802808
expected_actions=actions,
803809
match_attributes={"length": 35},
804810
attrs={
805-
"current_score": 108,
806-
"opponent_score": 78,
811+
"current_score": 110,
812+
"opponent_score": 75,
807813
"last_fresh_start": 24,
808814
"retaliation_length": 2,
809815
"retaliation_remaining": 0,

docs/reference/overview_of_strategies.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ An indication is given as to whether or not this strategy is implemented in the
1717
:header: "Name", "Author", "Axelrod Library Name"
1818

1919
"Tit For Tat", "Anatol Rapoport", ":class:`TitForTat <axelrod.strategies.titfortat.TitForTat>`"
20-
"Tideman and Chieruzzi", "T Nicolaus Tideman and Paula Chieruzz", ":class:`TidemanAndChieruzzi <axelrod.strategies.axelrod_first.TidemanAndChieruzzi>`"
20+
"Tideman and Chieruzzi", "T Nicolaus Tideman and Paula Chieruzz", ":class:`TidemanAndChieruzzi <axelrod.strategies.axelrod_first.FirstByTidemanAndChieruzzi>`"
2121
"Nydegger", "Rudy Nydegger", ":class:`Nydegger <axelrod.strategies.axelrod_first.FirstByNydegger>`"
2222
"Grofman", "Bernard Grofman", ":class:`Grofman <axelrod.strategies.axelrod_first.FirstByGrofman>`"
2323
"Shubik", "Martin Shubik", ":class:`Shubik <axelrod.strategies.axelrod_first.FirstByShubik>`"

0 commit comments

Comments
 (0)