From 9df081b4c62e9d0f5d5abcd46fd7156089d1833f Mon Sep 17 00:00:00 2001 From: Vince Knight Date: Wed, 15 Mar 2017 16:58:38 +0000 Subject: [PATCH] Refactor averagecopier for 884 and a bug. Note that I think I've caught a bug here: The average copier was using integer division for the calculation of the opponent's cooperation ratio. So it was in effect either 0 or 1. I've fixed this and also written tests that show the behaviour changes for different seeds (in essence testing that the behaviour is stochastic). --- axelrod/strategies/averagecopier.py | 4 +- .../tests/strategies/test_averagecopier.py | 86 ++++++++++++++++--- 2 files changed, 78 insertions(+), 12 deletions(-) diff --git a/axelrod/strategies/averagecopier.py b/axelrod/strategies/averagecopier.py index af38abcf3..af90835f3 100644 --- a/axelrod/strategies/averagecopier.py +++ b/axelrod/strategies/averagecopier.py @@ -26,7 +26,7 @@ def strategy(self, opponent: Player) -> Action: if len(opponent.history) == 0: # Randomly picks a strategy (not affected by history). return random_choice(0.5) - p = opponent.cooperations // len(opponent.history) + p = opponent.cooperations / len(opponent.history) return random_choice(p) @@ -47,5 +47,5 @@ class NiceAverageCopier(Player): def strategy(self, opponent: Player) -> Action: if len(opponent.history) == 0: return C - p = opponent.cooperations // len(opponent.history) + p = opponent.cooperations / len(opponent.history) return random_choice(p) diff --git a/axelrod/tests/strategies/test_averagecopier.py b/axelrod/tests/strategies/test_averagecopier.py index f889a4e69..40c2dfae0 100644 --- a/axelrod/tests/strategies/test_averagecopier.py +++ b/axelrod/tests/strategies/test_averagecopier.py @@ -22,12 +22,48 @@ class TestAverageCopier(TestPlayer): def test_strategy(self): # Test that the first strategy is picked randomly. - self.responses_test([C], seed=1) - self.responses_test([D], seed=2) + self.first_play_test(C, seed=1) + self.first_play_test(D, seed=2) + # Tests that if opponent has played all C then player chooses C. - self.responses_test([C, C, C], [C, C, C, C], [C, C, C, C], seed=5) + actions = [(C, C)] * 10 + self.versus_test(axelrod.Cooperator(), expected_actions=actions, + seed=1) + actions = [(D, C)] + [(C, C)] * 9 + self.versus_test(axelrod.Cooperator(), expected_actions=actions, + seed=2) + # Tests that if opponent has played all D then player chooses D. - self.responses_test([D, D, D], [C, C, C, C], [D, D, D, D], seed=5) + actions = [(C, D)] + [(D, D)] * 9 + self.versus_test(axelrod.Defector(), expected_actions=actions, + seed=1) + actions = [(D, D)] + [(D, D)] * 9 + self.versus_test(axelrod.Defector(), expected_actions=actions, + seed=2) + + # Variable behaviour based on the history and stochastic + + actions = [(C, C), (C, D), (D, C), (D, D), (C, C), + (C, D), (C, C), (D, D), (D, C), (C, D)] + self.versus_test(axelrod.Alternator(), expected_actions=actions, + seed=1) + + actions = [(D, C), (C, D), (D, C), (C, D), (C, C), + (D, D), (D, C), (D, D), (C, C), (D, D)] + self.versus_test(axelrod.Alternator(), expected_actions=actions, + seed=2) + + opponent = axelrod.MockPlayer([C, C, D, D, D, D]) + actions = [(C, C), (C, C), (C, D), (D, D), (D, D), + (C, D), (D, C), (D, C), (D, D), (D, D)] + self.versus_test(opponent, expected_actions=actions, + seed=1) + + opponent = axelrod.MockPlayer([C, C, C, D, D, D]) + actions = [(D, C), (C, C), (C, C), (C, D), (D, D), + (C, D), (C, C), (D, C), (D, C), (D, D)] + self.versus_test(opponent, expected_actions=actions, + seed=2) class TestNiceAverageCopier(TestPlayer): @@ -45,9 +81,39 @@ class TestNiceAverageCopier(TestPlayer): } def test_strategy(self): - # Cooperates initially. - self.first_play_test(C) - # If opponent has played all C then player chooses C. - self.responses_test([C, C, C], [C, C, C, C], [C, C, C, C], seed=5) - # If opponent has played all D then player chooses D. - self.responses_test([D, D, D], [D, D, D, D], [D, D, D, D], seed=5) + # Cooperates initially (not stochastic) + self.first_play_test(C, seed=1) + self.first_play_test(C, seed=2) + + # Tests that if opponent has played all C then player chooses C. + actions = [(C, C)] * 10 + self.versus_test(axelrod.Cooperator(), expected_actions=actions, + seed=1) + + # Tests that if opponent has played all D then player chooses D. + actions = [(C, D)] + [(D, D)] * 9 + self.versus_test(axelrod.Defector(), expected_actions=actions, + seed=1) + + # Variable behaviour based on the history and stochastic behaviour + actions = [(C, C), (C, D), (C, C), (D, D), (D, C), + (C, D), (C, C), (C, D), (D, C), (D, D)] + self.versus_test(axelrod.Alternator(), expected_actions=actions, + seed=1) + + actions = [(C, C), (C, D), (D, C), (D, D), (C, C), + (C, D), (D, C), (D, D), (D, C), (C, D)] + self.versus_test(axelrod.Alternator(), expected_actions=actions, + seed=2) + + opponent = axelrod.MockPlayer([C, C, D, D, D, D]) + actions = [(C, C), (C, C), (C, D), (C, D), (D, D), + (D, D), (C, C), (D, C), (C, D), (D, D)] + self.versus_test(opponent, expected_actions=actions, + seed=1) + + opponent = axelrod.MockPlayer([C, C, C, D, D, D]) + actions = [(C, C), (C, C), (C, C), (C, D), (D, D), + (D, D), (C, C), (C, C), (D, C), (D, D)] + self.versus_test(opponent, expected_actions=actions, + seed=2)