class TestStrategyList(unittest.TestCase): def test_call(self): strategies = strategy_lists().example() self.assertIsInstance(strategies, list) for p in strategies: self.assertIsInstance(p(), axelrod.Player) @given(strategies=strategy_lists(min_size=1, max_size=50)) @settings(max_examples=5, max_iterations=20) def test_decorator(self, strategies): self.assertIsInstance(strategies, list) self.assertGreaterEqual(len(strategies), 1) self.assertLessEqual(len(strategies), 50) for strategy in strategies: self.assertIsInstance(strategy(), axelrod.Player) @given(strategies=strategy_lists(strategies=axelrod.basic_strategies)) @settings(max_examples=5, max_iterations=20) def test_decorator_with_given_strategies(self, strategies): self.assertIsInstance(strategies, list) basic_player_names = [str(s()) for s in axelrod.basic_strategies] for strategy in strategies: player = strategy() self.assertIsInstance(player, axelrod.Player) self.assertIn(str(player), basic_player_names)
class TestMatchOutcomes(unittest.TestCase): @given( strategies=strategy_lists(strategies=deterministic_strategies, min_size=2, max_size=2), turns=integers(min_value=1, max_value=20), ) @settings(max_examples=5) 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()) @given( strategies=strategy_lists(strategies=stochastic_strategies, min_size=2, max_size=2), turns=integers(min_value=1, max_value=20), seed=integers(min_value=0, max_value=4294967295), ) @settings(max_examples=5) def test_outcome_repeats_stochastic(self, strategies, turns, seed): """a test to check that if a seed is set stochastic strategies give the same result""" results = [] for _ in range(3): axl.seed(seed) players = [s() for s in strategies] results.append(axl.Match(players, turns).play()) self.assertEqual(results[0], results[1]) self.assertEqual(results[1], results[2]) 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_init(self): tournament = axelrod.SpatialTournament( name=self.test_name, players=self.players, game=self.game, turns=self.test_turns, edges=self.test_edges, noise=0.2) self.assertEqual(tournament.match_generator.edges, tournament.edges) self.assertEqual(len(tournament.players), len(test_strategies)) self.assertEqual(tournament.game.score(('C', 'C')), (3, 3)) self.assertEqual(tournament.turns, 100) self.assertEqual(tournament.repetitions, 10) self.assertEqual(tournament.name, 'test') self.assertTrue(tournament._with_morality) self.assertIsInstance(tournament._logger, logging.Logger) self.assertEqual(tournament.noise, 0.2) anonymous_tournament = axelrod.Tournament(players=self.players) self.assertEqual(anonymous_tournament.name, 'axelrod') @given(strategies=strategy_lists(strategies=deterministic_strategies, min_size=2, max_size=2), turns=integers(min_value=1, max_value=20)) def test_complete_tournament(self, strategies, turns): """ A test to check that a spatial tournament on the complete multigraph gives the same results as the round robin. """ players = [s() for s in strategies] # edges edges=[] for i in range(0, len(players)) : for j in range(i, len(players)) : edges.append((i, j)) # create a round robin tournament tournament = axelrod.Tournament(players, turns=turns) results = tournament.play() # create a complete spatial tournament spatial_tournament = axelrod.SpatialTournament(players, turns=turns, edges=edges) spatial_results = spatial_tournament.play() self.assertEqual(results.ranked_names, spatial_results.ranked_names) self.assertEqual(results.nplayers, spatial_results.nplayers) self.assertEqual(results.nrepetitions, spatial_results.nrepetitions) self.assertEqual(results.payoff_diffs_means, spatial_results.payoff_diffs_means) self.assertEqual(results.payoff_matrix, spatial_results.payoff_matrix) self.assertEqual(results.payoff_stddevs, spatial_results.payoff_stddevs) self.assertEqual(results.payoffs, spatial_results.payoffs) self.assertEqual(results.cooperating_rating, spatial_results.cooperating_rating) self.assertEqual(results.cooperation, spatial_results.cooperation) self.assertEqual(results.normalised_cooperation, spatial_results.normalised_cooperation) self.assertEqual(results.normalised_scores, spatial_results.normalised_scores) self.assertEqual(results.good_partner_matrix, spatial_results.good_partner_matrix) self.assertEqual(results.good_partner_rating, spatial_results.good_partner_rating)
class TestFingerprint(unittest.TestCase): @classmethod def setUpClass(cls): cls.strategy = axl.WinStayLoseShift cls.probe = axl.TitForTat cls.expected_points = [(0.0, 0.0), (0.0, 0.5), (0.0, 1.0), (0.5, 0.0), (0.5, 0.5), (0.5, 1.0), (1.0, 0.0), (1.0, 0.5), (1.0, 1.0)] cls.expected_edges = [(0, 1), (0, 2), (0, 3), (0, 4), (0, 5), (0, 6), (0, 7), (0, 8), (0, 9)] def test_create_points(self): test_points = create_points(0.5, progress_bar=False) self.assertEqual(test_points, self.expected_points) def test_create_jossann(self): # x + y < 1 ja = create_jossann((.5, .4), self.probe) self.assertEqual(str(ja), "Joss-Ann Tit For Tat: (0.5, 0.4)") # x + y = 1 ja = create_jossann((.4, .6), self.probe) self.assertEqual(str(ja), "Dual Joss-Ann Tit For Tat: (0.6, 0.4)") # x + y > 1 ja = create_jossann((.5, .6), self.probe) self.assertEqual(str(ja), "Dual Joss-Ann Tit For Tat: (0.5, 0.4)") def test_create_jossann_parametrised_player(self): probe = axl.Random(p=0.1) # x + y < 1 ja = create_jossann((.5, .4), probe) self.assertEqual(str(ja), "Joss-Ann Random: 0.1: (0.5, 0.4)") # x + y = 1 ja = create_jossann((.4, .6), probe) self.assertEqual(str(ja), "Dual Joss-Ann Random: 0.1: (0.6, 0.4)") # x + y > 1 ja = create_jossann((.5, .6), probe) self.assertEqual(str(ja), "Dual Joss-Ann Random: 0.1: (0.5, 0.4)") def test_create_probes(self): probes = create_probes(self.probe, self.expected_points, progress_bar=False) self.assertEqual(len(probes), 9) def test_create_edges(self): edges = create_edges(self.expected_points, progress_bar=False) self.assertEqual(edges, self.expected_edges) def test_generate_data(self): interactions = { (0, 1): [[(C, C)], [(C, C)]], (0, 2): [[(C, C), (C, C)], [(C, D)]], (0, 3): [[(C, C), (D, C)]], (0, 4): [[(C, C), (D, C)], [(D, D)]], (0, 5): [[(C, D), (D, C)]], (0, 6): [[(C, D), (C, D)]], (0, 7): [[(C, D), (D, D)]], (0, 8): [[(D, D), (D, D)]], (0, 9): [[(D, C), (D, C)]], } expected = { Point(0.0, 0.0): 3.0, Point(0.0, 0.5): 1.5, Point(0.0, 1.0): 4.0, Point(0.5, 0.0): 2.5, Point(0.5, 0.5): 2.5, Point(0.5, 1.0): 0.0, Point(1.0, 0.0): 0.5, Point(1.0, 0.5): 1.0, Point(1.0, 1.0): 5.0, } data = generate_data(interactions, self.expected_points, self.expected_edges) self.assertEqual(data, expected) def test_reshape_data(self): test_points = [ Point(x=0.0, y=0.0), Point(x=0.0, y=0.5), Point(x=0.0, y=1.0), Point(x=0.5, y=0.0), Point(x=0.5, y=0.5), Point(x=0.5, y=1.0), Point(x=1.0, y=0.0), Point(x=1.0, y=0.5), Point(x=1.0, y=1.0) ] test_data = { Point(x=0.0, y=0.0): 5, Point(x=0.0, y=0.5): 9, Point(x=0.0, y=1.0): 3, Point(x=0.5, y=0.0): 8, Point(x=0.5, y=0.5): 2, Point(x=0.5, y=1.0): 4, Point(x=1.0, y=0.0): 2, Point(x=1.0, y=0.5): 1, Point(x=1.0, y=1.0): 9 } test_shaped_data = [[3, 4, 9], [9, 2, 1], [5, 8, 2]] plotting_data = reshape_data(test_data, test_points, 3) for i in range(len(plotting_data)): self.assertEqual(list(plotting_data[i]), test_shaped_data[i]) def test_default_init(self): fingerprint = AshlockFingerprint(self.strategy) self.assertEqual(fingerprint.strategy, self.strategy) self.assertEqual(fingerprint.probe, self.probe) def test_init(self): fingerprint = AshlockFingerprint(self.strategy, self.probe) self.assertEqual(fingerprint.strategy, self.strategy) self.assertEqual(fingerprint.probe, self.probe) def test_init_with_instance(self): player = self.strategy() fingerprint = AshlockFingerprint(player) self.assertEqual(fingerprint.strategy, player) self.assertEqual(fingerprint.probe, self.probe) probe_player = self.probe() fingerprint = AshlockFingerprint(self.strategy, probe_player) self.assertEqual(fingerprint.strategy, self.strategy) self.assertEqual(fingerprint.probe, probe_player) fingerprint = AshlockFingerprint(player, probe_player) self.assertEqual(fingerprint.strategy, player) self.assertEqual(fingerprint.probe, probe_player) def test_construct_tournament_elemets(self): af = AshlockFingerprint(self.strategy, self.probe) edges, tournament_players = af.construct_tournament_elements( 0.5, progress_bar=False) self.assertEqual(edges, self.expected_edges) self.assertEqual(len(tournament_players), 10) self.assertEqual(tournament_players[0].__class__, af.strategy) def test_progress_bar_fingerprint(self): af = AshlockFingerprint(self.strategy, self.probe) data = af.fingerprint(turns=10, repetitions=2, step=0.5, progress_bar=True) self.assertEqual(sorted(data.keys()), self.expected_points) def test_fingerprint_with_filename(self): filename = "test_outputs/test_fingerprint.csv" af = AshlockFingerprint(self.strategy, self.probe) af.fingerprint(turns=1, repetitions=1, step=0.5, progress_bar=False, filename=filename) with open(filename, 'r') as out: data = out.read() self.assertEqual(len(data.split("\n")), 10) def test_in_memory_fingerprint(self): af = AshlockFingerprint(self.strategy, self.probe) af.fingerprint(turns=10, repetitions=2, step=0.5, progress_bar=False, in_memory=True) edge_keys = sorted(list(af.interactions.keys())) coord_keys = sorted(list(af.data.keys())) self.assertEqual(af.step, 0.5) self.assertEqual(af.spatial_tournament.interactions_dict, af.interactions) self.assertEqual(edge_keys, self.expected_edges) self.assertEqual(coord_keys, self.expected_points) def test_serial_fingerprint(self): af = AshlockFingerprint(self.strategy, self.probe) data = af.fingerprint(turns=10, repetitions=2, step=0.5, progress_bar=False) edge_keys = sorted(list(af.interactions.keys())) coord_keys = sorted(list(data.keys())) self.assertEqual(af.step, 0.5) self.assertEqual(edge_keys, self.expected_edges) self.assertEqual(coord_keys, self.expected_points) @unittest.skipIf(axl.on_windows, "Parallel processing not supported on Windows") def test_parallel_fingerprint(self): af = AshlockFingerprint(self.strategy, self.probe) af.fingerprint(turns=10, repetitions=2, step=0.5, processes=2, progress_bar=False) edge_keys = sorted(list(af.interactions.keys())) coord_keys = sorted(list(af.data.keys())) self.assertEqual(af.step, 0.5) self.assertEqual(edge_keys, self.expected_edges) self.assertEqual(coord_keys, self.expected_points) def test_plot(self): af = AshlockFingerprint(self.strategy, self.probe) af.fingerprint(turns=10, repetitions=2, step=0.25, progress_bar=False) p = af.plot() self.assertIsInstance(p, matplotlib.pyplot.Figure) q = af.plot(col_map='jet') self.assertIsInstance(q, matplotlib.pyplot.Figure) r = af.plot(interpolation='bicubic') self.assertIsInstance(r, matplotlib.pyplot.Figure) t = af.plot(title='Title') self.assertIsInstance(t, matplotlib.pyplot.Figure) u = af.plot(colorbar=False) self.assertIsInstance(u, matplotlib.pyplot.Figure) v = af.plot(labels=False) self.assertIsInstance(v, matplotlib.pyplot.Figure) def test_wsls_fingerprint(self): axl.seed(0) # Fingerprinting is a random process test_data = { Point(x=0.25, y=1.0): 0.84, Point(x=0.25, y=0.5): 1.85, Point(x=0.75, y=0.5): 3.01, Point(x=0.25, y=0.25): 2.23, Point(x=0.0, y=0.75): 1.08, Point(x=0.75, y=1.0): 1.14, Point(x=0.5, y=0.25): 2.66, Point(x=0.0, y=0.0): 3.0, Point(x=0.75, y=0.25): 3.12, Point(x=1.0, y=0.75): 3.57, Point(x=1.0, y=0.5): 3.94, Point(x=1.0, y=0.0): 3.0, Point(x=1.0, y=0.25): 4.78, Point(x=0.0, y=1.0): 0.5, Point(x=0.5, y=0.0): 3.0, Point(x=0.25, y=0.0): 3.0, Point(x=0.0, y=0.25): 1.71, Point(x=0.0, y=0.5): 1.44, Point(x=0.5, y=0.75): 1.62, Point(x=0.5, y=0.5): 2.77, Point(x=0.75, y=0.75): 2.27, Point(x=0.5, y=1.0): 1.02, Point(x=0.75, y=0.0): 3.0, Point(x=0.25, y=0.75): 1.27, Point(x=1.0, y=1.0): 1.3 } af = axl.AshlockFingerprint(self.strategy, self.probe) data = af.fingerprint(turns=50, repetitions=2, step=0.25, progress_bar=False) for key, value in data.items(): self.assertAlmostEqual(value, test_data[key], places=2) def test_tft_fingerprint(self): axl.seed(0) # Fingerprinting is a random process test_data = { Point(x=0.25, y=1.0): 1.63, Point(x=0.25, y=0.5): 1.92, Point(x=0.75, y=0.5): 2.33, Point(x=0.25, y=0.25): 2.31, Point(x=0.0, y=0.75): 1.05, Point(x=0.75, y=1.0): 2.07, Point(x=0.5, y=0.25): 2.6, Point(x=0.0, y=0.0): 3.0, Point(x=0.75, y=0.25): 2.76, Point(x=1.0, y=0.75): 2.38, Point(x=1.0, y=0.5): 2.58, Point(x=1.0, y=0.0): 3.0, Point(x=1.0, y=0.25): 2.72, Point(x=0.0, y=1.0): 0.98, Point(x=0.5, y=0.0): 3.0, Point(x=0.25, y=0.0): 3.0, Point(x=0.0, y=0.25): 1.82, Point(x=0.0, y=0.5): 1.13, Point(x=0.5, y=0.75): 1.93, Point(x=0.5, y=0.5): 2.46, Point(x=0.75, y=0.75): 2.3, Point(x=0.5, y=1.0): 1.91, Point(x=0.75, y=0.0): 3.0, Point(x=0.25, y=0.75): 1.62, Point(x=1.0, y=1.0): 2.18 } af = axl.AshlockFingerprint(axl.TitForTat, self.probe) data = af.fingerprint(turns=50, repetitions=2, step=0.25, progress_bar=False) for key, value in data.items(): self.assertAlmostEqual(value, test_data[key], places=2) def test_majority_fingerprint(self): axl.seed(0) # Fingerprinting is a random process test_data = { Point(x=0.25, y=1.0): 2.179, Point(x=0.25, y=0.5): 1.9, Point(x=0.75, y=0.5): 1.81, Point(x=0.25, y=0.25): 2.31, Point(x=0.0, y=0.75): 1.03, Point(x=0.75, y=1.0): 2.58, Point(x=0.5, y=0.25): 2.34, Point(x=0.0, y=0.0): 3.0, Point(x=0.75, y=0.25): 2.4, Point(x=1.0, y=0.75): 2.0, Point(x=1.0, y=0.5): 1.74, Point(x=1.0, y=0.0): 3.0, Point(x=1.0, y=0.25): 2.219, Point(x=0.0, y=1.0): 0.98, Point(x=0.5, y=0.0): 3.0, Point(x=0.25, y=0.0): 3.0, Point(x=0.0, y=0.25): 1.94, Point(x=0.0, y=0.5): 1.13, Point(x=0.5, y=0.75): 2.6, Point(x=0.5, y=0.5): 1.89, Point(x=0.75, y=0.75): 2.13, Point(x=0.5, y=1.0): 2.7, Point(x=0.75, y=0.0): 3.0, Point(x=0.25, y=0.75): 1.859, Point(x=1.0, y=1.0): 2.26 } af = axl.AshlockFingerprint(axl.GoByMajority, self.probe) data = af.fingerprint(turns=50, repetitions=2, step=0.25, progress_bar=False) for key, value in data.items(): self.assertAlmostEqual(value, test_data[key], places=2) @given(strategy_pair=strategy_lists(min_size=2, max_size=2)) def test_pair_fingerprints(self, strategy_pair): """ A test to check that we can fingerprint with any two given strategies or instances """ strategy, probe = strategy_pair af = AshlockFingerprint(strategy, probe) data = af.fingerprint(turns=2, repetitions=2, step=0.5, progress_bar=False) self.assertIsInstance(data, dict) af = AshlockFingerprint(strategy(), probe) data = af.fingerprint(turns=2, repetitions=2, step=0.5, progress_bar=False) self.assertIsInstance(data, dict) af = AshlockFingerprint(strategy, probe()) data = af.fingerprint(turns=2, repetitions=2, step=0.5, progress_bar=False) self.assertIsInstance(data, dict) af = AshlockFingerprint(strategy(), probe()) data = af.fingerprint(turns=2, repetitions=2, step=0.5, progress_bar=False) self.assertIsInstance(data, dict)
class TestContriteTitForTat(TestPlayer): name = "Contrite Tit For Tat" player = axl.ContriteTitForTat expected_classifier = { "memory_depth": 3, "stochastic": False, "makes_use_of": set(), "inspects_source": False, "manipulates_source": False, "manipulates_state": False, } deterministic_strategies = [ s for s in axl.strategies if not axl.Classifiers["stochastic"](s()) ] def test_init(self): ctft = self.player() self.assertFalse(ctft.contrite, False) self.assertEqual(ctft._recorded_history, []) @given( strategies=strategy_lists(strategies=deterministic_strategies, max_size=1), turns=integers(min_value=1, max_value=20), ) def test_is_tit_for_tat_with_no_noise(self, strategies, turns): tft = axl.TitForTat() ctft = self.player() opponent = strategies[0]() m1 = axl.Match((tft, opponent), turns) m2 = axl.Match((ctft, opponent), turns) self.assertEqual(m1.play(), m2.play()) def test_strategy_with_noise(self): ctft = self.player() opponent = axl.Defector() self.assertEqual(ctft.strategy(opponent), C) self.assertEqual(ctft._recorded_history, [C]) ctft.reset() # Clear the recorded history self.assertEqual(ctft._recorded_history, []) random.seed(0) ctft.play(opponent, noise=0.9) self.assertEqual(ctft.history, [D]) self.assertEqual(ctft._recorded_history, [C]) self.assertEqual(opponent.history, [C]) # After noise: is contrite ctft.play(opponent) self.assertEqual(ctft.history, [D, C]) self.assertEqual(ctft._recorded_history, [C, C]) self.assertEqual(opponent.history, [C, D]) self.assertTrue(ctft.contrite) # Cooperates and no longer contrite ctft.play(opponent) self.assertEqual(ctft.history, [D, C, C]) self.assertEqual(ctft._recorded_history, [C, C, C]) self.assertEqual(opponent.history, [C, D, D]) self.assertFalse(ctft.contrite) # Goes back to playing tft ctft.play(opponent) self.assertEqual(ctft.history, [D, C, C, D]) self.assertEqual(ctft._recorded_history, [C, C, C, D]) self.assertEqual(opponent.history, [C, D, D, D]) self.assertFalse(ctft.contrite)
class TestContriteTitForTat(TestPlayer): name = "Contrite Tit For Tat" player = axelrod.ContriteTitForTat expected_classifier = { 'memory_depth': 3, 'stochastic': False, 'makes_use_of': set(), 'inspects_source': False, 'manipulates_source': False, 'manipulates_state': False } deterministic_strategies = [s for s in axelrod.strategies if not s().classifier['stochastic']] @given(strategies=strategy_lists(strategies=deterministic_strategies, max_size=1), turns=integers(min_value=1, max_value=20)) def test_is_tit_for_tat_with_no_noise(self, strategies, turns): tft = axelrod.TitForTat() ctft = self.player() opponent = strategies[0]() m1 = axelrod.Match((tft, opponent), turns) m2 = axelrod.Match((ctft, opponent), turns) self.assertEqual(m1.play(), m2.play()) def test_strategy_with_noise(self): ctft = self.player() opponent = axelrod.Defector() self.assertEqual(ctft.strategy(opponent), C) self.assertEqual(ctft._recorded_history, [C]) ctft.reset() # Clear the recorded history self.assertEqual(ctft._recorded_history, []) random.seed(0) ctft.play(opponent, noise=.9) self.assertEqual(ctft.history, [D]) self.assertEqual(ctft._recorded_history, [C]) self.assertEqual(opponent.history, [C]) # After noise: is contrite ctft.play(opponent) self.assertEqual(ctft.history, [D, C]) self.assertEqual(ctft._recorded_history, [C, C]) self.assertEqual(opponent.history, [C, D]) self.assertTrue(ctft.contrite) # Cooperates and no longer contrite ctft.play(opponent) self.assertEqual(ctft.history, [D, C, C]) self.assertEqual(ctft._recorded_history, [C, C, C]) self.assertEqual(opponent.history, [C, D, D]) self.assertFalse(ctft.contrite) # Goes back to playing tft ctft.play(opponent) self.assertEqual(ctft.history, [D, C, C, D]) self.assertEqual(ctft._recorded_history, [C, C, C, D]) self.assertEqual(opponent.history, [C, D, D, D]) self.assertFalse(ctft.contrite) def test_reset_cleans_all(self): p = self.player() p.contrite = True p.reset() self.assertFalse(p.contrite)
class TestFiltersAgainstComprehensions(unittest.TestCase): """ Test that the results of filtering strategies via a filterset dict match the results from using a list comprehension. """ def setUp(self) -> None: # Ignore warnings about classifiers running on instances warnings.simplefilter("ignore", category=UserWarning) def tearDown(self) -> None: warnings.simplefilter("default", category=UserWarning) @settings(deadline=None) @given(strategies=strategy_lists(min_size=20, max_size=20)) @example(strategies=[axl.DBS, axl.Cooperator]) def test_boolean_filtering(self, strategies): classifiers = [ "stochastic", "long_run_time", "manipulates_state", "manipulates_source", "inspects_source", ] for classifier in classifiers: comprehension = set(filter(axl.Classifiers[classifier], strategies)) filterset = {classifier: True} filtered = set(axl.filtered_strategies(filterset, strategies=strategies)) self.assertEqual(comprehension, filtered) @given( min_memory_depth=integers(min_value=1, max_value=10), max_memory_depth=integers(min_value=1, max_value=10), memory_depth=integers(min_value=1, max_value=10), strategies=strategy_lists(min_size=20, max_size=20), ) @example( min_memory_depth=float("inf"), max_memory_depth=float("inf"), memory_depth=float("inf"), strategies=axl.short_run_time_strategies, ) @settings(max_examples=5, deadline=None) def test_memory_depth_filtering( self, min_memory_depth, max_memory_depth, memory_depth, strategies ): min_comprehension = set( [ s for s in strategies if axl.Classifiers["memory_depth"](s) >= min_memory_depth ] ) min_filterset = {"min_memory_depth": min_memory_depth} min_filtered = set( axl.filtered_strategies(min_filterset, strategies=strategies) ) self.assertEqual(min_comprehension, min_filtered) max_comprehension = set( [ s for s in strategies if axl.Classifiers["memory_depth"](s) <= max_memory_depth ] ) max_filterset = {"max_memory_depth": max_memory_depth} max_filtered = set( axl.filtered_strategies(max_filterset, strategies=strategies) ) self.assertEqual(max_comprehension, max_filtered) comprehension = set( [ s for s in strategies if axl.Classifiers["memory_depth"](s) == memory_depth ] ) filterset = {"memory_depth": memory_depth} filtered = set(axl.filtered_strategies(filterset, strategies=strategies)) self.assertEqual(comprehension, filtered) @given(strategies=strategy_lists(min_size=20, max_size=20)) @settings(max_examples=5, deadline=None) def test_makes_use_of_filtering(self, strategies): """ Test equivalent filtering using two approaches. """ classifiers = [["game"], ["length"], ["game", "length"]] for classifier in classifiers: comprehension = set( [ s for s in strategies if set(classifier).issubset(set(axl.Classifiers["makes_use_of"](s))) ] ) filterset = {"makes_use_of": classifier} filtered = set(axl.filtered_strategies(filterset, strategies=strategies)) self.assertEqual( comprehension, filtered, msg="classifier: {}".format(classifier) )
class TestProbEndingSpatialTournament(unittest.TestCase): @classmethod def setUpClass(cls): cls.game = axelrod.Game() cls.players = [s() for s in test_strategies] cls.test_name = "test" cls.test_repetitions = test_repetitions cls.test_prob_end = test_prob_end cls.test_edges = test_edges def test_init(self): tournament = axelrod.Tournament( name=self.test_name, players=self.players, game=self.game, prob_end=self.test_prob_end, edges=self.test_edges, noise=0.2, ) self.assertEqual(tournament.match_generator.edges, tournament.edges) self.assertEqual(len(tournament.players), len(test_strategies)) self.assertEqual(tournament.game.score((C, C)), (3, 3)) self.assertIsNone(tournament.turns) self.assertEqual(tournament.repetitions, 10) self.assertEqual(tournament.name, "test") self.assertIsInstance(tournament._logger, logging.Logger) self.assertEqual(tournament.noise, 0.2) self.assertEqual(tournament.match_generator.noise, 0.2) self.assertEqual(tournament.prob_end, self.test_prob_end) @given( strategies=strategy_lists(strategies=deterministic_strategies, min_size=2, max_size=2), prob_end=floats(min_value=.1, max_value=.9), reps=integers(min_value=1, max_value=3), seed=integers(min_value=0, max_value=4294967295), ) @settings(max_examples=5, max_iterations=20) def test_complete_tournament(self, strategies, prob_end, seed, reps): """ A test to check that a spatial tournament on the complete graph gives the same results as the round robin. """ players = [s() for s in strategies] # create a prob end round robin tournament tournament = axelrod.Tournament(players, prob_end=prob_end, repetitions=reps) axelrod.seed(seed) results = tournament.play(progress_bar=False) # create a complete spatial tournament # edges edges = [(i, j) for i in range(len(players)) for j in range(i, len(players))] spatial_tournament = axelrod.Tournament(players, prob_end=prob_end, repetitions=reps, edges=edges) axelrod.seed(seed) spatial_results = spatial_tournament.play(progress_bar=False) self.assertEqual(results.match_lengths, spatial_results.match_lengths) self.assertEqual(results.ranked_names, spatial_results.ranked_names) self.assertEqual(results.wins, spatial_results.wins) self.assertEqual(results.scores, spatial_results.scores) self.assertEqual(results.cooperation, spatial_results.cooperation) @given( tournament=spatial_tournaments( strategies=axelrod.basic_strategies, max_turns=1, max_noise=0, max_repetitions=3, ), seed=integers(min_value=0, max_value=4294967295), ) @settings(max_examples=5, max_iterations=20) def test_one_turn_tournament(self, tournament, seed): """ Tests that gives same result as the corresponding spatial round robin spatial tournament """ prob_end_tour = axelrod.Tournament( tournament.players, prob_end=1, edges=tournament.edges, repetitions=tournament.repetitions, ) axelrod.seed(seed) prob_end_results = prob_end_tour.play(progress_bar=False) axelrod.seed(seed) one_turn_results = tournament.play(progress_bar=False) self.assertEqual(prob_end_results.scores, one_turn_results.scores) self.assertEqual(prob_end_results.wins, one_turn_results.wins) self.assertEqual(prob_end_results.cooperation, one_turn_results.cooperation)
class TestMoranProcess(unittest.TestCase): def test_init(self): players = axelrod.Cooperator(), axelrod.Defector() mp = MoranProcess(players) self.assertEqual(mp.turns, axelrod.DEFAULT_TURNS) self.assertIsNone(mp.prob_end) self.assertIsNone(mp.game) self.assertEqual(mp.noise, 0) self.assertEqual(mp.initial_players, players) self.assertEqual(mp.players, list(players)) self.assertEqual(mp.populations, [Counter({"Cooperator": 1, "Defector": 1})]) self.assertIsNone(mp.winning_strategy_name) self.assertEqual(mp.mutation_rate, 0) self.assertEqual(mp.mode, "bd") self.assertEqual(mp.deterministic_cache, axelrod.DeterministicCache()) self.assertEqual( mp.mutation_targets, {"Cooperator": [players[1]], "Defector": [players[0]]} ) self.assertEqual(mp.interaction_graph._edges, [(0, 1), (1, 0)]) self.assertEqual(mp.reproduction_graph._edges, [(0, 1), (1, 0), (0, 0), (1, 1)]) self.assertEqual(mp.fitness_transformation, None) self.assertEqual(mp.locations, [0, 1]) self.assertEqual(mp.index, {0: 0, 1: 1}) # Test non default graph cases players = axelrod.Cooperator(), axelrod.Defector(), axelrod.TitForTat() edges = [(0, 1), (2, 0), (1, 2)] graph = axelrod.graph.Graph(edges, directed=True) mp = MoranProcess(players, interaction_graph=graph) self.assertEqual(mp.interaction_graph._edges, [(0, 1), (2, 0), (1, 2)]) self.assertEqual( sorted(mp.reproduction_graph._edges), sorted([(0, 1), (2, 0), (1, 2), (0, 0), (1, 1), (2, 2)]), ) mp = MoranProcess(players, interaction_graph=graph, reproduction_graph=graph) self.assertEqual(mp.interaction_graph._edges, [(0, 1), (2, 0), (1, 2)]) self.assertEqual(mp.reproduction_graph._edges, [(0, 1), (2, 0), (1, 2)]) def test_set_players(self): """Test that set players resets all players""" players = axelrod.Cooperator(), axelrod.Defector() mp = MoranProcess(players) players[0].cooperations += 1 mp.set_players() self.assertEqual(players[0].cooperations, 0) def test_mutate(self): """Test that a mutated player is returned""" players = axelrod.Cooperator(), axelrod.Defector(), axelrod.TitForTat() mp = MoranProcess(players, mutation_rate=0.5) axelrod.seed(0) self.assertEqual(mp.mutate(0), players[0]) axelrod.seed(1) self.assertEqual(mp.mutate(0), players[2]) axelrod.seed(4) self.assertEqual(mp.mutate(0), players[1]) def test_death_in_db(self): players = axelrod.Cooperator(), axelrod.Defector(), axelrod.TitForTat() mp = MoranProcess(players, mutation_rate=0.5, mode="db") axelrod.seed(1) self.assertEqual(mp.death(), 0) self.assertEqual(mp.dead, 0) axelrod.seed(5) self.assertEqual(mp.death(), 1) self.assertEqual(mp.dead, 1) axelrod.seed(2) self.assertEqual(mp.death(), 2) self.assertEqual(mp.dead, 2) def test_death_in_bd(self): players = axelrod.Cooperator(), axelrod.Defector(), axelrod.TitForTat() edges = [(0, 1), (2, 0), (1, 2)] graph = axelrod.graph.Graph(edges, directed=True) mp = MoranProcess(players, mode="bd", interaction_graph=graph) axelrod.seed(1) self.assertEqual(mp.death(0), 0) axelrod.seed(5) self.assertEqual(mp.death(0), 1) axelrod.seed(2) self.assertEqual(mp.death(0), 0) def test_birth_in_db(self): players = axelrod.Cooperator(), axelrod.Defector(), axelrod.TitForTat() mp = MoranProcess(players, mode="db") axelrod.seed(1) self.assertEqual(mp.death(), 0) self.assertEqual(mp.birth(0), 2) def test_birth_in_bd(self): players = axelrod.Cooperator(), axelrod.Defector(), axelrod.TitForTat() mp = MoranProcess(players, mode="bd") axelrod.seed(1) self.assertEqual(mp.birth(), 0) def test_fixation_check(self): players = axelrod.Cooperator(), axelrod.Cooperator() mp = MoranProcess(players) self.assertTrue(mp.fixation_check()) players = axelrod.Cooperator(), axelrod.Defector() mp = MoranProcess(players) self.assertFalse(mp.fixation_check()) def test_next(self): players = axelrod.Cooperator(), axelrod.Defector() mp = MoranProcess(players) self.assertIsInstance(next(mp), MoranProcess) def test_matchup_indices(self): players = axelrod.Cooperator(), axelrod.Defector() mp = MoranProcess(players) self.assertEqual(mp._matchup_indices(), {(0, 1)}) players = axelrod.Cooperator(), axelrod.Defector(), axelrod.TitForTat() edges = [(0, 1), (2, 0), (1, 2)] graph = axelrod.graph.Graph(edges, directed=True) mp = MoranProcess(players, mode="bd", interaction_graph=graph) self.assertEqual(mp._matchup_indices(), {(0, 1), (1, 2), (2, 0)}) def test_fps(self): self.assertEqual(fitness_proportionate_selection([0, 0, 1]), 2) axelrod.seed(1) self.assertEqual(fitness_proportionate_selection([1, 1, 1]), 0) self.assertEqual(fitness_proportionate_selection([1, 1, 1]), 2) def test_exit_condition(self): p1, p2 = axelrod.Cooperator(), axelrod.Cooperator() mp = MoranProcess((p1, p2)) mp.play() self.assertEqual(len(mp), 1) def test_two_players(self): p1, p2 = axelrod.Cooperator(), axelrod.Defector() axelrod.seed(17) mp = MoranProcess((p1, p2)) populations = mp.play() self.assertEqual(len(mp), 5) self.assertEqual(len(populations), 5) self.assertEqual(populations, mp.populations) self.assertEqual(mp.winning_strategy_name, str(p2)) def test_two_prob_end(self): p1, p2 = axelrod.Random(), axelrod.TitForTat() axelrod.seed(0) mp = MoranProcess((p1, p2), prob_end=.5) populations = mp.play() self.assertEqual(len(mp), 4) self.assertEqual(len(populations), 4) self.assertEqual(populations, mp.populations) self.assertEqual(mp.winning_strategy_name, str(p1)) def test_different_game(self): # Possible for Cooperator to become fixed when using a different game p1, p2 = axelrod.Cooperator(), axelrod.Defector() axelrod.seed(0) game = axelrod.Game(r=4, p=2, s=1, t=6) mp = MoranProcess((p1, p2), turns=5, game=game) populations = mp.play() self.assertEqual(mp.winning_strategy_name, str(p1)) def test_death_birth(self): """Two player death-birth should fixate after one round.""" p1, p2 = axelrod.Cooperator(), axelrod.Defector() seeds = range(0, 20) for seed in seeds: axelrod.seed(seed) mp = MoranProcess((p1, p2), mode="db") next(mp) self.assertIsNotNone(mp.winning_strategy_name) def test_death_birth_outcomes(self): """Show that birth-death and death-birth can produce different outcomes.""" seeds = [(1, True), (23, False)] players = [] N = 6 for _ in range(N // 2): players.append(axelrod.Cooperator()) players.append(axelrod.Defector()) for seed, outcome in seeds: axelrod.seed(seed) mp = MoranProcess(players, mode="bd") mp.play() winner = mp.winning_strategy_name axelrod.seed(seed) mp = MoranProcess(players, mode="db") mp.play() winner2 = mp.winning_strategy_name self.assertEqual((winner == winner2), outcome) def test_two_random_players(self): p1, p2 = axelrod.Random(p=0.5), axelrod.Random(p=0.25) axelrod.seed(0) mp = MoranProcess((p1, p2)) populations = mp.play() self.assertEqual(len(mp), 2) self.assertEqual(len(populations), 2) self.assertEqual(populations, mp.populations) self.assertEqual(mp.winning_strategy_name, str(p2)) def test_two_players_with_mutation(self): p1, p2 = axelrod.Cooperator(), axelrod.Defector() axelrod.seed(5) mp = MoranProcess((p1, p2), mutation_rate=0.2) self.assertDictEqual(mp.mutation_targets, {str(p1): [p2], str(p2): [p1]}) # Test that mutation causes the population to alternate between # fixations counters = [ Counter({"Cooperator": 2}), Counter({"Defector": 2}), Counter({"Cooperator": 2}), Counter({"Defector": 2}), ] for counter in counters: for _ in itertools.takewhile( lambda x: x.population_distribution() != counter, mp ): pass self.assertEqual(mp.population_distribution(), counter) def test_play_exception(self): p1, p2 = axelrod.Cooperator(), axelrod.Defector() mp = MoranProcess((p1, p2), mutation_rate=0.2) with self.assertRaises(ValueError): mp.play() def test_three_players(self): players = [axelrod.Cooperator(), axelrod.Cooperator(), axelrod.Defector()] axelrod.seed(11) mp = MoranProcess(players) populations = mp.play() self.assertEqual(len(mp), 7) self.assertEqual(len(populations), 7) self.assertEqual(populations, mp.populations) self.assertEqual(mp.winning_strategy_name, str(axelrod.Defector())) def test_three_players_with_mutation(self): p1 = axelrod.Cooperator() p2 = axelrod.Random() p3 = axelrod.Defector() players = [p1, p2, p3] mp = MoranProcess(players, mutation_rate=0.2) self.assertDictEqual( mp.mutation_targets, {str(p1): [p3, p2], str(p2): [p1, p3], str(p3): [p1, p2]}, ) # Test that mutation causes the population to alternate between # fixations counters = [Counter({"Cooperator": 3}), Counter({"Defector": 3})] for counter in counters: for _ in itertools.takewhile( lambda x: x.population_distribution() != counter, mp ): pass self.assertEqual(mp.population_distribution(), counter) def test_four_players(self): players = [axelrod.Cooperator() for _ in range(3)] players.append(axelrod.Defector()) axelrod.seed(29) mp = MoranProcess(players) populations = mp.play() self.assertEqual(len(mp), 9) self.assertEqual(len(populations), 9) self.assertEqual(populations, mp.populations) self.assertEqual(mp.winning_strategy_name, str(axelrod.Defector())) @given(strategies=strategy_lists(min_size=2, max_size=4)) @settings(max_examples=5, max_iterations=20) # Two specific examples relating to cloning of strategies @example(strategies=[axelrod.BackStabber, axelrod.MindReader]) @example(strategies=[axelrod.ThueMorse, axelrod.MindReader]) def test_property_players(self, strategies): """Hypothesis test that randomly checks players""" players = [s() for s in strategies] mp = MoranProcess(players) populations = mp.play() self.assertEqual(populations, mp.populations) self.assertIn(mp.winning_strategy_name, [str(p) for p in players]) def test_reset(self): p1, p2 = axelrod.Cooperator(), axelrod.Defector() axelrod.seed(45) mp = MoranProcess((p1, p2)) mp.play() self.assertEqual(len(mp), 4) self.assertEqual(len(mp.score_history), 3) mp.reset() self.assertEqual(len(mp), 1) self.assertEqual(mp.winning_strategy_name, None) self.assertEqual(mp.score_history, []) # Check that players reset for player, initial_player in zip(mp.players, mp.initial_players): self.assertEqual(str(player), str(initial_player)) def test_constant_fitness_case(self): # Scores between an Alternator and Defector will be: (1, 6) axelrod.seed(0) players = ( axelrod.Alternator(), axelrod.Alternator(), axelrod.Defector(), axelrod.Defector(), ) mp = MoranProcess(players, turns=2) winners = [] for _ in range(100): mp.play() winners.append(mp.winning_strategy_name) mp.reset() winners = Counter(winners) self.assertEqual(winners["Defector"], 88) def test_cache(self): p1, p2 = axelrod.Cooperator(), axelrod.Defector() mp = MoranProcess((p1, p2)) mp.play() self.assertEqual(len(mp.deterministic_cache), 1) # Check that can pass a pre built cache cache = axelrod.DeterministicCache() mp = MoranProcess((p1, p2), deterministic_cache=cache) self.assertEqual(cache, mp.deterministic_cache) def test_iter(self): p1, p2 = axelrod.Cooperator(), axelrod.Defector() mp = MoranProcess((p1, p2)) self.assertEqual(mp.__iter__(), mp) def test_population_plot(self): # Test that can plot on a given matplotlib axes axelrod.seed(15) players = [random.choice(axelrod.demo_strategies)() for _ in range(5)] mp = axelrod.MoranProcess(players=players, turns=30) mp.play() fig, axarr = plt.subplots(2, 2) ax = axarr[1, 0] mp.populations_plot(ax=ax) self.assertEqual(ax.get_xlim(), (-0.8, 16.8)) self.assertEqual(ax.get_ylim(), (0, 5.25)) # Run without a given axis ax = mp.populations_plot() self.assertEqual(ax.get_xlim(), (-0.8, 16.8)) self.assertEqual(ax.get_ylim(), (0, 5.25)) def test_cooperator_can_win_with_fitness_transformation(self): axelrod.seed(689) players = ( axelrod.Cooperator(), axelrod.Defector(), axelrod.Defector(), axelrod.Defector(), ) w = 0.95 fitness_transformation = lambda score: 1 - w + w * score mp = MoranProcess( players, turns=10, fitness_transformation=fitness_transformation ) populations = mp.play() self.assertEqual(mp.winning_strategy_name, "Cooperator")
class TestFingerprint(unittest.TestCase): points_when_using_half_step = [ (0.0, 0.0), (0.0, 0.5), (0.0, 1.0), (0.5, 0.0), (0.5, 0.5), (0.5, 1.0), (1.0, 0.0), (1.0, 0.5), (1.0, 1.0), ] edges_when_using_half_step = [ (0, 1), (0, 2), (0, 3), (0, 4), (0, 5), (0, 6), (0, 7), (0, 8), (0, 9), ] def test_default_init(self): fingerprint = AshlockFingerprint(axl.WinStayLoseShift) self.assertEqual(fingerprint.strategy, axl.WinStayLoseShift) self.assertEqual(fingerprint.probe, axl.TitForTat) def test_init_with_explicit_probe(self): fingerprint = AshlockFingerprint(axl.WinStayLoseShift, axl.Random) self.assertEqual(fingerprint.strategy, axl.WinStayLoseShift) self.assertEqual(fingerprint.probe, axl.Random) def test_init_with_instances(self): player = axl.WinStayLoseShift() fingerprint = AshlockFingerprint(player) self.assertEqual(fingerprint.strategy, player) self.assertEqual(fingerprint.probe, axl.TitForTat) probe = axl.Random() fingerprint = AshlockFingerprint(axl.WinStayLoseShift, probe) self.assertEqual(fingerprint.strategy, axl.WinStayLoseShift) self.assertEqual(fingerprint.probe, probe) fingerprint = AshlockFingerprint(player, probe) self.assertEqual(fingerprint.strategy, player) self.assertEqual(fingerprint.probe, probe) def test_fingerprint_player(self): af = AshlockFingerprint(axl.Cooperator()) af.fingerprint(turns=5, repetitions=3, step=0.5, progress_bar=False) self.assertEqual(af.step, 0.5) self.assertEqual(af.points, self.points_when_using_half_step) self.assertEqual(af.spatial_tournament.turns, 5) self.assertEqual(af.spatial_tournament.repetitions, 3) self.assertEqual(af.spatial_tournament.edges, self.edges_when_using_half_step) # The first player is the fingerprinted one, the rest are probes. self.assertIsInstance(af.spatial_tournament.players[0], axl.Cooperator) self.assertEqual(len(af.spatial_tournament.players), 10) probes = af.spatial_tournament.players[1:] self.assertEqual(len(probes), len(af.points)) self.assertEqual(str(probes[0]), "Joss-Ann Tit For Tat: (0.0, 0.0)") # x + y < 1 self.assertEqual(str(probes[2]), "Dual Joss-Ann Tit For Tat: (1.0, 0.0)") # x + y = 1 self.assertEqual(str(probes[8]), "Dual Joss-Ann Tit For Tat: (0.0, 0.0)") # x + y > 1 def test_fingeprint_explicit_probe(self): af = AshlockFingerprint(axl.TitForTat(), probe=axl.Random(p=0.1)) af.fingerprint(turns=10, repetitions=2, step=0.5, progress_bar=False) probes = af.spatial_tournament.players[1:] self.assertEqual(str(probes[0]), "Joss-Ann Random: 0.1: (0.0, 0.0)") # x + y < 1 self.assertEqual(str(probes[2]), "Dual Joss-Ann Random: 0.1: (1.0, 0.0)") # x + y = 1 self.assertEqual(str(probes[8]), "Dual Joss-Ann Random: 0.1: (0.0, 0.0)") # x + y > 1 def test_fingerprint_interactions_cooperator(self): af = AshlockFingerprint(axl.Cooperator()) af.fingerprint(turns=5, repetitions=3, step=0.5, progress_bar=False) # The keys are edges between players, values are repetitions. self.assertCountEqual( af.interactions.keys(), [(0, 1), (0, 2), (0, 3), (0, 4), (0, 5), (0, 6), (0, 7), (0, 8), (0, 9)], ) self.assertEqual(len(af.interactions.values()), 9) # Each edge has 3 repetitions with 5 turns each. repetitions = af.interactions.values() self.assertTrue(all(len(rep) == 3 for rep in repetitions)) for iturn in range(3): self.assertTrue(all(len(rep[iturn]) == 5 for rep in repetitions)) # Interactions are invariant for any points where y is zero, and # the score should be maximum possible. # Player 1 is Point(0.0, 0.0). # Player 4 is Point(0.5, 0.0). # Player 7 is Point(1.0, 0.0). for iplayer in (1, 4, 7): for turns in af.interactions[(0, iplayer)]: self.assertEqual(len(turns), 5) self.assertTrue(all(t == (C, C) for t in turns)) self.assertEqual(af.data[Point(0.0, 0.0)], 3.0) self.assertEqual(af.data[Point(0.5, 0.0)], 3.0) self.assertEqual(af.data[Point(1.0, 0.0)], 3.0) # Player 3 is Point(0.0, 1.0), which means constant defection # from the probe. But the Cooperator doesn't change and score is zero. for turns in af.interactions[(0, 3)]: self.assertEqual(len(turns), 5) self.assertTrue(all(t == (C, D) for t in turns)) self.assertEqual(af.data[Point(0.0, 1.0)], 0.0) def test_fingerprint_interactions_titfortat(self): af = AshlockFingerprint(axl.TitForTat()) af.fingerprint(turns=5, repetitions=3, step=0.5, progress_bar=False) # Tit-for-Tats will always cooperate if left to their own devices, # so interactions are invariant for any points where y is zero, # and the score should be maximum possible. # Player 1 is Point(0.0, 0.0). # Player 4 is Point(0.5, 0.0). # Player 7 is Point(1.0, 0.0). for iplayer in (1, 4, 7): for turns in af.interactions[(0, iplayer)]: self.assertEqual(len(turns), 5) self.assertTrue(all(t == (C, C) for t in turns)) self.assertEqual(af.data[Point(0.0, 0.0)], 3.0) self.assertEqual(af.data[Point(0.5, 0.0)], 3.0) self.assertEqual(af.data[Point(1.0, 0.0)], 3.0) # Player 3 is Point(0.0, 1.0) which implies defection after the # first turn since Tit-for-Tat is playing, and a score of 0.8 # since we get zero on first turn and one point per turn later. for turns in af.interactions[(0, 3)]: self.assertEqual(len(turns), 5) self.assertTrue(all(t == (D, D) for t in turns[1:])) self.assertAlmostEqual(af.data[Point(0.0, 1.0)], 0.8) def test_progress_bar_fingerprint(self): af = AshlockFingerprint(axl.TitForTat) data = af.fingerprint(turns=10, repetitions=2, step=0.5, progress_bar=True) self.assertEqual(sorted(data.keys()), self.points_when_using_half_step) @patch("axelrod.fingerprint.mkstemp", RecordedMksTemp.mkstemp) def test_temp_file_creation(self): RecordedMksTemp.reset_record() af = AshlockFingerprint(axl.TitForTat) path = pathlib.Path("test_outputs/test_fingerprint.csv") filename = axl_filename(path) self.assertEqual(RecordedMksTemp.record, []) # Temp file is created and destroyed. af.fingerprint(turns=1, repetitions=1, step=0.5, progress_bar=False, filename=None) self.assertEqual(len(RecordedMksTemp.record), 1) filename = RecordedMksTemp.record[0][1] self.assertIsInstance(filename, str) self.assertNotEqual(filename, "") self.assertFalse(os.path.isfile(filename)) def test_fingerprint_with_filename(self): path = pathlib.Path("test_outputs/test_fingerprint.csv") filename = axl_filename(path) af = AshlockFingerprint(axl.TitForTat) af.fingerprint(turns=1, repetitions=1, step=0.5, progress_bar=False, filename=filename) with open(filename, "r") as out: data = out.read() self.assertEqual(len(data.split("\n")), 20) def test_serial_fingerprint(self): af = AshlockFingerprint(axl.TitForTat) data = af.fingerprint(turns=10, repetitions=2, step=0.5, progress_bar=False) edge_keys = sorted(list(af.interactions.keys())) coord_keys = sorted(list(data.keys())) self.assertEqual(af.step, 0.5) self.assertEqual(edge_keys, self.edges_when_using_half_step) self.assertEqual(coord_keys, self.points_when_using_half_step) def test_parallel_fingerprint(self): af = AshlockFingerprint(axl.TitForTat) af.fingerprint(turns=10, repetitions=2, step=0.5, processes=2, progress_bar=False) edge_keys = sorted(list(af.interactions.keys())) coord_keys = sorted(list(af.data.keys())) self.assertEqual(af.step, 0.5) self.assertEqual(edge_keys, self.edges_when_using_half_step) self.assertEqual(coord_keys, self.points_when_using_half_step) def test_plot_data(self): axl.seed(0) # Fingerprinting is a random process. af = AshlockFingerprint(axl.Cooperator()) af.fingerprint(turns=5, repetitions=3, step=0.5, progress_bar=False) reshaped_data = np.array([[0.0, 0.0, 0.0], [2.0, 1.0, 2.0], [3.0, 3.0, 3.0]]) plotted_data = af.plot().gca().images[0].get_array() np.testing.assert_allclose(plotted_data, reshaped_data) def test_plot_figure(self): af = AshlockFingerprint(axl.WinStayLoseShift, axl.TitForTat) af.fingerprint(turns=10, repetitions=2, step=0.25, progress_bar=False) p = af.plot() self.assertIsInstance(p, matplotlib.pyplot.Figure) q = af.plot(cmap="jet") self.assertIsInstance(q, matplotlib.pyplot.Figure) r = af.plot(interpolation="bicubic") self.assertIsInstance(r, matplotlib.pyplot.Figure) t = af.plot(title="Title") self.assertIsInstance(t, matplotlib.pyplot.Figure) u = af.plot(colorbar=False) self.assertIsInstance(u, matplotlib.pyplot.Figure) v = af.plot(labels=False) self.assertIsInstance(v, matplotlib.pyplot.Figure) def test_wsls_fingerprint(self): axl.seed(0) # Fingerprinting is a random process. test_data = { Point(x=0.0, y=0.0): 3.000, Point(x=0.0, y=0.25): 1.710, Point(x=0.0, y=0.5): 1.440, Point(x=0.0, y=0.75): 1.080, Point(x=0.0, y=1.0): 0.500, Point(x=0.25, y=0.0): 3.000, Point(x=0.25, y=0.25): 2.280, Point(x=0.25, y=0.5): 1.670, Point(x=0.25, y=0.75): 1.490, Point(x=0.25, y=1.0): 0.770, Point(x=0.5, y=0.0): 3.000, Point(x=0.5, y=0.25): 2.740, Point(x=0.5, y=0.5): 2.240, Point(x=0.5, y=0.75): 1.730, Point(x=0.5, y=1.0): 1.000, Point(x=0.75, y=0.0): 3.000, Point(x=0.75, y=0.25): 3.520, Point(x=0.75, y=0.5): 2.830, Point(x=0.75, y=0.75): 1.750, Point(x=0.75, y=1.0): 1.250, Point(x=1.0, y=0.0): 3.000, Point(x=1.0, y=0.25): 4.440, Point(x=1.0, y=0.5): 4.410, Point(x=1.0, y=0.75): 4.440, Point(x=1.0, y=1.0): 1.300, } af = axl.AshlockFingerprint(axl.WinStayLoseShift(), axl.TitForTat) data = af.fingerprint(turns=50, repetitions=2, step=0.25, progress_bar=False) for key, value in data.items(): self.assertAlmostEqual(value, test_data[key], places=2) def test_tft_fingerprint(self): axl.seed(0) # Fingerprinting is a random process. test_data = { Point(x=0.0, y=0.0): 3.000, Point(x=0.0, y=0.25): 1.820, Point(x=0.0, y=0.5): 1.130, Point(x=0.0, y=0.75): 1.050, Point(x=0.0, y=1.0): 0.980, Point(x=0.25, y=0.0): 3.000, Point(x=0.25, y=0.25): 2.440, Point(x=0.25, y=0.5): 1.770, Point(x=0.25, y=0.75): 1.700, Point(x=0.25, y=1.0): 1.490, Point(x=0.5, y=0.0): 3.000, Point(x=0.5, y=0.25): 2.580, Point(x=0.5, y=0.5): 2.220, Point(x=0.5, y=0.75): 2.000, Point(x=0.5, y=1.0): 1.940, Point(x=0.75, y=0.0): 3.000, Point(x=0.75, y=0.25): 2.730, Point(x=0.75, y=0.5): 2.290, Point(x=0.75, y=0.75): 2.310, Point(x=0.75, y=1.0): 2.130, Point(x=1.0, y=0.0): 3.000, Point(x=1.0, y=0.25): 2.790, Point(x=1.0, y=0.5): 2.480, Point(x=1.0, y=0.75): 2.310, Point(x=1.0, y=1.0): 2.180, } af = axl.AshlockFingerprint(axl.TitForTat(), axl.TitForTat) data = af.fingerprint(turns=50, repetitions=2, step=0.25, progress_bar=False) for key, value in data.items(): self.assertAlmostEqual(value, test_data[key], places=2) def test_majority_fingerprint(self): axl.seed(0) # Fingerprinting is a random process. test_data = { Point(x=0.0, y=0.0): 3.000, Point(x=0.0, y=0.25): 1.940, Point(x=0.0, y=0.5): 1.130, Point(x=0.0, y=0.75): 1.030, Point(x=0.0, y=1.0): 0.980, Point(x=0.25, y=0.0): 3.000, Point(x=0.25, y=0.25): 2.130, Point(x=0.25, y=0.5): 1.940, Point(x=0.25, y=0.75): 2.060, Point(x=0.25, y=1.0): 1.940, Point(x=0.5, y=0.0): 3.000, Point(x=0.5, y=0.25): 2.300, Point(x=0.5, y=0.5): 2.250, Point(x=0.5, y=0.75): 2.420, Point(x=0.5, y=1.0): 2.690, Point(x=0.75, y=0.0): 3.000, Point(x=0.75, y=0.25): 2.400, Point(x=0.75, y=0.5): 2.010, Point(x=0.75, y=0.75): 2.390, Point(x=0.75, y=1.0): 2.520, Point(x=1.0, y=0.0): 3.000, Point(x=1.0, y=0.25): 2.360, Point(x=1.0, y=0.5): 1.740, Point(x=1.0, y=0.75): 2.260, Point(x=1.0, y=1.0): 2.260, } af = axl.AshlockFingerprint(axl.GoByMajority, axl.TitForTat) data = af.fingerprint(turns=50, repetitions=2, step=0.25, progress_bar=False) for key, value in data.items(): self.assertAlmostEqual(value, test_data[key], places=2) @given(strategy_pair=strategy_lists(min_size=2, max_size=2)) @settings(max_examples=5) def test_pair_fingerprints(self, strategy_pair): """ A test to check that we can fingerprint with any two given strategies or instances """ strategy, probe = strategy_pair af = AshlockFingerprint(strategy, probe) data = af.fingerprint(turns=2, repetitions=2, step=0.5, progress_bar=False) self.assertIsInstance(data, dict) af = AshlockFingerprint(strategy(), probe) data = af.fingerprint(turns=2, repetitions=2, step=0.5, progress_bar=False) self.assertIsInstance(data, dict) af = AshlockFingerprint(strategy, probe()) data = af.fingerprint(turns=2, repetitions=2, step=0.5, progress_bar=False) self.assertIsInstance(data, dict) af = AshlockFingerprint(strategy(), probe()) data = af.fingerprint(turns=2, repetitions=2, step=0.5, progress_bar=False) self.assertIsInstance(data, dict)
class TestPlayer(unittest.TestCase): """A Test class from which other player test classes are inherited.""" player = TestOpponent expected_class_classifier = None def test_initialisation(self): """Test that the player initiates correctly.""" if self.__class__ != TestPlayer: player = self.player() self.assertEqual(len(player.history), 0) self.assertEqual(player.match_attributes, { "length": -1, "game": DefaultGame, "noise": 0 }) self.assertEqual(player.cooperations, 0) self.assertEqual(player.defections, 0) self.classifier_test(self.expected_class_classifier) def test_repr(self): """Test that the representation is correct.""" if self.__class__ != TestPlayer: self.assertEqual(str(self.player()), self.name) def test_match_attributes(self): player = self.player() # Default player.set_match_attributes() t_attrs = player.match_attributes self.assertEqual(t_attrs["length"], -1) self.assertEqual(t_attrs["noise"], 0) self.assertEqual(t_attrs["game"].RPST(), (3, 1, 0, 5)) # Common player.set_match_attributes(length=200) t_attrs = player.match_attributes self.assertEqual(t_attrs["length"], 200) self.assertEqual(t_attrs["noise"], 0) self.assertEqual(t_attrs["game"].RPST(), (3, 1, 0, 5)) # Noisy player.set_match_attributes(length=200, noise=.5) t_attrs = player.match_attributes self.assertEqual(t_attrs["noise"], .5) def test_reset_history_and_attributes(self): """Make sure resetting works correctly.""" for opponent in [ axelrod.Defector(), axelrod.Random(), axelrod.Alternator(), axelrod.Cooperator(), ]: player = self.player() clone = player.clone() for seed in range(10): axelrod.seed(seed) player.play(opponent) player.reset() self.assertEqual(player, clone) def test_reset_clone(self): """Make sure history resetting with cloning works correctly, regardless if self.test_reset() is overwritten.""" player = self.player() clone = player.clone() self.assertEqual(player, clone) 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) @given( strategies=strategy_lists(max_size=5, strategies=short_run_time_short_mem), seed=integers(min_value=1, max_value=200), turns=integers(min_value=1, max_value=200), ) @settings(max_examples=1, max_iterations=1) def test_memory_depth_upper_bound(self, strategies, seed, turns): """ Test that the memory depth is indeed an upper bound. """ player = self.player() memory = player.classifier["memory_depth"] if memory < float("inf"): for strategy in strategies: opponent = strategy() self.assertTrue( test_memory( player=player, opponent=opponent, seed=seed, turns=turns, memory_length=memory, ), msg="Failed for seed={} and opponent={}".format( seed, opponent), ) def versus_test( self, opponent, expected_actions, noise=None, seed=None, turns=10, match_attributes=None, attrs=None, init_kwargs=None, ): """ Tests a sequence of outcomes for two given players. Parameters: ----------- opponent: Player or list An instance of a player OR a sequence of actions. If a sequence of actions is passed, a Mock Player is created that cycles over that sequence. expected_actions: List The expected outcomes of the match (list of tuples of actions). noise: float Any noise to be passed to a match seed: int The random seed to be used length: int The length of the game. If `opponent` is a sequence of actions then the length is taken to be the length of the sequence. match_attributes: dict The match attributes to be passed to the players. For example, `{length:-1}` implies that the players do not know the length of the match. attrs: dict Dictionary of internal attributes to check at the end of all plays in player init_kwargs: dict A dictionary of keyword arguments to instantiate player with """ turns = len(expected_actions) if init_kwargs is None: init_kwargs = dict() if seed is not None: axelrod.seed(seed) player = self.player(**init_kwargs) match = axelrod.Match( (player, opponent), turns=turns, noise=noise, match_attributes=match_attributes, ) self.assertEqual(match.play(), expected_actions) if attrs: player = match.players[0] for attr, value in attrs.items(): self.assertEqual(getattr(player, attr), value) def classifier_test(self, expected_class_classifier=None): """Test that the keys in the expected_classifier dictionary give the expected values in the player classifier dictionary. Also checks that two particular keys (memory_depth and stochastic) are in the dictionary.""" player = self.player() # Test that player has same classifier as it's class unless otherwise # specified if expected_class_classifier is None: expected_class_classifier = player.classifier self.assertEqual(expected_class_classifier, self.player.classifier) self.assertTrue("memory_depth" in player.classifier, msg="memory_depth not in classifier") self.assertTrue("stochastic" in player.classifier, msg="stochastic not in classifier") for key in TestOpponent.classifier: self.assertEqual( player.classifier[key], self.expected_classifier[key], msg="%s - Behaviour: %s != Expected Behaviour: %s" % (key, player.classifier[key], self.expected_classifier[key]), )
class TestMoranProcess(unittest.TestCase): def test_fps(self): self.assertEqual(fitness_proportionate_selection([0, 0, 1]), 2) random.seed(1) self.assertEqual(fitness_proportionate_selection([1, 1, 1]), 0) self.assertEqual(fitness_proportionate_selection([1, 1, 1]), 2) def test_stochastic(self): p1, p2 = axelrod.Cooperator(), axelrod.Cooperator() mp = MoranProcess((p1, p2)) self.assertFalse(mp._stochastic) p1, p2 = axelrod.Cooperator(), axelrod.Cooperator() mp = MoranProcess((p1, p2), noise=0.05) self.assertTrue(mp._stochastic) p1, p2 = axelrod.Cooperator(), axelrod.Random() mp = MoranProcess((p1, p2)) self.assertTrue(mp._stochastic) def test_exit_condition(self): p1, p2 = axelrod.Cooperator(), axelrod.Cooperator() mp = MoranProcess((p1, p2)) mp.play() self.assertEqual(len(mp), 1) def test_two_players(self): p1, p2 = axelrod.Cooperator(), axelrod.Defector() random.seed(5) mp = MoranProcess((p1, p2)) populations = mp.play() self.assertEqual(len(mp), 5) self.assertEqual(len(populations), 5) self.assertEqual(populations, mp.populations) self.assertEqual(mp.winning_strategy_name, str(p2)) def test_two_random_players(self): p1, p2 = axelrod.Random(0.5), axelrod.Random(0.25) random.seed(5) mp = MoranProcess((p1, p2)) populations = mp.play() self.assertEqual(len(mp), 2) self.assertEqual(len(populations), 2) self.assertEqual(populations, mp.populations) self.assertEqual(mp.winning_strategy_name, str(p1)) def test_two_players_with_mutation(self): p1, p2 = axelrod.Cooperator(), axelrod.Defector() random.seed(5) mp = MoranProcess((p1, p2), mutation_rate=0.2) self.assertEqual(mp._stochastic, True) self.assertDictEqual(mp.mutation_targets, { str(p1): [p2], str(p2): [p1] }) # Test that mutation causes the population to alternate between fixations counters = [ Counter({'Cooperator': 2}), Counter({'Defector': 2}), Counter({'Cooperator': 2}), Counter({'Defector': 2}) ] for counter in counters: for _ in itertools.takewhile( lambda x: x.population_distribution() != counter, mp): pass self.assertEqual(mp.population_distribution(), counter) def test_play_exception(self): p1, p2 = axelrod.Cooperator(), axelrod.Defector() mp = MoranProcess((p1, p2), mutation_rate=0.2) with self.assertRaises(ValueError): mp.play() def test_three_players(self): players = [ axelrod.Cooperator(), axelrod.Cooperator(), axelrod.Defector() ] random.seed(5) mp = MoranProcess(players) populations = mp.play() self.assertEqual(len(mp), 7) self.assertEqual(len(populations), 7) self.assertEqual(populations, mp.populations) self.assertEqual(mp.winning_strategy_name, str(axelrod.Defector())) def test_three_players_with_mutation(self): p1 = axelrod.Cooperator() p2 = axelrod.Random() p3 = axelrod.Defector() players = [p1, p2, p3] mp = MoranProcess(players, mutation_rate=0.2) self.assertEqual(mp._stochastic, True) self.assertDictEqual(mp.mutation_targets, { str(p1): [p3, p2], str(p2): [p1, p3], str(p3): [p1, p2] }) # Test that mutation causes the population to alternate between fixations counters = [ Counter({'Cooperator': 3}), Counter({'Defector': 3}), ] for counter in counters: for _ in itertools.takewhile( lambda x: x.population_distribution() != counter, mp): pass self.assertEqual(mp.population_distribution(), counter) def test_four_players(self): players = [axelrod.Cooperator() for _ in range(3)] players.append(axelrod.Defector()) random.seed(10) mp = MoranProcess(players) populations = mp.play() self.assertEqual(len(mp), 9) self.assertEqual(len(populations), 9) self.assertEqual(populations, mp.populations) self.assertEqual(mp.winning_strategy_name, str(axelrod.Defector())) @given(strategies=strategy_lists(min_size=2, max_size=5)) @settings(max_examples=5, timeout=0) # Very low number of examples # Two specific examples relating to cloning of strategies @example(strategies=[axelrod.BackStabber, axelrod.MindReader]) @example(strategies=[axelrod.ThueMorse, axelrod.MindReader]) def test_property_players(self, strategies): """Hypothesis test that randomly checks players""" players = [s() for s in strategies] mp = MoranProcess(players) populations = mp.play() self.assertEqual(populations, mp.populations) self.assertIn(mp.winning_strategy_name, [str(p) for p in players]) def test_reset(self): p1, p2 = axelrod.Cooperator(), axelrod.Defector() random.seed(8) mp = MoranProcess((p1, p2)) mp.play() self.assertEqual(len(mp), 4) self.assertEqual(len(mp.score_history), 3) mp.reset() self.assertEqual(len(mp), 1) self.assertEqual(mp.winning_strategy_name, None) self.assertEqual(mp.score_history, []) # Check that players reset for player, intial_player in zip(mp.players, mp.initial_players): self.assertEqual(str(player), str(intial_player)) def test_cache(self): p1, p2 = axelrod.Cooperator(), axelrod.Defector() mp = MoranProcess((p1, p2)) mp.play() self.assertEqual(len(mp.deterministic_cache), 1) # Check that can pass a pre built cache cache = axelrod.DeterministicCache() mp = MoranProcess((p1, p2), deterministic_cache=cache) self.assertEqual(cache, mp.deterministic_cache) def test_iter(self): p1, p2 = axelrod.Cooperator(), axelrod.Defector() mp = MoranProcess((p1, p2)) self.assertEqual(mp.__iter__(), mp)
class TestMoranProcess(unittest.TestCase): def test_fps(self): self.assertEqual(fitness_proportionate_selection([0, 0, 1]), 2) random.seed(1) self.assertEqual(fitness_proportionate_selection([1, 1, 1]), 0) self.assertEqual(fitness_proportionate_selection([1, 1, 1]), 2) def test_stochastic(self): p1, p2 = axelrod.Cooperator(), axelrod.Cooperator() mp = MoranProcess((p1, p2)) self.assertFalse(mp._stochastic) p1, p2 = axelrod.Cooperator(), axelrod.Cooperator() mp = MoranProcess((p1, p2), noise=0.05) self.assertTrue(mp._stochastic) p1, p2 = axelrod.Cooperator(), axelrod.Random() mp = MoranProcess((p1, p2)) self.assertTrue(mp._stochastic) def test_exit_condition(self): p1, p2 = axelrod.Cooperator(), axelrod.Cooperator() mp = MoranProcess((p1, p2)) mp.play() self.assertEqual(len(mp), 1) def test_two_players(self): p1, p2 = axelrod.Cooperator(), axelrod.Defector() random.seed(5) mp = MoranProcess((p1, p2)) populations = mp.play() self.assertEqual(len(mp), 5) self.assertEqual(len(populations), 5) self.assertEqual(populations, mp.populations) self.assertEqual(mp.winning_strategy_name, str(p2)) def test_three_players(self): players = [ axelrod.Cooperator(), axelrod.Cooperator(), axelrod.Defector() ] random.seed(5) mp = MoranProcess(players) populations = mp.play() self.assertEqual(len(mp), 7) self.assertEqual(len(populations), 7) self.assertEqual(populations, mp.populations) self.assertEqual(mp.winning_strategy_name, str(axelrod.Defector())) def test_four_players(self): players = [axelrod.Cooperator() for _ in range(3)] players.append(axelrod.Defector()) random.seed(10) mp = MoranProcess(players) populations = mp.play() self.assertEqual(len(mp), 9) self.assertEqual(len(populations), 9) self.assertEqual(populations, mp.populations) self.assertEqual(mp.winning_strategy_name, str(axelrod.Defector())) @given(strategies=strategy_lists(min_size=2, max_size=5), rm=random_module()) @settings(max_examples=5, timeout=0) # Very low number of examples # Two specific examples relating to cloning of strategies @example(strategies=[axelrod.BackStabber, axelrod.MindReader], rm=random.seed(0)) @example(strategies=[axelrod.ThueMorse, axelrod.MindReader], rm=random.seed(0)) def test_property_players(self, strategies, rm): """Hypothesis test that randomly checks players""" players = [s() for s in strategies] mp = MoranProcess(players) populations = mp.play() self.assertEqual(populations, mp.populations) self.assertIn(mp.winning_strategy_name, [str(p) for p in players]) def test_reset(self): p1, p2 = axelrod.Cooperator(), axelrod.Defector() random.seed(8) mp = MoranProcess((p1, p2)) mp.play() self.assertEqual(len(mp), 4) self.assertEqual(len(mp.score_history), 3) mp.reset() self.assertEqual(len(mp), 1) self.assertEqual(mp.winning_strategy_name, None) self.assertEqual(mp.score_history, []) # Check that players reset for player, intial_player in zip(mp.players, mp.initial_players): self.assertEqual(str(player), str(intial_player)) def test_cache(self): p1, p2 = axelrod.Cooperator(), axelrod.Defector() mp = MoranProcess((p1, p2)) mp.play() self.assertEqual(len(mp.deterministic_cache), 1) # Check that can pass a pre built cache cache = axelrod.DeterministicCache() mp = MoranProcess((p1, p2), deterministic_cache=cache) self.assertEqual(cache, mp.deterministic_cache) def test_iter(self): p1, p2 = axelrod.Cooperator(), axelrod.Defector() mp = MoranProcess((p1, p2)) self.assertEqual(mp.__iter__(), mp)
class TestMoranProcess(unittest.TestCase): def test_fps(self): self.assertEqual(fitness_proportionate_selection([0, 0, 1]), 2) random.seed(1) self.assertEqual(fitness_proportionate_selection([1, 1, 1]), 0) self.assertEqual(fitness_proportionate_selection([1, 1, 1]), 2) def test_exit_condition(self): p1, p2 = axelrod.Cooperator(), axelrod.Cooperator() mp = MoranProcess((p1, p2)) mp.play() self.assertEqual(len(mp), 1) def test_two_players(self): p1, p2 = axelrod.Cooperator(), axelrod.Defector() random.seed(5) mp = MoranProcess((p1, p2)) populations = mp.play() self.assertEqual(len(mp), 5) self.assertEqual(len(populations), 5) self.assertEqual(populations, mp.populations) self.assertEqual(mp.winning_strategy_name, str(p2)) def test_death_birth(self): """Two player death-birth should fixate after one round.""" p1, p2 = axelrod.Cooperator(), axelrod.Defector() seeds = range(0, 20) for seed in seeds: random.seed(seed) mp = MoranProcess((p1, p2), mode='db') next(mp) self.assertIsNotNone(mp.winning_strategy_name) def test_death_birth_outcomes(self): """Show that birth-death and death-birth can produce different outcomes.""" seeds = [(1, True), (23, False)] players = [] N = 6 for _ in range(N // 2): players.append(axelrod.Cooperator()) players.append(axelrod.Defector()) for seed, outcome in seeds: axelrod.seed(seed) mp = MoranProcess(players, mode='bd') mp.play() winner = mp.winning_strategy_name axelrod.seed(seed) mp = MoranProcess(players, mode='db') mp.play() winner2 = mp.winning_strategy_name self.assertEqual((winner == winner2), outcome) def test_two_random_players(self): p1, p2 = axelrod.Random(0.5), axelrod.Random(0.25) random.seed(5) mp = MoranProcess((p1, p2)) populations = mp.play() self.assertEqual(len(mp), 2) self.assertEqual(len(populations), 2) self.assertEqual(populations, mp.populations) self.assertEqual(mp.winning_strategy_name, str(p1)) def test_two_players_with_mutation(self): p1, p2 = axelrod.Cooperator(), axelrod.Defector() random.seed(5) mp = MoranProcess((p1, p2), mutation_rate=0.2) self.assertDictEqual(mp.mutation_targets, { str(p1): [p2], str(p2): [p1] }) # Test that mutation causes the population to alternate between # fixations counters = [ Counter({'Cooperator': 2}), Counter({'Defector': 2}), Counter({'Cooperator': 2}), Counter({'Defector': 2}) ] for counter in counters: for _ in itertools.takewhile( lambda x: x.population_distribution() != counter, mp): pass self.assertEqual(mp.population_distribution(), counter) def test_play_exception(self): p1, p2 = axelrod.Cooperator(), axelrod.Defector() mp = MoranProcess((p1, p2), mutation_rate=0.2) with self.assertRaises(ValueError): mp.play() def test_three_players(self): players = [ axelrod.Cooperator(), axelrod.Cooperator(), axelrod.Defector() ] random.seed(5) mp = MoranProcess(players) populations = mp.play() self.assertEqual(len(mp), 7) self.assertEqual(len(populations), 7) self.assertEqual(populations, mp.populations) self.assertEqual(mp.winning_strategy_name, str(axelrod.Defector())) def test_three_players_with_mutation(self): p1 = axelrod.Cooperator() p2 = axelrod.Random() p3 = axelrod.Defector() players = [p1, p2, p3] mp = MoranProcess(players, mutation_rate=0.2) self.assertDictEqual(mp.mutation_targets, { str(p1): [p3, p2], str(p2): [p1, p3], str(p3): [p1, p2] }) # Test that mutation causes the population to alternate between # fixations counters = [ Counter({'Cooperator': 3}), Counter({'Defector': 3}), ] for counter in counters: for _ in itertools.takewhile( lambda x: x.population_distribution() != counter, mp): pass self.assertEqual(mp.population_distribution(), counter) def test_four_players(self): players = [axelrod.Cooperator() for _ in range(3)] players.append(axelrod.Defector()) random.seed(10) mp = MoranProcess(players) populations = mp.play() self.assertEqual(len(mp), 9) self.assertEqual(len(populations), 9) self.assertEqual(populations, mp.populations) self.assertEqual(mp.winning_strategy_name, str(axelrod.Defector())) def test_standard_fixation(self): """Test a traditional Moran process with a MockMatch.""" axelrod.seed(0) players = (axelrod.Cooperator(), axelrod.Cooperator(), axelrod.Defector(), axelrod.Defector()) mp = MoranProcess(players, match_class=MockMatch) winners = [] for i in range(100): mp.play() winner = mp.winning_strategy_name winners.append(winner) mp.reset() winners = Counter(winners) self.assertEqual(winners["Cooperator"], 82) @given(strategies=strategy_lists(min_size=2, max_size=5)) @settings(max_examples=5, timeout=0) # Very low number of examples # Two specific examples relating to cloning of strategies @example(strategies=[axelrod.BackStabber, axelrod.MindReader]) @example(strategies=[axelrod.ThueMorse, axelrod.MindReader]) def test_property_players(self, strategies): """Hypothesis test that randomly checks players""" players = [s() for s in strategies] mp = MoranProcess(players) populations = mp.play() self.assertEqual(populations, mp.populations) self.assertIn(mp.winning_strategy_name, [str(p) for p in players]) def test_reset(self): p1, p2 = axelrod.Cooperator(), axelrod.Defector() random.seed(8) mp = MoranProcess((p1, p2)) mp.play() self.assertEqual(len(mp), 4) self.assertEqual(len(mp.score_history), 3) mp.reset() self.assertEqual(len(mp), 1) self.assertEqual(mp.winning_strategy_name, None) self.assertEqual(mp.score_history, []) # Check that players reset for player, initial_player in zip(mp.players, mp.initial_players): self.assertEqual(str(player), str(initial_player)) def test_cache(self): p1, p2 = axelrod.Cooperator(), axelrod.Defector() mp = MoranProcess((p1, p2)) mp.play() self.assertEqual(len(mp.deterministic_cache), 1) # Check that can pass a pre built cache cache = axelrod.DeterministicCache() mp = MoranProcess((p1, p2), deterministic_cache=cache) self.assertEqual(cache, mp.deterministic_cache) def test_iter(self): p1, p2 = axelrod.Cooperator(), axelrod.Defector() mp = MoranProcess((p1, p2)) self.assertEqual(mp.__iter__(), mp)
class TestFiltersAgainstComprehensions(unittest.TestCase): """ Test that the results of filtering strategies via a filterset dict match the results from using a list comprehension. """ @given(strategies=strategy_lists(min_size=20, max_size=20)) def test_boolean_filtering(self, strategies): classifiers = [ "stochastic", "long_run_time", "manipulates_state", "manipulates_source", "inspects_source", ] for classifier in classifiers: comprehension = set( [s for s in strategies if s.classifier[classifier]]) filterset = {classifier: True} filtered = set(filtered_strategies(filterset, strategies=strategies)) self.assertEqual(comprehension, filtered) @given( min_memory_depth=integers(min_value=1, max_value=10), max_memory_depth=integers(min_value=1, max_value=10), memory_depth=integers(min_value=1, max_value=10), strategies=strategy_lists(min_size=20, max_size=20), ) @example( min_memory_depth=float("inf"), max_memory_depth=float("inf"), memory_depth=float("inf"), strategies=short_run_time_strategies, ) @settings(max_examples=5) def test_memory_depth_filtering(self, min_memory_depth, max_memory_depth, memory_depth, strategies): min_comprehension = set([ s for s in strategies if s().classifier["memory_depth"] >= min_memory_depth ]) min_filterset = {"min_memory_depth": min_memory_depth} min_filtered = set( filtered_strategies(min_filterset, strategies=strategies)) self.assertEqual(min_comprehension, min_filtered) max_comprehension = set([ s for s in strategies if s().classifier["memory_depth"] <= max_memory_depth ]) max_filterset = {"max_memory_depth": max_memory_depth} max_filtered = set( filtered_strategies(max_filterset, strategies=strategies)) self.assertEqual(max_comprehension, max_filtered) comprehension = set([ s for s in strategies if s().classifier["memory_depth"] == memory_depth ]) filterset = {"memory_depth": memory_depth} filtered = set(filtered_strategies(filterset, strategies=strategies)) self.assertEqual(comprehension, filtered) @given( seed_=integers(min_value=0, max_value=4294967295), strategies=strategy_lists(min_size=20, max_size=20), ) @settings(max_examples=5) def test_makes_use_of_filtering(self, seed_, strategies): """ Test equivalent filtering using two approaches. This needs to be seeded as some players classification is random. """ classifiers = [["game"], ["length"], ["game", "length"]] for classifier in classifiers: seed(seed_) comprehension = set([ s for s in strategies if set(classifier).issubset( set(s().classifier["makes_use_of"])) ]) seed(seed_) filterset = {"makes_use_of": classifier} filtered = set( filtered_strategies(filterset, strategies=strategies)) self.assertEqual(comprehension, filtered, msg="classifier: {}".format(classifier))
def test_call(self): strategies = strategy_lists().example() self.assertIsInstance(strategies, list) for p in strategies: self.assertIsInstance(p(), axelrod.Player)
class TestFingerprint(unittest.TestCase): @classmethod def setUpClass(cls): cls.strategy = axl.WinStayLoseShift cls.probe = axl.TitForTat cls.expected_points = [(0.0, 0.0), (0.0, 0.5), (0.0, 1.0), (0.5, 0.0), (0.5, 0.5), (0.5, 1.0), (1.0, 0.0), (1.0, 0.5), (1.0, 1.0)] cls.expected_edges = [(0, 1), (0, 2), (0, 3), (0, 4), (0, 5), (0, 6), (0, 7), (0, 8), (0, 9)] def test_default_init(self): fingerprint = AshlockFingerprint(self.strategy) self.assertEqual(fingerprint.strategy, self.strategy) self.assertEqual(fingerprint.probe, self.probe) def test_init(self): fingerprint = AshlockFingerprint(self.strategy, self.probe) self.assertEqual(fingerprint.strategy, self.strategy) self.assertEqual(fingerprint.probe, self.probe) def test_init_with_instance(self): player = self.strategy() fingerprint = AshlockFingerprint(player) self.assertEqual(fingerprint.strategy, player) self.assertEqual(fingerprint.probe, self.probe) probe_player = self.probe() fingerprint = AshlockFingerprint(self.strategy, probe_player) self.assertEqual(fingerprint.strategy, self.strategy) self.assertEqual(fingerprint.probe, probe_player) fingerprint = AshlockFingerprint(player, probe_player) self.assertEqual(fingerprint.strategy, player) self.assertEqual(fingerprint.probe, probe_player) def test_create_jossann(self): fingerprint = AshlockFingerprint(self.strategy) # x + y < 1 ja = fingerprint.create_jossann((.5, .4), self.probe) self.assertEqual(str(ja), "Joss-Ann Tit For Tat") # x + y = 1 ja = fingerprint.create_jossann((.4, .6), self.probe) self.assertEqual(str(ja), "Dual Joss-Ann Tit For Tat") # x + y > 1 ja = fingerprint.create_jossann((.5, .6), self.probe) self.assertEqual(str(ja), "Dual Joss-Ann Tit For Tat") def test_create_jossann_parametrised_player(self): fingerprint = AshlockFingerprint(self.strategy) probe = axl.Random(0.1) # x + y < 1 ja = fingerprint.create_jossann((.5, .4), probe) self.assertEqual(str(ja), "Joss-Ann Random: 0.1") # x + y = 1 ja = fingerprint.create_jossann((.4, .6), probe) self.assertEqual(str(ja), "Dual Joss-Ann Random: 0.1") # x + y > 1 ja = fingerprint.create_jossann((.5, .6), probe) self.assertEqual(str(ja), "Dual Joss-Ann Random: 0.1") def test_create_points(self): test_points = create_points(0.5, progress_bar=False) self.assertEqual(test_points, self.expected_points) def test_create_probes(self): af = AshlockFingerprint(self.strategy, self.probe) probes = af.create_probes(self.probe, self.expected_points, progress_bar=False) self.assertEqual(len(probes), 9) def test_create_edges(self): af = AshlockFingerprint(self.strategy, self.probe) edges = af.create_edges(self.expected_points, progress_bar=False) self.assertEqual(edges, self.expected_edges) def test_construct_tournament_elemets(self): af = AshlockFingerprint(self.strategy, self.probe) edges, tournament_players = af.construct_tournament_elements(0.5, progress_bar=False) self.assertEqual(edges, self.expected_edges) self.assertEqual(len(tournament_players), 10) self.assertEqual(tournament_players[0].__class__, af.strategy) def test_progress_bar_fingerprint(self): af = AshlockFingerprint(self.strategy, self.probe) data = af.fingerprint(turns=10, repetitions=2, step=0.5, progress_bar=True) self.assertEqual(sorted(data.keys()), self.expected_points) def test_in_memory_fingerprint(self): af = AshlockFingerprint(self.strategy, self.probe) af.fingerprint(turns=10, repetitions=2, step=0.5, progress_bar=False, in_memory=True) edge_keys = sorted(list(af.interactions.keys())) coord_keys = sorted(list(af.data.keys())) self.assertEqual(af.step, 0.5) self.assertEqual(af.spatial_tournament.interactions_dict, af.interactions) self.assertEqual(edge_keys, self.expected_edges) self.assertEqual(coord_keys, self.expected_points) def test_serial_fingerprint(self): af = AshlockFingerprint(self.strategy, self.probe) data = af.fingerprint(turns=10, repetitions=2, step=0.5, progress_bar=False) edge_keys = sorted(list(af.interactions.keys())) coord_keys = sorted(list(data.keys())) self.assertEqual(af.step, 0.5) self.assertEqual(edge_keys, self.expected_edges) self.assertEqual(coord_keys, self.expected_points) @unittest.skipIf(axl.on_windows, "Parallel processing not supported on Windows") def test_parallel_fingerprint(self): af = AshlockFingerprint(self.strategy, self.probe) af.fingerprint(turns=10, repetitions=2, step=0.5, processes=2, progress_bar=False) edge_keys = sorted(list(af.interactions.keys())) coord_keys = sorted(list(af.data.keys())) self.assertEqual(af.step, 0.5) self.assertEqual(edge_keys, self.expected_edges) self.assertEqual(coord_keys, self.expected_points) def test_generate_data(self): af = AshlockFingerprint(self.strategy, self.probe) edges, players = af.construct_tournament_elements(0.5) spatial_tournament = axl.SpatialTournament(players, turns=10, repetitions=2, edges=edges) results = spatial_tournament.play(progress_bar=False, keep_interactions=True) data = af.generate_data(results.interactions, self.expected_points, self.expected_edges) keys = sorted(list(data.keys())) values = [0 < score < 5 for score in data.values()] self.assertEqual(sorted(keys), self.expected_points) self.assertEqual(all(values), True) def test_reshape_data(self): test_points = [Point(x=0.0, y=0.0), Point(x=0.0, y=0.5), Point(x=0.0, y=1.0), Point(x=0.5, y=0.0), Point(x=0.5, y=0.5), Point(x=0.5, y=1.0), Point(x=1.0, y=0.0), Point(x=1.0, y=0.5), Point(x=1.0, y=1.0)] test_data = {Point(x=0.0, y=0.0): 5, Point(x=0.0, y=0.5): 9, Point(x=0.0, y=1.0): 3, Point(x=0.5, y=0.0): 8, Point(x=0.5, y=0.5): 2, Point(x=0.5, y=1.0): 4, Point(x=1.0, y=0.0): 2, Point(x=1.0, y=0.5): 1, Point(x=1.0, y=1.0): 9} test_shaped_data = [[3, 4, 9], [9, 2, 1], [5, 8, 2]] af = AshlockFingerprint(self.strategy, self.probe) plotting_data = af.reshape_data(test_data, test_points, 3) for i in range(len(plotting_data)): self.assertEqual(list(plotting_data[i]), test_shaped_data[i]) def test_plot(self): af = AshlockFingerprint(self.strategy, self.probe) af.fingerprint(turns=10, repetitions=2, step=0.25, progress_bar=False) p = af.plot() self.assertIsInstance(p, matplotlib.pyplot.Figure) q = af.plot(col_map='jet') self.assertIsInstance(q, matplotlib.pyplot.Figure) r = af.plot(interpolation='bicubic') self.assertIsInstance(r, matplotlib.pyplot.Figure) t = af.plot(title='Title') self.assertIsInstance(t, matplotlib.pyplot.Figure) u = af.plot(colorbar=False) self.assertIsInstance(u, matplotlib.pyplot.Figure) v = af.plot(labels=False) self.assertIsInstance(v, matplotlib.pyplot.Figure) def test_wsls_fingerprint(self): axl.seed(0) # Fingerprinting is a random process test_data = {Point(x=0.0, y=0.0): 3.0, Point(x=0.0, y=0.25): 1.46, Point(x=0.0, y=0.5): 1.54, Point(x=0.0, y=0.75): 1.12, Point(x=0.0, y=1.0): 0.5, Point(x=0.25, y=0.0): 3.0, Point(x=0.25, y=0.25): 2.04, Point(x=0.25, y=0.5): 2.0, Point(x=0.25, y=0.75): 1.34, Point(x=0.25, y=1.0): 0.9, Point(x=0.5, y=0.0): 3.0, Point(x=0.5, y=0.25): 3.0, Point(x=0.5, y=0.5): 2.06, Point(x=0.5, y=0.75): 1.36, Point(x=0.5, y=1.0): 1.0, Point(x=0.75, y=0.0): 3.0, Point(x=0.75, y=0.25): 3.56, Point(x=0.75, y=0.5): 2.06, Point(x=0.75, y=0.75): 3.0, Point(x=0.75, y=1.0): 1.04, Point(x=1.0, y=0.0): 3.0, Point(x=1.0, y=0.25): 4.86, Point(x=1.0, y=0.5): 4.9, Point(x=1.0, y=0.75): 4.9, Point(x=1.0, y=1.0): 1.3} af = axl.AshlockFingerprint(self.strategy, self.probe) data = af.fingerprint(turns=50, repetitions=2, step=0.25) for key, value in data.items(): self.assertAlmostEqual(value, test_data[key]) def test_tft_fingerprint(self): axl.seed(0) # Fingerprinting is a random process test_data = {Point(x=0.0, y=0.0): 3.0, Point(x=0.0, y=0.25): 1.1, Point(x=0.0, y=0.5): 1.08, Point(x=0.0, y=0.75): 1.04, Point(x=0.0, y=1.0): 0.98, Point(x=0.25, y=0.0): 3.0, Point(x=0.25, y=0.25): 2.26, Point(x=0.25, y=0.5): 2.1, Point(x=0.25, y=0.75): 1.66, Point(x=0.25, y=1.0): 1.64, Point(x=0.5, y=0.0): 3.0, Point(x=0.5, y=0.25): 2.5, Point(x=0.5, y=0.5): 2.12, Point(x=0.5, y=0.75): 1.86, Point(x=0.5, y=1.0): 1.88, Point(x=0.75, y=0.0): 3.0, Point(x=0.75, y=0.25): 2.84, Point(x=0.75, y=0.5): 2.36, Point(x=0.75, y=0.75): 2.28, Point(x=0.75, y=1.0): 1.98, Point(x=1.0, y=0.0): 3.0, Point(x=1.0, y=0.25): 2.78, Point(x=1.0, y=0.5): 2.56, Point(x=1.0, y=0.75): 2.44, Point(x=1.0, y=1.0): 2.18} af = axl.AshlockFingerprint(axl.TitForTat, self.probe) data = af.fingerprint(turns=50, repetitions=2, step=0.25) for key, value in data.items(): self.assertAlmostEqual(value, test_data[key]) def test_majority_fingerprint(self): axl.seed(0) # Fingerprinting is a random process test_data = {Point(x=0.0, y=0.0): 3.0, Point(x=0.0, y=0.25): 1.18, Point(x=0.0, y=0.5): 1.98, Point(x=0.0, y=0.75): 1.04, Point(x=0.0, y=1.0): 0.98, Point(x=0.25, y=0.0): 3.0, Point(x=0.25, y=0.25): 2.16, Point(x=0.25, y=0.5): 1.74, Point(x=0.25, y=0.75): 1.96, Point(x=0.25, y=1.0): 2.24, Point(x=0.5, y=0.0): 3.0, Point(x=0.5, y=0.25): 2.46, Point(x=0.5, y=0.5): 2.44, Point(x=0.5, y=0.75): 2.24, Point(x=0.5, y=1.0): 2.74, Point(x=0.75, y=0.0): 3.0, Point(x=0.75, y=0.25): 2.52, Point(x=0.75, y=0.5): 2.16, Point(x=0.75, y=0.75): 2.1, Point(x=0.75, y=1.0): 2.44, Point(x=1.0, y=0.0): 3.0, Point(x=1.0, y=0.25): 2.22, Point(x=1.0, y=0.5): 1.64, Point(x=1.0, y=0.75): 2.08, Point(x=1.0, y=1.0): 2.26} af = axl.AshlockFingerprint(axl.GoByMajority, self.probe) data = af.fingerprint(turns=50, repetitions=2, step=0.25) for key, value in data.items(): self.assertAlmostEqual(value, test_data[key]) @given(strategy_pair=strategy_lists(min_size=2, max_size=2)) def test_pair_fingerprints(self, strategy_pair): """ A test to check that we can fingerprint with any two given strategies or instances """ strategy, probe = strategy_pair af = AshlockFingerprint(strategy, probe) data = af.fingerprint(turns=2, repetitions=2, step=0.5, progress_bar=False) self.assertIsInstance(data, dict) af = AshlockFingerprint(strategy(), probe) data = af.fingerprint(turns=2, repetitions=2, step=0.5, progress_bar=False) self.assertIsInstance(data, dict) af = AshlockFingerprint(strategy, probe()) data = af.fingerprint(turns=2, repetitions=2, step=0.5, progress_bar=False) self.assertIsInstance(data, dict) af = AshlockFingerprint(strategy(), probe()) data = af.fingerprint(turns=2, repetitions=2, step=0.5, progress_bar=False) self.assertIsInstance(data, dict)
class TestContriteTitForTat(TestPlayer): name = "Contrite Tit For Tat" player = axl.ContriteTitForTat expected_classifier = { "memory_depth": 3, "stochastic": False, "makes_use_of": set(), "inspects_source": False, "manipulates_source": False, "manipulates_state": False, } deterministic_strategies = [ s for s in axl.strategies if not axl.Classifiers["stochastic"](s()) ] def test_init(self): player = self.player() self.assertFalse(player.contrite, False) self.assertEqual(player._recorded_history, []) @given(strategies=strategy_lists(strategies=deterministic_strategies, max_size=1), turns=integers(min_value=1, max_value=20)) @settings(deadline=None) 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_strategy_with_noise1(self): self.versus_test(axl.Defector(), [(C, D)], turns=1, seed=9, attrs={"_recorded_history": [C]}) def test_strategy_with_noise2(self): self.versus_test(axl.Defector(), [(D, C)], turns=1, noise=0.5, seed=11, attrs={"_recorded_history": [C]}) def test_strategy_with_noise3(self): # After noise: is contrite actions = list(zip([D, C], [C, D])) self.versus_test(axl.Defector(), actions, turns=2, noise=0.5, seed=49, attrs={ "_recorded_history": [C, C], "contrite": True }) def test_strategy_with_noise4(self): # Cooperates and no longer contrite actions = list(zip([D, C, C], [C, D, D])) self.versus_test(axl.Defector(), actions, turns=3, noise=0.5, seed=49, attrs={ "_recorded_history": [C, C, C], "contrite": False }) def test_strategy_with_noise5(self): # Defects and no longer contrite actions = list(zip([D, C, C, D], [C, D, D, D])) self.versus_test(axl.Defector(), actions, turns=4, noise=0.5, seed=158, attrs={ "_recorded_history": [C, C, C, D], "contrite": False })
def test_call(self): strategies = strategy_lists().example() self.assertIsInstance(strategies, list) for p in strategies: self.assertIsInstance(p(), axelrod.Player)
class TestSpatialTournament(unittest.TestCase): @classmethod def setUpClass(cls): cls.game = axelrod.Game() cls.players = [s() for s in test_strategies] cls.test_name = "test" cls.test_repetitions = test_repetitions cls.test_turns = test_turns cls.test_edges = test_edges def test_init(self): tournament = axelrod.Tournament( name=self.test_name, players=self.players, game=self.game, turns=self.test_turns, edges=self.test_edges, noise=0.2, ) self.assertEqual(tournament.match_generator.edges, tournament.edges) self.assertEqual(len(tournament.players), len(test_strategies)) self.assertEqual(tournament.game.score((C, C)), (3, 3)) self.assertEqual(tournament.turns, 100) self.assertEqual(tournament.repetitions, 10) self.assertEqual(tournament.name, "test") self.assertIsInstance(tournament._logger, logging.Logger) self.assertEqual(tournament.noise, 0.2) self.assertEqual(tournament.match_generator.noise, 0.2) anonymous_tournament = axelrod.Tournament(players=self.players) self.assertEqual(anonymous_tournament.name, "axelrod") @given( strategies=strategy_lists(strategies=deterministic_strategies, min_size=2, max_size=2), turns=integers(min_value=1, max_value=20), repetitions=integers(min_value=1, max_value=5), noise=floats(min_value=0, max_value=1), seed=integers(min_value=0, max_value=4294967295), ) @settings(max_examples=5, max_iterations=20) def test_complete_tournament(self, strategies, turns, repetitions, noise, seed): """ A test to check that a spatial tournament on the complete multigraph gives the same results as the round robin. """ players = [s() for s in strategies] # edges edges = [] for i in range(0, len(players)): for j in range(i, len(players)): edges.append((i, j)) # create a round robin tournament tournament = axelrod.Tournament(players, repetitions=repetitions, turns=turns, noise=noise) # create a complete spatial tournament spatial_tournament = axelrod.Tournament(players, repetitions=repetitions, turns=turns, noise=noise, edges=edges) axelrod.seed(seed) results = tournament.play(progress_bar=False) axelrod.seed(seed) spatial_results = spatial_tournament.play(progress_bar=False) self.assertEqual(results.ranked_names, spatial_results.ranked_names) self.assertEqual(results.num_players, spatial_results.num_players) self.assertEqual(results.repetitions, spatial_results.repetitions) self.assertEqual(results.payoff_diffs_means, spatial_results.payoff_diffs_means) self.assertEqual(results.payoff_matrix, spatial_results.payoff_matrix) self.assertEqual(results.payoff_stddevs, spatial_results.payoff_stddevs) self.assertEqual(results.payoffs, spatial_results.payoffs) self.assertEqual(results.cooperating_rating, spatial_results.cooperating_rating) self.assertEqual(results.cooperation, spatial_results.cooperation) self.assertEqual(results.normalised_cooperation, spatial_results.normalised_cooperation) self.assertEqual(results.normalised_scores, spatial_results.normalised_scores) self.assertEqual(results.good_partner_matrix, spatial_results.good_partner_matrix) self.assertEqual(results.good_partner_rating, spatial_results.good_partner_rating) def test_particular_tournament(self): """A test for a tournament that has caused failures during some bug fixing""" players = [ axelrod.Cooperator(), axelrod.Defector(), axelrod.TitForTat(), axelrod.Grudger(), ] edges = [(0, 2), (0, 3), (1, 2), (1, 3)] tournament = axelrod.Tournament(players, edges=edges) results = tournament.play(progress_bar=False) expected_ranked_names = [ "Cooperator", "Tit For Tat", "Grudger", "Defector" ] self.assertEqual(results.ranked_names, expected_ranked_names) # Check that this tournament runs with noise tournament = axelrod.Tournament(players, edges=edges, noise=.5) results = tournament.play(progress_bar=False) self.assertIsInstance(results, axelrod.ResultSet)
class TestFingerprint(unittest.TestCase): @classmethod def setUpClass(cls): cls.strategy = axl.WinStayLoseShift cls.probe = axl.TitForTat cls.expected_points = [(0.0, 0.0), (0.0, 0.5), (0.0, 1.0), (0.5, 0.0), (0.5, 0.5), (0.5, 1.0), (1.0, 0.0), (1.0, 0.5), (1.0, 1.0)] cls.expected_edges = [(0, 1), (0, 2), (0, 3), (0, 4), (0, 5), (0, 6), (0, 7), (0, 8), (0, 9)] def test_create_points(self): test_points = create_points(0.5, progress_bar=False) self.assertEqual(test_points, self.expected_points) def test_create_jossann(self): # x + y < 1 ja = create_jossann((.5, .4), self.probe) self.assertEqual(str(ja), "Joss-Ann Tit For Tat: (0.5, 0.4)") # x + y = 1 ja = create_jossann((.4, .6), self.probe) self.assertEqual(str(ja), "Dual Joss-Ann Tit For Tat: (0.6, 0.4)") # x + y > 1 ja = create_jossann((.5, .6), self.probe) self.assertEqual(str(ja), "Dual Joss-Ann Tit For Tat: (0.5, 0.4)") def test_create_jossann_parametrised_player(self): probe = axl.Random(p=0.1) # x + y < 1 ja = create_jossann((.5, .4), probe) self.assertEqual(str(ja), "Joss-Ann Random: 0.1: (0.5, 0.4)") # x + y = 1 ja = create_jossann((.4, .6), probe) self.assertEqual(str(ja), "Dual Joss-Ann Random: 0.1: (0.6, 0.4)") # x + y > 1 ja = create_jossann((.5, .6), probe) self.assertEqual(str(ja), "Dual Joss-Ann Random: 0.1: (0.5, 0.4)") def test_create_probes(self): probes = create_probes(self.probe, self.expected_points, progress_bar=False) self.assertEqual(len(probes), 9) def test_create_edges(self): edges = create_edges(self.expected_points, progress_bar=False) self.assertEqual(edges, self.expected_edges) def test_generate_data(self): interactions = { (0, 1): [[(C, C)], [(C, C)]], (0, 2): [[(C, C), (C, C)], [(C, D)]], (0, 3): [[(C, C), (D, C)]], (0, 4): [[(C, C), (D, C)], [(D, D)]], (0, 5): [[(C, D), (D, C)]], (0, 6): [[(C, D), (C, D)]], (0, 7): [[(C, D), (D, D)]], (0, 8): [[(D, D), (D, D)]], (0, 9): [[(D, C), (D, C)]], } expected = { Point(0.0, 0.0): 3.0, Point(0.0, 0.5): 1.5, Point(0.0, 1.0): 4.0, Point(0.5, 0.0): 2.5, Point(0.5, 0.5): 2.5, Point(0.5, 1.0): 0.0, Point(1.0, 0.0): 0.5, Point(1.0, 0.5): 1.0, Point(1.0, 1.0): 5.0, } data = generate_data(interactions, self.expected_points, self.expected_edges) self.assertEqual(data, expected) def test_reshape_data(self): test_points = [ Point(x=0.0, y=0.0), Point(x=0.0, y=0.5), Point(x=0.0, y=1.0), Point(x=0.5, y=0.0), Point(x=0.5, y=0.5), Point(x=0.5, y=1.0), Point(x=1.0, y=0.0), Point(x=1.0, y=0.5), Point(x=1.0, y=1.0) ] test_data = { Point(x=0.0, y=0.0): 5, Point(x=0.0, y=0.5): 9, Point(x=0.0, y=1.0): 3, Point(x=0.5, y=0.0): 8, Point(x=0.5, y=0.5): 2, Point(x=0.5, y=1.0): 4, Point(x=1.0, y=0.0): 2, Point(x=1.0, y=0.5): 1, Point(x=1.0, y=1.0): 9 } test_shaped_data = [[3, 4, 9], [9, 2, 1], [5, 8, 2]] plotting_data = reshape_data(test_data, test_points, 3) for i in range(len(plotting_data)): self.assertEqual(list(plotting_data[i]), test_shaped_data[i]) def test_default_init(self): fingerprint = AshlockFingerprint(self.strategy) self.assertEqual(fingerprint.strategy, self.strategy) self.assertEqual(fingerprint.probe, self.probe) def test_init(self): fingerprint = AshlockFingerprint(self.strategy, self.probe) self.assertEqual(fingerprint.strategy, self.strategy) self.assertEqual(fingerprint.probe, self.probe) def test_init_with_instance(self): player = self.strategy() fingerprint = AshlockFingerprint(player) self.assertEqual(fingerprint.strategy, player) self.assertEqual(fingerprint.probe, self.probe) probe_player = self.probe() fingerprint = AshlockFingerprint(self.strategy, probe_player) self.assertEqual(fingerprint.strategy, self.strategy) self.assertEqual(fingerprint.probe, probe_player) fingerprint = AshlockFingerprint(player, probe_player) self.assertEqual(fingerprint.strategy, player) self.assertEqual(fingerprint.probe, probe_player) def test_construct_tournament_elemets(self): af = AshlockFingerprint(self.strategy, self.probe) edges, tournament_players = af.construct_tournament_elements( 0.5, progress_bar=False) self.assertEqual(edges, self.expected_edges) self.assertEqual(len(tournament_players), 10) self.assertEqual(tournament_players[0].__class__, af.strategy) def test_progress_bar_fingerprint(self): af = AshlockFingerprint(self.strategy, self.probe) data = af.fingerprint(turns=10, repetitions=2, step=0.5, progress_bar=True) self.assertEqual(sorted(data.keys()), self.expected_points) @patch('axelrod.fingerprint.mkstemp', RecordedMksTemp.mkstemp) def test_temp_file_creation(self): RecordedMksTemp.reset_record() af = AshlockFingerprint(self.strategy, self.probe) filename = "test_outputs/test_fingerprint.csv" self.assertEqual(RecordedMksTemp.record, []) # Temp file is created and destroyed. af.fingerprint(turns=1, repetitions=1, step=0.5, progress_bar=False, filename=None) self.assertEqual(len(RecordedMksTemp.record), 1) filename = RecordedMksTemp.record[0][1] self.assertIsInstance(filename, str) self.assertNotEqual(filename, '') self.assertFalse(os.path.isfile(filename)) def test_fingerprint_with_filename(self): filename = "test_outputs/test_fingerprint.csv" af = AshlockFingerprint(self.strategy, self.probe) af.fingerprint(turns=1, repetitions=1, step=0.5, progress_bar=False, filename=filename) with open(filename, 'r') as out: data = out.read() self.assertEqual(len(data.split("\n")), 20) def test_serial_fingerprint(self): af = AshlockFingerprint(self.strategy, self.probe) data = af.fingerprint(turns=10, repetitions=2, step=0.5, progress_bar=False) edge_keys = sorted(list(af.interactions.keys())) coord_keys = sorted(list(data.keys())) self.assertEqual(af.step, 0.5) self.assertEqual(edge_keys, self.expected_edges) self.assertEqual(coord_keys, self.expected_points) def test_parallel_fingerprint(self): af = AshlockFingerprint(self.strategy, self.probe) af.fingerprint(turns=10, repetitions=2, step=0.5, processes=2, progress_bar=False) edge_keys = sorted(list(af.interactions.keys())) coord_keys = sorted(list(af.data.keys())) self.assertEqual(af.step, 0.5) self.assertEqual(edge_keys, self.expected_edges) self.assertEqual(coord_keys, self.expected_points) def test_plot(self): af = AshlockFingerprint(self.strategy, self.probe) af.fingerprint(turns=10, repetitions=2, step=0.25, progress_bar=False) p = af.plot() self.assertIsInstance(p, matplotlib.pyplot.Figure) q = af.plot(cmap='jet') self.assertIsInstance(q, matplotlib.pyplot.Figure) r = af.plot(interpolation='bicubic') self.assertIsInstance(r, matplotlib.pyplot.Figure) t = af.plot(title='Title') self.assertIsInstance(t, matplotlib.pyplot.Figure) u = af.plot(colorbar=False) self.assertIsInstance(u, matplotlib.pyplot.Figure) v = af.plot(labels=False) self.assertIsInstance(v, matplotlib.pyplot.Figure) def test_wsls_fingerprint(self): axl.seed(0) # Fingerprinting is a random process test_data = { Point(x=0.0, y=0.0): 3.000, Point(x=0.0, y=0.25): 1.710, Point(x=0.0, y=0.5): 1.440, Point(x=0.0, y=0.75): 1.080, Point(x=0.0, y=1.0): 0.500, Point(x=0.25, y=0.0): 3.000, Point(x=0.25, y=0.25): 2.280, Point(x=0.25, y=0.5): 1.670, Point(x=0.25, y=0.75): 1.490, Point(x=0.25, y=1.0): 0.770, Point(x=0.5, y=0.0): 3.000, Point(x=0.5, y=0.25): 2.740, Point(x=0.5, y=0.5): 2.240, Point(x=0.5, y=0.75): 1.730, Point(x=0.5, y=1.0): 1.000, Point(x=0.75, y=0.0): 3.000, Point(x=0.75, y=0.25): 3.520, Point(x=0.75, y=0.5): 2.830, Point(x=0.75, y=0.75): 1.750, Point(x=0.75, y=1.0): 1.250, Point(x=1.0, y=0.0): 3.000, Point(x=1.0, y=0.25): 4.440, Point(x=1.0, y=0.5): 4.410, Point(x=1.0, y=0.75): 4.440, Point(x=1.0, y=1.0): 1.300 } af = axl.AshlockFingerprint(self.strategy, self.probe) data = af.fingerprint(turns=50, repetitions=2, step=0.25, progress_bar=False) for key, value in data.items(): self.assertAlmostEqual(value, test_data[key], places=2) def test_tft_fingerprint(self): axl.seed(0) # Fingerprinting is a random process test_data = { Point(x=0.0, y=0.0): 3.000, Point(x=0.0, y=0.25): 1.820, Point(x=0.0, y=0.5): 1.130, Point(x=0.0, y=0.75): 1.050, Point(x=0.0, y=1.0): 0.980, Point(x=0.25, y=0.0): 3.000, Point(x=0.25, y=0.25): 2.440, Point(x=0.25, y=0.5): 1.770, Point(x=0.25, y=0.75): 1.700, Point(x=0.25, y=1.0): 1.490, Point(x=0.5, y=0.0): 3.000, Point(x=0.5, y=0.25): 2.580, Point(x=0.5, y=0.5): 2.220, Point(x=0.5, y=0.75): 2.000, Point(x=0.5, y=1.0): 1.940, Point(x=0.75, y=0.0): 3.000, Point(x=0.75, y=0.25): 2.730, Point(x=0.75, y=0.5): 2.290, Point(x=0.75, y=0.75): 2.310, Point(x=0.75, y=1.0): 2.130, Point(x=1.0, y=0.0): 3.000, Point(x=1.0, y=0.25): 2.790, Point(x=1.0, y=0.5): 2.480, Point(x=1.0, y=0.75): 2.310, Point(x=1.0, y=1.0): 2.180 } af = axl.AshlockFingerprint(axl.TitForTat, self.probe) data = af.fingerprint(turns=50, repetitions=2, step=0.25, progress_bar=False) for key, value in data.items(): self.assertAlmostEqual(value, test_data[key], places=2) def test_majority_fingerprint(self): axl.seed(0) # Fingerprinting is a random process test_data = { Point(x=0.0, y=0.0): 3.000, Point(x=0.0, y=0.25): 1.940, Point(x=0.0, y=0.5): 1.130, Point(x=0.0, y=0.75): 1.030, Point(x=0.0, y=1.0): 0.980, Point(x=0.25, y=0.0): 3.000, Point(x=0.25, y=0.25): 2.130, Point(x=0.25, y=0.5): 1.940, Point(x=0.25, y=0.75): 2.060, Point(x=0.25, y=1.0): 1.940, Point(x=0.5, y=0.0): 3.000, Point(x=0.5, y=0.25): 2.300, Point(x=0.5, y=0.5): 2.250, Point(x=0.5, y=0.75): 2.420, Point(x=0.5, y=1.0): 2.690, Point(x=0.75, y=0.0): 3.000, Point(x=0.75, y=0.25): 2.400, Point(x=0.75, y=0.5): 2.010, Point(x=0.75, y=0.75): 2.390, Point(x=0.75, y=1.0): 2.520, Point(x=1.0, y=0.0): 3.000, Point(x=1.0, y=0.25): 2.360, Point(x=1.0, y=0.5): 1.740, Point(x=1.0, y=0.75): 2.260, Point(x=1.0, y=1.0): 2.260 } af = axl.AshlockFingerprint(axl.GoByMajority, self.probe) data = af.fingerprint(turns=50, repetitions=2, step=0.25, progress_bar=False) for key, value in data.items(): self.assertAlmostEqual(value, test_data[key], places=2) @given(strategy_pair=strategy_lists(min_size=2, max_size=2)) @settings(max_examples=5, max_iterations=20) def test_pair_fingerprints(self, strategy_pair): """ A test to check that we can fingerprint with any two given strategies or instances """ strategy, probe = strategy_pair af = AshlockFingerprint(strategy, probe) data = af.fingerprint(turns=2, repetitions=2, step=0.5, progress_bar=False) self.assertIsInstance(data, dict) af = AshlockFingerprint(strategy(), probe) data = af.fingerprint(turns=2, repetitions=2, step=0.5, progress_bar=False) self.assertIsInstance(data, dict) af = AshlockFingerprint(strategy, probe()) data = af.fingerprint(turns=2, repetitions=2, step=0.5, progress_bar=False) self.assertIsInstance(data, dict) af = AshlockFingerprint(strategy(), probe()) data = af.fingerprint(turns=2, repetitions=2, step=0.5, progress_bar=False) self.assertIsInstance(data, dict)
class TestPlayer(unittest.TestCase): """A Test class from which other player test classes are inherited.""" player = TestOpponent expected_class_classifier = None def test_initialisation(self): """Test that the player initiates correctly.""" if self.__class__ != TestPlayer: player = self.player() self.assertEqual(len(player.history), 0) self.assertEqual( player.match_attributes, { "length": -1, "game": axl.DefaultGame, "noise": 0 }, ) self.assertEqual(player.cooperations, 0) self.assertEqual(player.defections, 0) self.classifier_test(self.expected_class_classifier) def test_repr(self): """Test that the representation is correct.""" if self.__class__ != TestPlayer: self.assertEqual(str(self.player()), self.name) def test_match_attributes(self): player = self.player() # Default player.set_match_attributes() t_attrs = player.match_attributes self.assertEqual(t_attrs["length"], -1) self.assertEqual(t_attrs["noise"], 0) self.assertEqual(t_attrs["game"].RPST(), (3, 1, 0, 5)) # Common player.set_match_attributes(length=200) t_attrs = player.match_attributes self.assertEqual(t_attrs["length"], 200) self.assertEqual(t_attrs["noise"], 0) self.assertEqual(t_attrs["game"].RPST(), (3, 1, 0, 5)) # Noisy player.set_match_attributes(length=200, noise=0.5) t_attrs = player.match_attributes self.assertEqual(t_attrs["noise"], 0.5) def equality_of_players_test(self, p1, p2, seed, opponent): a1 = opponent() a2 = opponent() self.assertEqual(p1, p2) for player, op in [(p1, a1), (p2, a2)]: m = axl.Match(players=(player, op), turns=10, seed=seed) m.play() self.assertEqual(p1, p2) p1 = pickle.loads(pickle.dumps(p1)) p2 = pickle.loads(pickle.dumps(p2)) self.assertEqual(p1, p2) @given( opponent=sampled_from(short_run_time_short_mem), seed=integers(min_value=1, max_value=200), ) @settings(max_examples=1, deadline=None) def test_equality_of_clone(self, seed, opponent): p1 = self.player() p2 = p1.clone() self.equality_of_players_test(p1, p2, seed, opponent) @given( opponent=sampled_from(axl.short_run_time_strategies), seed=integers(min_value=1, max_value=200), ) @settings(max_examples=1, deadline=None) def test_equality_of_pickle_clone(self, seed, opponent): p1 = self.player() p2 = pickle.loads(pickle.dumps(p1)) self.equality_of_players_test(p1, p2, seed, opponent) def test_reset_history_and_attributes(self): """Make sure resetting works correctly.""" for opponent in [ axl.Defector(), axl.Random(), axl.Alternator(), axl.Cooperator(), ]: player = self.player() clone = player.clone() match = axl.Match((player, opponent), turns=10, seed=111) match.play() player.reset() self.assertEqual(player, clone) def test_reset_clone(self): """Make sure history resetting with cloning works correctly, regardless if self.test_reset() is overwritten.""" player = self.player() clone = player.clone() self.assertEqual(player, clone) @given(seed=integers(min_value=1, max_value=20000000), turns=integers(min_value=5, max_value=10), noise=integers(min_value=0, max_value=10)) @settings(max_examples=1, deadline=None) 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) @given( strategies=strategy_lists(max_size=5, strategies=short_run_time_short_mem), seed=integers(min_value=1, max_value=200), turns=integers(min_value=1, max_value=200), ) @settings(max_examples=1, deadline=None) def test_memory_depth_upper_bound(self, strategies, seed, turns): """ Test that the memory depth is indeed an upper bound. """ def get_memory_depth_or_zero(player): # Some of the test strategies have no entry in the classifiers # table, so there isn't logic to load default value of zero. memory = axl.Classifiers["memory_depth"](player) return memory if memory else 0 player = self.player() memory = get_memory_depth_or_zero(player) if memory < float("inf"): for strategy in strategies: player.reset() opponent = strategy() max_memory = max(memory, get_memory_depth_or_zero(opponent)) self.assertTrue( test_memory( player=player, opponent=opponent, seed=seed, turns=turns, memory_length=max_memory, ), msg="{} failed for seed={} and opponent={}".format( player.name, seed, opponent), ) def versus_test( self, opponent, expected_actions, turns=None, noise=None, seed=None, match_attributes=None, attrs=None, init_kwargs=None, ): """ Tests a sequence of outcomes for two given players. Parameters: ----------- opponent: Player or list An instance of a player OR a sequence of actions. If a sequence of actions is passed, a Mock Player is created that cycles over that sequence. expected_actions: List The expected outcomes of the match (list of tuples of actions). noise: float Any noise to be passed to a match seed: int The random seed to be used match_attributes: dict The match attributes to be passed to the players. For example, `{length:-1}` implies that the players do not know the length of the match. attrs: dict Dictionary of internal attributes to check at the end of all plays in player init_kwargs: dict A dictionary of keyword arguments to instantiate player with """ if init_kwargs is None: init_kwargs = dict() player = self.player(**init_kwargs) test_match = TestMatch() test_match.versus_test(player, opponent, [x for (x, y) in expected_actions], [y for (x, y) in expected_actions], turns=turns, noise=noise, seed=seed, attrs=attrs, match_attributes=match_attributes) def classifier_test(self, expected_class_classifier=None): """Test that the keys in the expected_classifier dictionary give the expected values in the player classifier dictionary. Also checks that two particular keys (memory_depth and stochastic) are in the dictionary.""" player = self.player() # Test that player has same classifier as its class unless otherwise # specified if expected_class_classifier is None: expected_class_classifier = player.classifier actual_class_classifier = { c: axl.Classifiers[c](player) for c in expected_class_classifier.keys() } self.assertEqual(expected_class_classifier, actual_class_classifier) self.assertTrue( "memory_depth" in player.classifier, msg="memory_depth not in classifier", ) self.assertTrue( "stochastic" in player.classifier, msg="stochastic not in classifier", ) for key in TestOpponent.classifier: self.assertEqual( axl.Classifiers[key](player), self.expected_classifier[key], msg="%s - Behaviour: %s != Expected Behaviour: %s" % ( key, axl.Classifiers[key](player), self.expected_classifier[key], ), )
class TestMoranProcess(unittest.TestCase): def test_init(self): players = axl.Cooperator(), axl.Defector() mp = axl.MoranProcess(players) self.assertEqual(mp.turns, axl.DEFAULT_TURNS) self.assertIsNone(mp.prob_end) self.assertIsNone(mp.game) self.assertEqual(mp.noise, 0) self.assertEqual(mp.initial_players, players) self.assertEqual(mp.players, list(players)) self.assertEqual(mp.populations, [Counter({ "Cooperator": 1, "Defector": 1 })]) self.assertIsNone(mp.winning_strategy_name) self.assertEqual(mp.mutation_rate, 0) self.assertEqual(mp.mode, "bd") self.assertEqual(mp.deterministic_cache, axl.DeterministicCache()) self.assertEqual(mp.mutation_targets, { "Cooperator": [players[1]], "Defector": [players[0]] }) self.assertEqual(mp.interaction_graph._edges, [(0, 1), (1, 0)]) self.assertEqual(mp.reproduction_graph._edges, [(0, 1), (1, 0), (0, 0), (1, 1)]) self.assertEqual(mp.fitness_transformation, None) self.assertEqual(mp.locations, [0, 1]) self.assertEqual(mp.index, {0: 0, 1: 1}) # Test non default graph cases players = axl.Cooperator(), axl.Defector(), axl.TitForTat() edges = [(0, 1), (2, 0), (1, 2)] graph = axl.graph.Graph(edges, directed=True) mp = axl.MoranProcess(players, interaction_graph=graph) self.assertEqual(mp.interaction_graph._edges, [(0, 1), (2, 0), (1, 2)]) self.assertEqual( sorted(mp.reproduction_graph._edges), sorted([(0, 1), (2, 0), (1, 2), (0, 0), (1, 1), (2, 2)]), ) mp = axl.MoranProcess(players, interaction_graph=graph, reproduction_graph=graph) self.assertEqual(mp.interaction_graph._edges, [(0, 1), (2, 0), (1, 2)]) self.assertEqual(mp.reproduction_graph._edges, [(0, 1), (2, 0), (1, 2)]) def test_set_players(self): """Test that set players resets all players""" players = axl.Cooperator(), axl.Defector() mp = axl.MoranProcess(players) players[0].history.append(C, D) mp.set_players() self.assertEqual(players[0].cooperations, 0) def test_mutate(self): """Test that a mutated player is returned""" players = axl.Cooperator(), axl.Defector(), axl.TitForTat() mp = MoranProcess(players, mutation_rate=0.5, seed=0) self.assertEqual(mp.mutate(0), players[0]) mp = MoranProcess(players, mutation_rate=0.5, seed=2) self.assertEqual(mp.mutate(0), players[2]) mp = MoranProcess(players, mutation_rate=0.5, seed=7) self.assertEqual(mp.mutate(0), players[1]) def test_death_in_db(self): players = axl.Cooperator(), axl.Defector(), axl.TitForTat() mp = MoranProcess(players, mutation_rate=0.5, mode="db", seed=1) self.assertEqual(mp.death(), 2) self.assertEqual(mp.dead, 2) mp = MoranProcess(players, mutation_rate=0.5, mode="db", seed=2) self.assertEqual(mp.death(), 0) self.assertEqual(mp.dead, 0) mp = MoranProcess(players, mutation_rate=0.5, mode="db", seed=9) self.assertEqual(mp.death(), 1) self.assertEqual(mp.dead, 1) def test_death_in_bd(self): players = axl.Cooperator(), axl.Defector(), axl.TitForTat() edges = [(0, 1), (2, 0), (1, 2)] graph = axl.graph.Graph(edges, directed=True) mp = MoranProcess(players, mode="bd", interaction_graph=graph, seed=1) self.assertEqual(mp.death(0), 1) mp = MoranProcess(players, mode="bd", interaction_graph=graph, seed=2) self.assertEqual(mp.death(0), 1) mp = MoranProcess(players, mode="bd", interaction_graph=graph, seed=3) self.assertEqual(mp.death(0), 0) def test_birth_in_db(self): players = axl.Cooperator(), axl.Defector(), axl.TitForTat() mp = MoranProcess(players, mode="db", seed=1) self.assertEqual(mp.death(), 2) self.assertEqual(mp.birth(0), 2) def test_birth_in_bd(self): players = axl.Cooperator(), axl.Defector(), axl.TitForTat() mp = MoranProcess(players, mode="bd", seed=2) self.assertEqual(mp.birth(), 0) def test_fixation_check(self): players = axl.Cooperator(), axl.Cooperator() mp = axl.MoranProcess(players) self.assertTrue(mp.fixation_check()) players = axl.Cooperator(), axl.Defector() mp = axl.MoranProcess(players) self.assertFalse(mp.fixation_check()) def test_next(self): players = axl.Cooperator(), axl.Defector() mp = axl.MoranProcess(players) self.assertIsInstance(next(mp), axl.MoranProcess) def test_matchup_indices(self): players = axl.Cooperator(), axl.Defector() mp = axl.MoranProcess(players) self.assertEqual(mp._matchup_indices(), {(0, 1)}) players = axl.Cooperator(), axl.Defector(), axl.TitForTat() edges = [(0, 1), (2, 0), (1, 2)] graph = axl.graph.Graph(edges, directed=True) mp = axl.MoranProcess(players, mode="bd", interaction_graph=graph) self.assertEqual(mp._matchup_indices(), {(0, 1), (1, 2), (2, 0)}) def test_fps(self): players = axl.Cooperator(), axl.Defector() mp = MoranProcess(players, seed=1) self.assertEqual(mp.fitness_proportionate_selection([0, 0, 1]), 2) self.assertEqual(mp.fitness_proportionate_selection([1, 1, 1]), 2) self.assertEqual(mp.fitness_proportionate_selection([1, 1, 1]), 0) def test_exit_condition(self): p1, p2 = axl.Cooperator(), axl.Cooperator() mp = axl.MoranProcess((p1, p2)) mp.play() self.assertEqual(len(mp), 1) @given(seed=integers(min_value=1, max_value=4294967295)) @settings(max_examples=5, deadline=None) def test_seeding_equality(self, seed): players = [axl.Random(x) for x in (0.2, 0.4, 0.6, 0.8)] mp1 = MoranProcess(players, seed=seed) mp1.play() mp2 = MoranProcess(players, seed=seed) mp2.play() self.assertEqual(mp1.populations, mp2.populations) def test_seeding_inequality(self): players = [axl.Random(x) for x in (0.2, 0.4, 0.6, 0.8)] mp1 = MoranProcess(players, seed=0) mp1.play() mp2 = MoranProcess(players, seed=1) mp2.play() self.assertNotEqual(mp1, mp2) def test_two_players(self): p1, p2 = axl.Cooperator(), axl.Defector() mp = MoranProcess((p1, p2), seed=99) populations = mp.play() self.assertEqual(len(mp), 2) self.assertEqual(len(populations), 2) self.assertEqual(populations, mp.populations) self.assertEqual(mp.winning_strategy_name, str(p2)) def test_two_prob_end(self): p1, p2 = axl.Random(), axl.TitForTat() mp = MoranProcess((p1, p2), prob_end=0.5, seed=10) populations = mp.play() self.assertEqual(len(mp), 2) self.assertEqual(len(populations), 2) self.assertEqual(populations, mp.populations) self.assertEqual(mp.winning_strategy_name, str(p1)) def test_different_game(self): # Possible for Cooperator to become fixed when using a different game p1, p2 = axl.Cooperator(), axl.Defector() game = axl.Game(r=4, p=2, s=1, t=6) mp = MoranProcess((p1, p2), turns=5, game=game, seed=88) populations = mp.play() self.assertEqual(mp.winning_strategy_name, str(p2)) def test_death_birth(self): """Two player death-birth should fixate after one round.""" p1, p2 = axl.Cooperator(), axl.Defector() seeds = range(0, 20) for seed in seeds: mp = MoranProcess((p1, p2), mode="db", seed=seed) mp.play() self.assertIsNotNone(mp.winning_strategy_name) # Number of populations is 2: the original and the one after the first round. self.assertEqual(len(mp.populations), 2) def test_death_birth_outcomes(self): """Show that birth-death and death-birth can produce different outcomes.""" seeds = [(1, True), (23, False)] players = [] N = 6 for _ in range(N // 2): players.append(axl.Cooperator()) players.append(axl.Defector()) for seed, outcome in seeds: mp = MoranProcess(players, mode="bd", seed=seed) mp.play() winner = mp.winning_strategy_name mp = MoranProcess(players, mode="db", seed=seed) mp.play() winner2 = mp.winning_strategy_name self.assertEqual((winner == winner2), outcome) def test_two_random_players(self): p1, p2 = axl.Random(p=0.5), axl.Random(p=0.25) mp = MoranProcess((p1, p2), seed=66) populations = mp.play() self.assertEqual(len(mp), 2) self.assertEqual(len(populations), 2) self.assertEqual(populations, mp.populations) self.assertEqual(mp.winning_strategy_name, str(p1)) def test_two_players_with_mutation(self): p1, p2 = axl.Cooperator(), axl.Defector() mp = MoranProcess((p1, p2), mutation_rate=0.2, stop_on_fixation=False, seed=5) self.assertDictEqual(mp.mutation_targets, { str(p1): [p2], str(p2): [p1] }) # Test that mutation causes the population to alternate between # fixations counters = [ Counter({"Cooperator": 2}), Counter({"Defector": 2}), Counter({"Cooperator": 2}), Counter({"Defector": 2}), ] for counter in counters: for _ in itertools.takewhile( lambda x: x.population_distribution() != counter, mp): pass self.assertEqual(mp.population_distribution(), counter) def test_play_exception(self): p1, p2 = axl.Cooperator(), axl.Defector() mp = axl.MoranProcess((p1, p2), mutation_rate=0.2) with self.assertRaises(ValueError): mp.play() def test_three_players(self): players = [axl.Cooperator(), axl.Cooperator(), axl.Defector()] mp = MoranProcess(players, seed=11) populations = mp.play() self.assertEqual(len(mp), 7) self.assertEqual(len(populations), 7) self.assertEqual(populations, mp.populations) self.assertEqual(mp.winning_strategy_name, str(axl.Defector())) def test_three_players_with_mutation(self): p1 = axl.Cooperator() p2 = axl.Random() p3 = axl.Defector() players = [p1, p2, p3] mp = axl.MoranProcess(players, mutation_rate=0.2, stop_on_fixation=False) self.assertDictEqual( mp.mutation_targets, { str(p1): [p3, p2], str(p2): [p1, p3], str(p3): [p1, p2] }, ) # Test that mutation causes the population to alternate between # fixations counters = [Counter({"Cooperator": 3}), Counter({"Defector": 3})] for counter in counters: for _ in itertools.takewhile( lambda x: x.population_distribution() != counter, mp): pass self.assertEqual(mp.population_distribution(), counter) def test_four_players(self): players = [axl.Cooperator() for _ in range(3)] players.append(axl.Defector()) mp = MoranProcess(players, seed=29) populations = mp.play() self.assertEqual(len(mp), 8) self.assertEqual(len(populations), 8) self.assertEqual(populations, mp.populations) self.assertEqual(mp.winning_strategy_name, str(axl.Defector())) @given(strategies=strategy_lists(min_size=2, max_size=4)) @settings(max_examples=5, deadline=None) # Two specific examples relating to cloning of strategies @example(strategies=[axl.BackStabber, axl.MindReader]) @example(strategies=[axl.ThueMorse, axl.MindReader]) def test_property_players(self, strategies): """Hypothesis test that randomly checks players""" players = [s() for s in strategies] mp = axl.MoranProcess(players) populations = mp.play() self.assertEqual(populations, mp.populations) self.assertIn(mp.winning_strategy_name, [str(p) for p in players]) def test_reset(self): p1, p2 = axl.Cooperator(), axl.Defector() mp = MoranProcess((p1, p2), seed=45) mp.play() self.assertEqual(len(mp), 2) self.assertEqual(len(mp.score_history), 1) mp.reset() self.assertEqual(len(mp), 1) self.assertEqual(mp.winning_strategy_name, None) self.assertEqual(mp.score_history, []) # Check that players reset for player, initial_player in zip(mp.players, mp.initial_players): self.assertEqual(str(player), str(initial_player)) def test_constant_fitness_case(self): # Scores between an Alternator and Defector will be: (1, 6) players = ( axl.Alternator(), axl.Alternator(), axl.Defector(), axl.Defector(), ) mp = MoranProcess(players, turns=2, seed=0) winners = [] for _ in range(100): mp.play() winners.append(mp.winning_strategy_name) mp.reset() winners = Counter(winners) self.assertEqual(winners["Defector"], 86) def test_cache(self): p1, p2 = axl.Cooperator(), axl.Defector() mp = axl.MoranProcess((p1, p2)) mp.play() self.assertEqual(len(mp.deterministic_cache), 1) # Check that can pass a pre-built cache cache = axl.DeterministicCache() mp = axl.MoranProcess((p1, p2), deterministic_cache=cache) self.assertEqual(cache, mp.deterministic_cache) def test_iter(self): p1, p2 = axl.Cooperator(), axl.Defector() mp = axl.MoranProcess((p1, p2)) self.assertEqual(mp.__iter__(), mp) def test_population_plot(self): # Test that can plot on a given matplotlib axes rng = axl.RandomGenerator(seed=15) players = [rng.choice(axl.demo_strategies)() for _ in range(5)] mp = axl.MoranProcess(players=players, turns=30, seed=20) mp.play() fig, axarr = plt.subplots(2, 2) ax = axarr[1, 0] mp.populations_plot(ax=ax) self.assertEqual(ax.get_xlim(), (-0.7000000000000001, 14.7)) self.assertEqual(ax.get_ylim(), (0, 5.25)) # Run without a given axis ax = mp.populations_plot() self.assertEqual(ax.get_xlim(), (-0.7000000000000001, 14.7)) self.assertEqual(ax.get_ylim(), (0, 5.25)) def test_cooperator_can_win_with_fitness_transformation(self): players = ( axl.Cooperator(), axl.Defector(), axl.Defector(), axl.Defector(), ) w = 0.95 fitness_transformation = lambda score: 1 - w + w * score mp = MoranProcess(players, turns=10, fitness_transformation=fitness_transformation, seed=3419) populations = mp.play() self.assertEqual(mp.winning_strategy_name, "Cooperator") def test_atomic_mutation_fsm(self): players = [ axl.EvolvableFSMPlayer(num_states=2, initial_state=1, initial_action=C, seed=4) for _ in range(5) ] mp = MoranProcess(players, turns=10, mutation_method="atomic", seed=12) rounds = 10 for _ in range(rounds): next(mp) self.assertEqual( list(sorted(mp.populations[-1].items()))[0][0], 'EvolvableFSMPlayer: ((0, C, 0, C), (0, D, 1, C), (1, C, 1, D), (1, D, 1, D)), 0, D, 2, 0.1, 2240802643' ) self.assertEqual(len(mp.populations), 11) self.assertFalse(mp.fixated) def test_atomic_mutation_cycler(self): cycle_length = 5 players = [ axl.EvolvableCycler(cycle_length=cycle_length, seed=4) for _ in range(5) ] mp = MoranProcess(players, turns=10, mutation_method="atomic", seed=10) rounds = 10 for _ in range(rounds): next(mp) self.assertEqual( list(mp.populations[-1].items())[0], ('EvolvableCycler: CCDDD, 5, 0.2, 1, 1164244177', 1)) self.assertEqual(len(mp.populations), 11) self.assertFalse(mp.fixated) def test_mutation_method_exceptions(self): cycle_length = 5 players = [ axl.EvolvableCycler(cycle_length=cycle_length, seed=4) for _ in range(5) ] with self.assertRaises(ValueError): MoranProcess(players, turns=10, mutation_method="random", seed=10) players = [ axl.Cycler(cycle="CD" * random.randint(2, 10)) for _ in range(10) ] mp = MoranProcess(players, turns=10, mutation_method="atomic", seed=53) with self.assertRaises(TypeError): for _ in range(10): next(mp)