diff --git a/axelrod/strategies/_strategies.py b/axelrod/strategies/_strategies.py index b3d7f5b62..129756292 100644 --- a/axelrod/strategies/_strategies.py +++ b/axelrod/strategies/_strategies.py @@ -11,7 +11,7 @@ Champion, Eatherley, Tester, Gladstein, Tranquilizer, MoreGrofman, Kluepfel, Borufsen, Cave, WmAdams, GraaskampKatzen, Weiner, Harrington, MoreTidemanAndChieruzzi, Getzler, Leyvraz, White, Black, RichardHufford, - Yamachi) + Yamachi, Colbert) from .backstabber import BackStabber, DoubleCrosser from .better_and_better import BetterAndBetter from .bush_mosteller import BushMosteller @@ -118,6 +118,7 @@ CautiousQLearner, Cave, Champion, + Colbert, CollectiveStrategy, ContriteTitForTat, Cooperator, diff --git a/axelrod/strategies/axelrod_second.py b/axelrod/strategies/axelrod_second.py index ac4064ca2..6b093bf4e 100644 --- a/axelrod/strategies/axelrod_second.py +++ b/axelrod/strategies/axelrod_second.py @@ -9,6 +9,7 @@ from axelrod.action import Action from axelrod.player import Player from axelrod.random_ import random_choice +from axelrod.strategies.finite_state_machines import FSMPlayer from axelrod.interaction_utils import compute_final_score @@ -1803,3 +1804,50 @@ def strategy(self, opponent: Player) -> Action: self.count_them_us_them[(them_two_ago, us_last, D)]: return self.try_return(C, opponent.defections) return self.try_return(D, opponent.defections) + + +class Colbert(FSMPlayer): + """ + Strategy submitted to Axelrod's second tournament by William Colbert (K51R) + and came in eighteenth in that tournament. + + In the first eight turns, this strategy Coopearates on all but the sixth + turn, in which it Defects. After that, the strategy responds to an + opponent Cooperation with a single Cooperation, and responds to a Defection + with a chain of responses: Defect, Defect, Cooperate, Cooperate. During + this chain, the strategy ignores opponent's moves. + + Names: + + - Colbert: [Axelrod1980b]_ + """ + + name = "Colbert" + classifier = { + 'memory_depth': 4, + 'stochastic': False, + 'makes_use_of': set(), + 'long_run_time': False, + 'inspects_source': False, + 'manipulates_source': False, + 'manipulates_state': False + } + + def __init__(self) -> None: + transitions = ( + (0, C, 1, C), (0, D, 1, C), # First 8 turns are special + (1, C, 2, C), (1, D, 2, C), + (2, C, 3, C), (2, D, 3, C), + (3, C, 4, C), (3, D, 4, C), + (4, C, 5, D), (4, D, 5, D), # Defect on 6th turn. + (5, C, 6, C), (5, D, 6, C), + (6, C, 7, C), (6, D, 7, C), + + (7, C, 7, C), (7, D, 8, D), + (8, C, 9, D), (8, D, 9, D), + (9, C, 10, C), (9, D, 10, C), + (10, C, 7, C), (10, D, 7, C) + ) + + super().__init__(transitions=transitions, initial_state=0, + initial_action=C) diff --git a/axelrod/tests/strategies/test_axelrod_second.py b/axelrod/tests/strategies/test_axelrod_second.py index 1a89e47ed..1db5f7964 100644 --- a/axelrod/tests/strategies/test_axelrod_second.py +++ b/axelrod/tests/strategies/test_axelrod_second.py @@ -1161,3 +1161,31 @@ def test_strategy(self): actions += [(D, D)] # Next turn, `portion_defect` = 0.5521 actions += [(D, D), (C, D), (D, C), (C, D)] # Takes a turn to fall back into the cycle. self.versus_test(axelrod.Ripoff(), expected_actions=actions) + + +class TestColbert(TestPlayer): + name = 'Colbert' + player = axelrod.Colbert + expected_classifier = { + 'memory_depth': 4, + 'stochastic': False, + 'makes_use_of': set(), + 'long_run_time': False, + 'inspects_source': False, + 'manipulates_source': False, + 'manipulates_state': False + } + + def test_strategy(self): + actions = [(C, C)] * 5 + [(D, C)] + [(C, C)] * 30 + self.versus_test(axelrod.Cooperator(), expected_actions=actions) + + actions = [(C, D)] * 5 + [(D, D)] + [(C, D)] * 2 + actions += [(D, D), (D, D), (C, D), (C, D)] * 20 + self.versus_test(axelrod.Defector(), expected_actions=actions) + + opponent_actions = [C] * 8 + [C, C, D, C, C, C, C, C] + OddBall = axelrod.MockPlayer(actions=opponent_actions) + actions = [(C, C)] * 5 + [(D, C)] + [(C, C)] * 4 + actions += [(C, D)] + [(D, C), (D, C), (C, C), (C, C)] + [(C, C)] + self.versus_test(OddBall, expected_actions=actions) diff --git a/docs/tutorials/advanced/classification_of_strategies.rst b/docs/tutorials/advanced/classification_of_strategies.rst index c5fb62a5a..b99219bda 100644 --- a/docs/tutorials/advanced/classification_of_strategies.rst +++ b/docs/tutorials/advanced/classification_of_strategies.rst @@ -69,7 +69,7 @@ range of memory_depth values, we can use the 'min_memory_depth' and ... } >>> strategies = axl.filtered_strategies(filterset) >>> len(strategies) - 56 + 57 We can also identify strategies that make use of particular properties of the tournament. For example, here is the number of strategies that make use of the