From 0db7186af91e86d2b93b271ab27ae85b35fd9cc2 Mon Sep 17 00:00:00 2001 From: cath Date: Sun, 14 Sep 2025 12:52:44 +0100 Subject: [PATCH 01/10] Created adaptive_cooperator.py --- axelrod/strategies/adaptive_cooperator.py | 63 +++++++++++++++++++++++ 1 file changed, 63 insertions(+) create mode 100644 axelrod/strategies/adaptive_cooperator.py diff --git a/axelrod/strategies/adaptive_cooperator.py b/axelrod/strategies/adaptive_cooperator.py new file mode 100644 index 000000000..a76eae69f --- /dev/null +++ b/axelrod/strategies/adaptive_cooperator.py @@ -0,0 +1,63 @@ +from axelrod.action import Action +from axelrod.player import Player + +C, D = Action.C, Action.D + +class AdaptiveCooperator(Player): + """ + This is an adaptive strategy where the player starts + by cooperating, but switches to Tit-For-Tat if the + opponent's score exceed's its own score. Then, it + switches to Defector if the opponent's score is twice + its own score. + """ + + name = 'Adaptive Cooperator' + classifier = { + 'memory': 1, + 'stochastic': False, + 'inspects_source': False, + 'manipulates_source': False, + 'manipulates_state': False + } + + def __init__(self): + super().__init__() + self.is_tft = False + self.is_defect = False + self.current_score = 0 + self.opponent_score = 0 + + def _score_last_round(self, opponent): + game = self.match_attributes["game"] + last_round = (self.history[-1], opponent.history[-1]) + scores = game.score(last_round) + self.current_score += scores[0] + self.opponent_score += scores[1] + + def strategy(self, opponent): + turn = len(self.history) + 1 + if turn > 1: + self._score_last_round(opponent) + + if self.opponent_score > self.current_score * 2: + self.is_defect = True + elif self.opponent_score > self.current_score: + self.is_tft = True + + #response to strategies + if self.is_defect: + return D + elif self.is_tft: + if not opponent.history or len(self.history) == 0: + return C + else: + return opponent.history[-1] + else: #cooperate + return C + + def reset(self): + super().__init__() + self.is_defect = False + self.is_tft = False + From 1e564f50f115f8733effda9c314105d48e82ae38 Mon Sep 17 00:00:00 2001 From: cath Date: Sun, 14 Sep 2025 12:53:13 +0100 Subject: [PATCH 02/10] Create test_adaptive_cooperator.py --- .../strategies/test_adaptive_cooperator.py | 31 +++++++++++++++++++ 1 file changed, 31 insertions(+) create mode 100644 axelrod/tests/strategies/test_adaptive_cooperator.py diff --git a/axelrod/tests/strategies/test_adaptive_cooperator.py b/axelrod/tests/strategies/test_adaptive_cooperator.py new file mode 100644 index 000000000..f577c185b --- /dev/null +++ b/axelrod/tests/strategies/test_adaptive_cooperator.py @@ -0,0 +1,31 @@ +import axelrod +from test_player import TestPlayer + +C, D = axelrod.Action.C, axelrod.Action.D + +class TestAdaptiveCooperator(TestPlayer): + name = 'Adaptive Cooperator' + player = axelrod.AdaptiveCooperator + expected_classifier = { + 'memory': 1, + 'stochastic': False, + 'inspects_source': False, + 'manipulates_source': False, + 'manipulates_state': False + } + + def test_first__strategy(self): + self.first_play_test(C) + + def test_strategy_cooperator(self): + actions = [(C, C), (C, C), (C, C), (C, C), (C, C)] + self.versus_test(axelrod.Cooperator(), expected_actions=actions) + + def test_strategy_defector(self): + actions = [(C, D), (D, D), (D, D), (D, D), (D, D)] + self.versus_test(axelrod.Defector(), expected_actions=actions) + + def test_strategy_alternator(self): + actions = [(C, C), (C, D), (D, C), (D, D), (D, C)] + self.versus_test(axelrod.Alternator(), expected_actions=actions) + From fd512eccf1e75ef4c2768e51e956dd2c05a689d9 Mon Sep 17 00:00:00 2001 From: cath Date: Sun, 14 Sep 2025 12:54:53 +0100 Subject: [PATCH 03/10] Update _strategies.py with AdaptiveCooperator --- axelrod/strategies/_strategies.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/axelrod/strategies/_strategies.py b/axelrod/strategies/_strategies.py index bc80eeccc..f9d85100d 100644 --- a/axelrod/strategies/_strategies.py +++ b/axelrod/strategies/_strategies.py @@ -24,6 +24,7 @@ import warnings from .adaptive import Adaptive +from .adaptive_cooperator import AdaptiveCooperator from .adaptor import AdaptorBrief, AdaptorLong from .alternator import Alternator from .ann import EvolvedANN, EvolvedANN5, EvolvedANNNoise05 @@ -294,6 +295,7 @@ APavlov2006, APavlov2011, Adaptive, + AdaptiveCooperator, AdaptiveTitForTat, AdaptorBrief, AdaptorLong, From 569be2c64ae1c0e04867afd11931d47a1542e5c1 Mon Sep 17 00:00:00 2001 From: cath Date: Sun, 14 Sep 2025 12:55:26 +0100 Subject: [PATCH 04/10] Update index.rst docstring --- docs/index.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/index.rst b/docs/index.rst index 82b9f41b5..a379bbc7f 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -53,7 +53,7 @@ Count the number of available players:: >>> import axelrod as axl >>> len(axl.strategies) - 243 + 244 Create matches between two players:: From 1b6bf7f79bee3ca4019c2c500d3aa5f6502a258a Mon Sep 17 00:00:00 2001 From: cath Date: Sun, 14 Sep 2025 12:57:28 +0100 Subject: [PATCH 05/10] Update strategy_index.rst for AdaptiveCooperator --- docs/reference/strategy_index.rst | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/reference/strategy_index.rst b/docs/reference/strategy_index.rst index 9764d3082..7a656a1c3 100644 --- a/docs/reference/strategy_index.rst +++ b/docs/reference/strategy_index.rst @@ -8,6 +8,8 @@ Here are the docstrings of all the strategies in the library. .. automodule:: axelrod.strategies.adaptive :members: +.. automodule:: axelrod.strategies.adaptive_cooperator + :members: .. automodule:: axelrod.strategies.adaptor :members: .. automodule:: axelrod.strategies.alternator From fbc9efe343712e947cc107a7acd7317baaf0792e Mon Sep 17 00:00:00 2001 From: cath Date: Tue, 16 Sep 2025 08:51:25 +0100 Subject: [PATCH 06/10] Update test_adaptive_cooperator.py --- axelrod/tests/strategies/test_adaptive_cooperator.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/axelrod/tests/strategies/test_adaptive_cooperator.py b/axelrod/tests/strategies/test_adaptive_cooperator.py index f577c185b..279741b0a 100644 --- a/axelrod/tests/strategies/test_adaptive_cooperator.py +++ b/axelrod/tests/strategies/test_adaptive_cooperator.py @@ -1,5 +1,5 @@ import axelrod -from test_player import TestPlayer +from .test_player import TestPlayer C, D = axelrod.Action.C, axelrod.Action.D From 1079d8df4fb3076e869eb09c475433c6a16239c8 Mon Sep 17 00:00:00 2001 From: cath Date: Tue, 16 Sep 2025 09:41:49 +0100 Subject: [PATCH 07/10] Update test_adaptive_cooperator.py --- axelrod/tests/strategies/test_adaptive_cooperator.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/axelrod/tests/strategies/test_adaptive_cooperator.py b/axelrod/tests/strategies/test_adaptive_cooperator.py index 279741b0a..79c08c05f 100644 --- a/axelrod/tests/strategies/test_adaptive_cooperator.py +++ b/axelrod/tests/strategies/test_adaptive_cooperator.py @@ -14,9 +14,6 @@ class TestAdaptiveCooperator(TestPlayer): 'manipulates_state': False } - def test_first__strategy(self): - self.first_play_test(C) - def test_strategy_cooperator(self): actions = [(C, C), (C, C), (C, C), (C, C), (C, C)] self.versus_test(axelrod.Cooperator(), expected_actions=actions) From cf0f005881a69bfa6c5ec62d0f62e0083ea6d9bc Mon Sep 17 00:00:00 2001 From: cath Date: Tue, 16 Sep 2025 12:47:38 +0100 Subject: [PATCH 08/10] Update axelrod/tests/strategies/test_adaptive_cooperator.py Co-authored-by: Vince Knight --- axelrod/tests/strategies/test_adaptive_cooperator.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/axelrod/tests/strategies/test_adaptive_cooperator.py b/axelrod/tests/strategies/test_adaptive_cooperator.py index 79c08c05f..f9d026194 100644 --- a/axelrod/tests/strategies/test_adaptive_cooperator.py +++ b/axelrod/tests/strategies/test_adaptive_cooperator.py @@ -7,7 +7,7 @@ class TestAdaptiveCooperator(TestPlayer): name = 'Adaptive Cooperator' player = axelrod.AdaptiveCooperator expected_classifier = { - 'memory': 1, + "memory_depth": 1, 'stochastic': False, 'inspects_source': False, 'manipulates_source': False, From 36dc4171cc873b9b820eaf28f4784eb54b4520ed Mon Sep 17 00:00:00 2001 From: cath Date: Tue, 16 Sep 2025 12:47:44 +0100 Subject: [PATCH 09/10] Update axelrod/strategies/adaptive_cooperator.py Co-authored-by: Vince Knight --- axelrod/strategies/adaptive_cooperator.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/axelrod/strategies/adaptive_cooperator.py b/axelrod/strategies/adaptive_cooperator.py index a76eae69f..8596df227 100644 --- a/axelrod/strategies/adaptive_cooperator.py +++ b/axelrod/strategies/adaptive_cooperator.py @@ -14,7 +14,7 @@ class AdaptiveCooperator(Player): name = 'Adaptive Cooperator' classifier = { - 'memory': 1, + "memory_depth": 1, 'stochastic': False, 'inspects_source': False, 'manipulates_source': False, From a6c10e4ef10d631fd29f5e4fe3c4275cee50d909 Mon Sep 17 00:00:00 2001 From: cath Date: Thu, 25 Sep 2025 04:43:36 +0100 Subject: [PATCH 10/10] Update test_adaptive_cooperator.py --- axelrod/tests/strategies/test_adaptive_cooperator.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/axelrod/tests/strategies/test_adaptive_cooperator.py b/axelrod/tests/strategies/test_adaptive_cooperator.py index f9d026194..fa9d1f063 100644 --- a/axelrod/tests/strategies/test_adaptive_cooperator.py +++ b/axelrod/tests/strategies/test_adaptive_cooperator.py @@ -26,3 +26,6 @@ def test_strategy_alternator(self): actions = [(C, C), (C, D), (D, C), (D, D), (D, C)] self.versus_test(axelrod.Alternator(), expected_actions=actions) + def test_strategy_tit4tat(self): + actions = [(C, C), (C, C), (C, C), (C, C), (C, C)] + self.versus_test(axelrod.TitForTat(), expected_actions=actions)