def test_strategy(self): P1 = axl.NiceMetaWinner(team=[axl.Cooperator, axl.Defector]) P2 = axl.Player() # This meta player will simply choose the strategy with the highest # current score. P1.team[0].score = 0 P1.team[1].score = 1 self.assertEqual(P1.strategy(P2), C) P1.team[0].score = 1 P1.team[1].score = 0 self.assertEqual(P1.strategy(P2), C) # If there is a tie, choose to cooperate if possible. P1.team[0].score = 1 P1.team[1].score = 1 self.assertEqual(P1.strategy(P2), C) opponent = axl.Cooperator() player = axl.NiceMetaWinner(team=[axl.Cooperator, axl.Defector]) match = axl.Match((player, opponent), turns=5) match.play() self.assertEqual(player.history[-1], C) opponent = axl.Defector() player = axl.NiceMetaWinner(team=[axl.Defector]) match = axl.Match((player, opponent), turns=20) match.play() self.assertEqual(player.history[-1], D) opponent = axl.Defector() player = axl.MetaWinner(team=[axl.Cooperator, axl.Defector]) match = axl.Match((player, opponent), turns=20) match.play() self.assertEqual(player.history[-1], D)
def test_play(self): player1, player2 = self.player(), self.player() player1.strategy = cooperate player2.strategy = defect match = axl.Match((player1, player2), turns=1) match.play() self.assertEqual(player1.history[0], C) self.assertEqual(player2.history[0], D) # Test cooperation / defection counts self.assertEqual(player1.cooperations, 1) self.assertEqual(player1.defections, 0) self.assertEqual(player2.cooperations, 0) self.assertEqual(player2.defections, 1) # Test state distribution self.assertEqual(player1.state_distribution, {(C, D): 1}) self.assertEqual(player2.state_distribution, {(D, C): 1}) match = axl.Match((player1, player2), turns=2) match.play() self.assertEqual(player1.history[-1], C) self.assertEqual(player2.history[-1], D) # Test cooperation / defection counts self.assertEqual(player1.cooperations, 2) self.assertEqual(player1.defections, 0) self.assertEqual(player2.cooperations, 0) self.assertEqual(player2.defections, 2) # Test state distribution self.assertEqual(player1.state_distribution, {(C, D): 2}) self.assertEqual(player2.state_distribution, {(D, C): 2})
def test_strategy(self): """ Test that the strategy gives expected behaviour """ axelrod.seed(1) opponent = axelrod.Cooperator() player = axelrod.KnowledgeableWorseAndWorse() match = axelrod.Match((opponent, player), turns=5) self.assertEqual(match.play(), [('C', 'C'), ('C', 'D'), ('C', 'D'), ('C', 'D'), ('C', 'D')]) # Test that behaviour does not depend on opponent opponent = axelrod.Defector() player = axelrod.KnowledgeableWorseAndWorse() axelrod.seed(1) match = axelrod.Match((opponent, player), turns=5) self.assertEqual(match.play(), [('D', 'C'), ('D', 'D'), ('D', 'D'), ('D', 'D'), ('D', 'D')]) # Test that behaviour changes when does not know length. axelrod.seed(1) match = axelrod.Match((opponent, player), turns=5, match_attributes={'length': float('inf')}) self.assertEqual(match.play(), [('D', 'C'), ('D', 'C'), ('D', 'C'), ('D', 'C'), ('D', 'C')])
def test_cooperation_probability(self): # Test cooperation probabilities p1 = self.player(start_coop_prob=1.0, end_coop_prob=0.8, rounds_of_decay=100) self.assertEqual(1.0, p1._cooperation_probability()) p2 = axelrod.Cooperator() match = axelrod.Match((p1, p2), turns=50) match.play() self.assertEqual(0.9, p1._cooperation_probability()) match = axelrod.Match((p1, p2), turns=100) match.play() self.assertEqual(0.8, p1._cooperation_probability()) # Test cooperation probabilities, second set of params p1 = self.player(start_coop_prob=1.0, end_coop_prob=0.5, rounds_of_decay=200) self.assertEqual(1.0, p1._cooperation_probability()) match = axelrod.Match((p1, p2), turns=100) match.play() self.assertEqual(0.75, p1._cooperation_probability()) match = axelrod.Match((p1, p2), turns=200) match.play() self.assertEqual(0.5, p1._cooperation_probability())
def test_is_tit_for_tat_with_no_noise(self, strategies, turns): tft = axl.TitForTat() player = self.player() opponent = strategies[0]() m1 = axl.Match((tft, opponent), turns) m2 = axl.Match((player, opponent), turns) self.assertEqual(m1.play(), m2.play())
def test_clone_reproducible_play(self, seed, turns, noise): # Test that the cloned player produces identical play player = self.player() if player.name in [ "Darwin", "Human", "Mind Bender", "Mind Controller", "Mind Warper" ]: # Known exceptions return for op in [ axl.Cooperator(), axl.Defector(), axl.TitForTat(), axl.Random(p=0.5), ]: player = self.player() player_clone = player.clone() op = op.clone() op_clone = op.clone() m1 = axl.Match((player, op), turns=turns, seed=seed, noise=noise / 100.) m2 = axl.Match((player_clone, op_clone), turns=turns, seed=seed, noise=noise / 100.) m1.play() m2.play() self.assertEqual(m1.result, m2.result) self.assertEqual(player, player_clone) self.assertEqual(op, op_clone)
def test_idempotency(self): """Show that these transformers are idempotent, i.e. that transformer(transformer(PlayerClass)) == transformer(PlayerClass). That means that the transformer is a projection on the set of strategies.""" for transformer in [ IdentityTransformer(), GrudgeTransformer(1), FinalTransformer([C]), FinalTransformer([D]), InitialTransformer([C]), InitialTransformer([D]), DeadlockBreakingTransformer(), RetaliationTransformer(1), RetaliateUntilApologyTransformer(), TrackHistoryTransformer(), ApologyTransformer([D], [C]), ]: for PlayerClass in [axl.Cooperator, axl.Defector]: for third_player in [axl.Cooperator(), axl.Defector()]: clone = third_player.clone() player = transformer(PlayerClass)() transformed = transformer(transformer(PlayerClass))() match = axl.Match((player, third_player), turns=5) match.play() match = axl.Match((transformed, clone), turns=5) match.play() self.assertEqual(player.history, transformed.history)
def setUpClass(cls): cls.players = ( axelrod.Alternator(), axelrod.TitForTat(), axelrod.Defector()) cls.turns = 5 cls.matches = { (0, 1): [axelrod.Match( (cls.players[0], cls.players[1]), turns=cls.turns) for _ in range(3)], (0, 2): [axelrod.Match( (cls.players[0], cls.players[2]), turns=cls.turns) for _ in range(3)], (1, 2): [axelrod.Match( (cls.players[1], cls.players[2]), turns=cls.turns) for _ in range(3)] } # This would not actually be a round robin tournament # (no cloned matches) cls.interactions = {} for index_pair, matches in cls.matches.items(): for match in matches: match.play() try: cls.interactions[index_pair].append(match.result) except KeyError: cls.interactions[index_pair] = [match.result] cls.test_result_set = axelrod.ResultSet(cls.players, cls.interactions, progress_bar=False) cls.expected_boxplot_dataset = [ [(17 / 5 + 9 / 5) / 2 for _ in range(3)], [(13 / 5 + 4 / 5) / 2 for _ in range(3)], [3 / 2 for _ in range(3)] ] cls.expected_boxplot_xticks_locations = [1, 2, 3, 4] cls.expected_boxplot_xticks_labels = [ 'Defector', 'Tit For Tat', 'Alternator'] cls.expected_lengthplot_dataset = [ [cls.turns for _ in range(3)], [cls.turns for _ in range(3)], [cls.turns for _ in range(3)], ] cls.expected_payoff_dataset = [ [0, mean( [9 / 5 for _ in range(3)]), mean([17 / 5 for _ in range(3)])], [mean( [4 / 5 for _ in range(3)]), 0, mean([13 / 5 for _ in range(3)])], [mean( [2 / 5 for _ in range(3)]), mean([13 / 5 for _ in range(3)]), 0] ] cls.expected_winplot_dataset = ( [[2, 2, 2], [0, 0, 0], [0, 0, 0]], ['Defector', 'Tit For Tat', 'Alternator'])
def test_stochastic(self, p): p1, p2 = axl.Cooperator(), axl.Cooperator() match = axl.Match((p1, p2), 5) self.assertFalse(match._stochastic) match = axl.Match((p1, p2), 5, noise=p) self.assertTrue(match._stochastic) p1 = axl.Random() match = axl.Match((p1, p2), 5) self.assertTrue(match._stochastic)
def test_stochastic(self): p1, p2 = axelrod.Cooperator(), axelrod.Cooperator() match = axelrod.Match((p1, p2), 5) self.assertFalse(match._stochastic) match = axelrod.Match((p1, p2), 5, noise=0.2) self.assertTrue(match._stochastic) p1 = axelrod.Random() match = axelrod.Match((p1, p2), 5) self.assertTrue(match._stochastic)
def behavior_test(self, player1, player2, seed=7): """Test that the evolvable player plays the same as its (nonevolvable) parent class.""" for opponent_class in [axl.Random, axl.TitForTat, axl.Alternator]: opponent = opponent_class() match = axl.Match((player1.clone(), opponent), seed=seed) results1 = match.play() opponent = opponent_class() match = axl.Match((player2.clone(), opponent), seed=seed) results2 = match.play() self.assertEqual(results1, results2)
def test_final_score(self): player1 = axelrod.TitForTat() player2 = axelrod.Defector() match = axelrod.Match((player1, player2), 3) self.assertEqual(match.final_score(), None) match.play() self.assertEqual(match.final_score(), (2, 7)) match = axelrod.Match((player2, player1), 3) self.assertEqual(match.final_score(), None) match.play() self.assertEqual(match.final_score(), (7, 2))
def test_cache_update_required(self): p1, p2 = axelrod.Cooperator(), axelrod.Cooperator() match = axelrod.Match((p1, p2), 5, noise=0.2) self.assertFalse(match._cache_update_required) match = axelrod.Match((p1, p2), 5, cache_mutable=False) self.assertFalse(match._cache_update_required) match = axelrod.Match((p1, p2), 5) self.assertTrue(match._cache_update_required) p1 = axelrod.Random() match = axelrod.Match((p1, p2), 5) self.assertFalse(match._cache_update_required)
def test_final_score_per_turn(self): turns = 3 player1 = axelrod.TitForTat() player2 = axelrod.Defector() match = axelrod.Match((player1, player2), turns) self.assertEqual(match.final_score_per_turn(), None) match.play() self.assertEqual(match.final_score_per_turn(), (2 / turns, 7 / turns)) match = axelrod.Match((player2, player1), turns) self.assertEqual(match.final_score_per_turn(), None) match.play() self.assertEqual(match.final_score_per_turn(), (7 / turns, 2 / turns))
def test_play(self): cache = DeterministicCache() players = (axelrod.Cooperator(), axelrod.Defector()) match = axelrod.Match(players, 3, deterministic_cache=cache) expected_result = [(C, D), (C, D), (C, D)] self.assertEqual(match.play(), expected_result) self.assertEqual(cache[(axelrod.Cooperator(), axelrod.Defector(), 3)], expected_result) # a deliberately incorrect result so we can tell it came from the cache expected_result = [(C, C), (D, D), (D, C)] cache[(axelrod.Cooperator(), axelrod.Defector(), 3)] = expected_result match = axelrod.Match(players, 3, deterministic_cache=cache) self.assertEqual(match.play(), expected_result)
def test_stochastic(self, p): assume(0 < p < 1) p1, p2 = axelrod.Cooperator(), axelrod.Cooperator() match = axelrod.Match((p1, p2), 5) self.assertFalse(match._stochastic) match = axelrod.Match((p1, p2), 5, noise=p) self.assertTrue(match._stochastic) p1 = axelrod.Random() match = axelrod.Match((p1, p2), 5) self.assertTrue(match._stochastic)
def test_play(self): cache = {} players = (axelrod.Cooperator(), axelrod.Defector()) match = axelrod.Match(players, 3, cache) expected_result = [(C, D), (C, D), (C, D)] self.assertEqual(match.play(), expected_result) self.assertEqual(cache[(axelrod.Cooperator, axelrod.Defector)], expected_result) # a deliberately incorrect result so we can tell it came from the cache expected_result = [(C, C), (D, D), (D, C)] cache = {(axelrod.Cooperator, axelrod.Defector): expected_result} match = axelrod.Match(players, 3, cache) self.assertEqual(match.play(), expected_result)
def test_strategies_without_countermeasures_return_their_strategy(self): tft = axl.TitForTat() inspector = axl.Alternator() match = axl.Match((tft, inspector), turns=1) match.play() self.assertEqual(tft.history, [C]) self.assertEqual(inspect_strategy(inspector=inspector, opponent=tft), C) match = axl.Match((tft, inspector), turns=2) match.play() self.assertEqual(tft.history, [C, C]) self.assertEqual(inspect_strategy(inspector=inspector, opponent=tft), D) self.assertEqual(tft.strategy(inspector), D)
def test_matches_with_det_player_for_stochastic_classes(self): """A test based on a bug found in the cache. See: https://github.com/Axelrod-Python/Axelrod/issues/779""" p1 = axl.MemoryOnePlayer(four_vector=(0, 0, 0, 0)) p2 = axl.MemoryOnePlayer(four_vector=(1, 0, 1, 0)) p3 = axl.MemoryOnePlayer(four_vector=(1, 1, 1, 0)) m = axl.Match((p1, p2), turns=3) self.assertEqual(m.play(), [(C, C), (D, C), (D, D)]) m = axl.Match((p2, p3), turns=3) self.assertEqual(m.play(), [(C, C), (C, C), (C, C)]) m = axl.Match((p1, p3), turns=3) self.assertEqual(m.play(), [(C, C), (D, C), (D, C)])
def test_outcome_repeats(self, strategies, turns): """A test that if we repeat 3 matches with deterministic and well behaved strategies then we get the same result""" players = [s() for s in strategies] matches = [axl.Match(players, turns) for _ in range(3)] self.assertEqual(matches[0].play(), matches[1].play()) self.assertEqual(matches[1].play(), matches[2].play())
def test_flip_transformer(self): """Tests that FlipTransformer(Cooperator) == Defector.""" p1 = axelrod.Cooperator() p2 = FlipTransformer()(axelrod.Cooperator)() # Defector match = axelrod.Match((p1, p2), turns=3) results = match.play() self.assertEqual(results, [(C, D), (C, D), (C, D)])
def versus_test(self, player1, player2, expected_actions1, expected_actions2, turns=None, noise=None, seed=None, match_attributes=None, attrs=None): """Tests a sequence of outcomes for two given players.""" if len(expected_actions1) != len(expected_actions2): raise ValueError("Mismatched Expected History in TestMatch.") if not turns: turns = len(expected_actions1) match = axl.Match((player1, player2), turns=turns, noise=noise, seed=seed, match_attributes=match_attributes) match.play() # Test expected sequence of plays from the match is as expected. for i, (play, expected_play) in enumerate( zip(player1.history, expected_actions1)): self.assertEqual((i, play), (i, expected_play)) for i, (play, expected_play) in enumerate( zip(player2.history, expected_actions2)): self.assertEqual((i, play), (i, expected_play)) # Test final player attributes are as expected if attrs: for attr, value in attrs.items(): self.assertEqual(getattr(player1, attr), value)
def test_clone(self): # Test that the cloned player produces identical play player1 = self.player() if player1.name in ["Darwin", "Human"]: # Known exceptions return player2 = player1.clone() self.assertEqual(len(player2.history), 0) self.assertEqual(player2.cooperations, 0) self.assertEqual(player2.defections, 0) self.assertEqual(player2.state_distribution, {}) self.assertEqual(player2.classifier, player1.classifier) self.assertEqual(player2.match_attributes, player1.match_attributes) turns = 50 r = random.random() for op in [ axelrod.Cooperator(), axelrod.Defector(), axelrod.TitForTat(), axelrod.Random(p=r) ]: player1.reset() player2.reset() seed = random.randint(0, 10**6) for p in [player1, player2]: axelrod.seed(seed) m = axelrod.Match((p, op), turns=turns) m.play() self.assertEqual(len(player1.history), turns) self.assertEqual(player1.history, player2.history)
def test_history_track(self): """Tests the tracked history matches.""" p1 = axl.Cooperator() p2 = TrackHistoryTransformer()(axl.Random)() match = axl.Match((p1, p2), turns=6, seed=1) match.play() self.assertEqual(p2.history, p2._recorded_history)
def custom_nrof_mathches (p1, p2, matches): ''' Plays N matches and N turns with random inputs. Also gathers statistics. ''' players = (p1, p2) p1_wins = 0 p2_wins = 0 eq = 0 results = [] for m in range(matches): if dev_t is None: turns = mean_t else: turns = int(np.random.default_rng().normal(mean_t, dev_t, None)) match = axl.Match(players, turns=turns) match.play() if match.winner() == p1: p1_wins += 1 if match.winner() == p2: p2_wins += 1 elif match.winner() == False: eq += 1 results = [p1_wins, p2_wins, eq] return results
def test_clone(self, seed): # Test that the cloned player produces identical play player1 = self.player() player2 = player1.clone() self.assertEqual(len(player2.history), 0) self.assertEqual(player2.cooperations, 0) self.assertEqual(player2.defections, 0) self.assertEqual(player2.state_distribution, {}) self.assertEqual(player2.classifier, player1.classifier) self.assertEqual(player2.match_attributes, player1.match_attributes) turns = 10 for op in [ axelrod.Cooperator(), axelrod.Defector(), axelrod.TitForTat(), ]: player1.reset() player2.reset() for p in [player1, player2]: axelrod.seed(seed) m = axelrod.Match((p, op), turns=turns) m.play() self.assertEqual(len(player1.history), turns) self.assertEqual(player1.history, player2.history)
def matches(draw, strategies=axelrod.strategies, min_turns=1, max_turns=200, min_noise=0, max_noise=1): """ A hypothesis decorator to return a random match as well as a random seed (to ensure reproducibility when instance of class need the random library). Parameters ---------- strategies : list The strategies from which to sample the two the players min_turns : integer The minimum number of turns max_turns : integer The maximum number of turns min_noise : float The minimum noise max_noise : float The maximum noise Returns ------- tuple : a random match as well as a random seed """ seed = draw(random_module()) strategies = draw(strategy_lists(min_size=2, max_size=2)) players = [s() for s in strategies] turns = draw(integers(min_value=min_turns, max_value=max_turns)) noise = draw(floats(min_value=min_noise, max_value=max_noise)) match = axelrod.Match(players, turns=turns, noise=noise) return match, seed
def test_scores(self): player1 = axelrod.TitForTat() player2 = axelrod.Defector() match = axelrod.Match((player1, player2), 3) self.assertEqual(match.scores(), []) match.play() self.assertEqual(match.scores(), [(0, 5), (1, 1), (1, 1)])
def matches( draw, strategies=axl.short_run_time_strategies, min_turns=1, max_turns=200, min_noise=0, max_noise=1, ): """ A hypothesis decorator to return a random match. Parameters ---------- strategies : list The strategies from which to sample the two the players min_turns : integer The minimum number of turns max_turns : integer The maximum number of turns min_noise : float The minimum noise max_noise : float The maximum noise Returns ------- match : a random match """ strategies = draw(strategy_lists(min_size=2, max_size=2)) players = [s() for s in strategies] turns = draw(integers(min_value=min_turns, max_value=max_turns)) noise = draw(floats(min_value=min_noise, max_value=max_noise)) match = axl.Match(players, turns=turns, noise=noise) return match
def test_cache_update_required(self, p): p1, p2 = axl.Cooperator(), axl.Cooperator() match = axl.Match((p1, p2), 5, noise=p) self.assertFalse(match._cache_update_required) cache = DeterministicCache() cache.mutable = False match = axl.Match((p1, p2), 5, deterministic_cache=cache) self.assertFalse(match._cache_update_required) match = axl.Match((p1, p2), 5) self.assertTrue(match._cache_update_required) p1 = axl.Random() match = axl.Match((p1, p2), 5) self.assertFalse(match._cache_update_required)