From cb0e930e733db98a9cecfe8f8b51eb892f1e3842 Mon Sep 17 00:00:00 2001 From: Nikoleta Glynatsi Date: Tue, 21 Jun 2016 15:42:06 +0100 Subject: [PATCH 01/25] Have tests for Spatial Match generator. --- axelrod/tests/unit/test_match_generator.py | 29 ++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/axelrod/tests/unit/test_match_generator.py b/axelrod/tests/unit/test_match_generator.py index 4f49666ca..739db5e4d 100644 --- a/axelrod/tests/unit/test_match_generator.py +++ b/axelrod/tests/unit/test_match_generator.py @@ -207,3 +207,32 @@ def test_len(self, prob_end): self.players, prob_end, game=None, repetitions=repetitions) self.assertEqual(len(rr), len(list(rr.build_match_chunks()))) self.assertAlmostEqual(rr.estimated_size(), len(rr) * 1. / prob_end * repetitions) + + +class TestSpatialMatches(unittest.TestCase): + + @classmethod + def setUpClass(cls): + cls.players = [s() for s in test_strategies] + + @given(repetitions=integers(min_value=1, max_value=test_repetitions), + turns=integers(min_value=1, max_value=test_turns)) + @example(repetitions=test_repetitions, turns=test_turns) + def test_build_match_chunks(self, repetitions, turns): + edges = [(0, 1), (1, 2), (3, 4)] + sp = axelrod.SpatialMatches( + self.players, turns, test_game, repetitions, edges) + chunks = list(sp.build_match_chunks()) + match_definitions = [tuple(list(index_pair) + [repetitions]) + for (index_pair, match_params, repetitions) in chunks] + expected_match_definitions = [(edge[0], edge[1], repetitions) + for edge in edges] + + self.assertEqual(sorted(match_definitions), sorted(expected_match_definitions)) + + def test_len(self): + edges = [(0, 1), (1, 2), (3, 4)] + sp = axelrod.SpatialMatches( + self.players, test_turns, test_game, test_repetitions, edges) + self.assertEqual(len(sp), len(list(sp.build_match_chunks()))) + self.assertEqual(len(sp), len(edges)) From 9a75263a9b375b30913d2d3f6eccfa82d9f67e7a Mon Sep 17 00:00:00 2001 From: Nikoleta Glynatsi Date: Wed, 22 Jun 2016 12:07:52 +0100 Subject: [PATCH 02/25] Added a new class in the match generator, the SpatialMatches. This class can be used from the tournament to create matches with spatial structure topology. By spatial stucture, we mean a graph where the players are the nodes and they only play other players - nodes that are connected with a an edge. --- axelrod/match_generator.py | 53 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 53 insertions(+) diff --git a/axelrod/match_generator.py b/axelrod/match_generator.py index 75611fac0..caebbc97c 100644 --- a/axelrod/match_generator.py +++ b/axelrod/match_generator.py @@ -167,3 +167,56 @@ def estimated_size(self): """Rough estimate of the number of matches that will be generated.""" size = self.__len__() * (1. / self.prob_end) * self.repetitions return size + +class SpatialMatches(RoundRobinMatches): + + def __init__(self, players, turns, game, repetitions, edges): + self.edges = edges + super(RoundRobinMatches, self).__init__(players, turns, game, repetitions) + """ + A class that generates spatial structure matches. In spatial structure + matches the players do not play against every other player, instead they + only play their neighbors. + + In literature the authors interpreted spatial tournaments topology + as a 2D square lattice. We want to create a class that will not take as + an argument only a 2D lattice but any given graph. + + After considering various python packages for graphs, we ended up using + a simple dictionary that includes the edges.So the players - nodes will + only play players that are connected to with an edge. + + We have chosen to implement spatial structure tournaments because + it has spon various tournaments after the work of Nowak and May 1992, + + which proved that in PD cooperation behavior can merge for spatial + games. + + Moreover, IPD tournaments with this topology have been conducted by + various researchers such as Lindgren and Nordahl in 1994 + + and Brauchli, Killingback and Doebeli 1999. + + + Parameters + ---------- + players : list + A list of axelrod.Player objects + turns : integer + The number of turns per match + game : axelrod.Game + The game object used to score the match + repetitions : int + The number of repetitions of a given match + edges : dictionary + A dictionary containing the existing edges + """ + + def build_match_chunks(self): + for edge in self.edges: + match_params = self.build_single_match_params() + index_pair = edge + yield (index_pair, match_params, self.repetitions) + + def __len__(self): + return len(self.edges) From b6d2b9e8cdc7a66d5739032c6e95e0899305ab03 Mon Sep 17 00:00:00 2001 From: Nikoleta Glynatsi Date: Fri, 24 Jun 2016 10:48:18 +0100 Subject: [PATCH 03/25] Altering the arguments of super function in Spatial Match Generator. SpatialMatches is class created in the match generator file in order to create matches where not all players play each other. But instead the players, that are illustrated as nodes in a graph, only play with players that are connected to by an edge. SpatialMatches inherit from RoundRobinMatches but there is need for an extra argument taken by the class which is an edge dictionary. To achieve that we use the python function super. Super takes the name of the class and a self argument, and here we will replace what was previously written as super(RoundRobinMatches, self) with super(SpatialMatches, self). --- axelrod/match_generator.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/axelrod/match_generator.py b/axelrod/match_generator.py index caebbc97c..9de731ed9 100644 --- a/axelrod/match_generator.py +++ b/axelrod/match_generator.py @@ -172,7 +172,7 @@ class SpatialMatches(RoundRobinMatches): def __init__(self, players, turns, game, repetitions, edges): self.edges = edges - super(RoundRobinMatches, self).__init__(players, turns, game, repetitions) + super(SpatialMatches, self).__init__(players, turns, game, repetitions) """ A class that generates spatial structure matches. In spatial structure matches the players do not play against every other player, instead they From e432b87bbdba0b4ea2cf22d040c5cea18d96198c Mon Sep 17 00:00:00 2001 From: Nikoleta Glynatsi Date: Fri, 24 Jun 2016 11:07:04 +0100 Subject: [PATCH 04/25] Tests for the class SpatialTournament in the Tournament file. SpatialTournament is a class which will be running a Spatial Tournament by calling the SpatialMatches class we created before. It inherit for the class Tournament and these are some tests for the specific class. The tests for the SpatialTournament do not contain the hypothesis tests yet. They will be added shortly. We have run all the unit tests and we all 22 have passed. --- axelrod/tests/unit/test_tournament.py | 33 +++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/axelrod/tests/unit/test_tournament.py b/axelrod/tests/unit/test_tournament.py index 3d433cd7f..4ab0877e2 100644 --- a/axelrod/tests/unit/test_tournament.py +++ b/axelrod/tests/unit/test_tournament.py @@ -31,6 +31,8 @@ test_prob_end = .5 +test_edges = [(0, 1), (1, 2), (3, 4)] + class TestTournament(unittest.TestCase): @@ -548,3 +550,34 @@ def test_property_serial_play(self, tournament): self.assertEqual(results.players, [str(p) for p in tournament.players]) for rep in results.interactions.values(): self.assertEqual(len(rep), tournament.repetitions) + +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.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') From e5332a108ff71712e8ff5c060c0eded293bd434c Mon Sep 17 00:00:00 2001 From: Nikoleta Glynatsi Date: Fri, 24 Jun 2016 11:14:39 +0100 Subject: [PATCH 05/25] Adding Spatial Tournament Class. The Spatial Tournament class is a class resposinble for creating a Spatial structure tournament, where the players are respresented on a graph and they only matches are bewteen players-nodes connected with an edge. It does that by using the SpatialMatch class and it inherit from the tournament class. It's take a extra argument which is a dictionary called edges, that represents which nodes- players are connected and will face each other in the tournament. Proper testes for this class have been written and all are passing. --- axelrod/tournament.py | 42 +++++++++++++++++++++++++++++++++++++++++- 1 file changed, 41 insertions(+), 1 deletion(-) diff --git a/axelrod/tournament.py b/axelrod/tournament.py index 15716adbf..2b5f8666e 100644 --- a/axelrod/tournament.py +++ b/axelrod/tournament.py @@ -11,7 +11,7 @@ from .game import Game from .match import Match -from .match_generator import RoundRobinMatches, ProbEndRoundRobinMatches +from .match_generator import RoundRobinMatches, ProbEndRoundRobinMatches, SpatialMatches from .result_set import ResultSetFromFile @@ -335,3 +335,43 @@ def __init__(self, players, match_generator=ProbEndRoundRobinMatches, self.prob_end = prob_end self.match_generator = ProbEndRoundRobinMatches( players, prob_end, self.game, repetitions) + + +class SpatialTournament(Tournament): + """ + A tournament in which the players are allocated in a graph as nodes + and they players only play the others that are connected to with an edge. + """ + def __init__(self, players, edges, match_generator=SpatialMatches, + name='axelrod', game=None, turns=200, repetitions=10, + noise=0, + with_morality=True): + """ + Parameters + ---------- + players : list + A list of axelrod.Player objects + match_generator : class + A class that must be descended from axelrod.MatchGenerator + name : string + A name for the tournament + game : axelrod.Game + The game object used to score the tournament + edges : dictionary + A dictionary containing the existing edges + repetitions : integer + The number of times the round robin should be repeated + processes : integer + The number of processes to be used for parallel processing + noise : float + The probability that a player's intended action should be flipped + with_morality : boolean + Whether morality metrics should be calculated + """ + super(SpatialTournament, self).__init__( + players, name=name, game=game, turns=turns, + repetitions=repetitions, noise=noise, with_morality=with_morality) + + self.edges = edges + self.match_generator = SpatialMatches( + players, turns, self.game, repetitions, edges) From 87a8ec7f80eb5862fa13183c8d1f15bd895bb2eb Mon Sep 17 00:00:00 2001 From: Nikoleta Glynatsi Date: Fri, 24 Jun 2016 11:26:59 +0100 Subject: [PATCH 06/25] Adding Spatial Tournament to be imported into Axelrod. __init__.py file is responsible for importing functions and classes and putting everything together for axelrod library. Now that Spatial Tournament is written is has to be added in to be imported as well. The same was not needed to be done for SpatialMatches because __init__.py already imports everything for the file Match, which contains SpatialMatches. --- axelrod/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/axelrod/__init__.py b/axelrod/__init__.py index 7cb2ebda6..43bfa6729 100644 --- a/axelrod/__init__.py +++ b/axelrod/__init__.py @@ -12,6 +12,6 @@ from .strategies import * from .deterministic_cache import DeterministicCache from .match_generator import * -from .tournament import Tournament, ProbEndTournament +from .tournament import Tournament, ProbEndTournament, SpatialTournament from .result_set import ResultSet, ResultSetFromFile from .ecosystem import Ecosystem From d018a248af8fa496561bdf858351dc6ca0019de0 Mon Sep 17 00:00:00 2001 From: Nikoleta Glynatsi Date: Fri, 24 Jun 2016 14:35:03 +0100 Subject: [PATCH 07/25] Adding a Value Error for tournaments with disconnected nodes-players. In case a tournament is created containing disconnected nodes-players an Error will be displayed. That is because if a player does not have any interaction with any other player it should be removed from the tournament as not active player could not have a score or rank in the tournament. A player not participating is different from a player scoring zero and this should be noted. Also a test for this constrain was added in the test_match_generator. --- axelrod/match_generator.py | 7 ++++++- axelrod/tests/unit/test_match_generator.py | 7 +++++++ 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/axelrod/match_generator.py b/axelrod/match_generator.py index 9de731ed9..426b19723 100644 --- a/axelrod/match_generator.py +++ b/axelrod/match_generator.py @@ -171,6 +171,12 @@ def estimated_size(self): class SpatialMatches(RoundRobinMatches): def __init__(self, players, turns, game, repetitions, edges): + + player_indices = list(range(len(players))) + node_indices = sorted(set([node for edge in edges for node in edge])) + if player_indices != node_indices: + raise ValueError("The graph edges do not include all players.") + self.edges = edges super(SpatialMatches, self).__init__(players, turns, game, repetitions) """ @@ -211,7 +217,6 @@ def __init__(self, players, turns, game, repetitions, edges): edges : dictionary A dictionary containing the existing edges """ - def build_match_chunks(self): for edge in self.edges: match_params = self.build_single_match_params() diff --git a/axelrod/tests/unit/test_match_generator.py b/axelrod/tests/unit/test_match_generator.py index 739db5e4d..4790a6d55 100644 --- a/axelrod/tests/unit/test_match_generator.py +++ b/axelrod/tests/unit/test_match_generator.py @@ -236,3 +236,10 @@ def test_len(self): self.players, test_turns, test_game, test_repetitions, edges) self.assertEqual(len(sp), len(list(sp.build_match_chunks()))) self.assertEqual(len(sp), len(edges)) + +""" + def test_edges_that_do_not_include_all_players(self): + edges = [(0, 1)] + self.assertRaises(ValueError, axelrod.SpatialMatches, + self.players, test_turns, test_game, test_repetitions, edges) +""" From ba532195539cd35ce3e8c3a3d4b9652f0a7a39ee Mon Sep 17 00:00:00 2001 From: Nikoleta Glynatsi Date: Tue, 28 Jun 2016 09:42:22 +0100 Subject: [PATCH 08/25] Fixing test that was passing by chance. This test was not correct as the number of repetitions is not the same as the number of interactions. --- axelrod/tests/unit/test_resultset.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/axelrod/tests/unit/test_resultset.py b/axelrod/tests/unit/test_resultset.py index 4adbf513c..bdd8a2e90 100644 --- a/axelrod/tests/unit/test_resultset.py +++ b/axelrod/tests/unit/test_resultset.py @@ -164,7 +164,8 @@ def test_init(self): self.assertEqual(rs.players, self.players) self.assertEqual(rs.nplayers, len(self.players)) self.assertEqual(rs.interactions, self.interactions) - self.assertEqual(rs.nrepetitions, len(self.interactions)) + for inter in self.interactions.values(): + self.assertEqual(rs.nrepetitions, len(inter)) # Test structure of matches # This is really a test of the test From eaee751291985bdfb7fdce05b0d7958c3cf4c040 Mon Sep 17 00:00:00 2001 From: Nikoleta Glynatsi Date: Tue, 28 Jun 2016 10:33:07 +0100 Subject: [PATCH 09/25] Fixed self interactions being counted twice. --- axelrod/result_set.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/axelrod/result_set.py b/axelrod/result_set.py index cac7bc2b4..ad250897e 100644 --- a/axelrod/result_set.py +++ b/axelrod/result_set.py @@ -309,7 +309,7 @@ def build_payoffs(self): if (player, opponent) == index_pair: for interaction in repetitions: utilities.append(iu.compute_final_score_per_turn(interaction)[0]) - if (opponent, player) == index_pair: + elif (opponent, player) == index_pair: for interaction in repetitions: utilities.append(iu.compute_final_score_per_turn(interaction)[1]) @@ -460,7 +460,7 @@ def build_payoff_diffs_means(self): for interaction in repetitions: scores = iu.compute_final_score_per_turn(interaction) diffs.append(scores[0] - scores[1]) - if (opponent, player) == index_pair: + elif (opponent, player) == index_pair: for interaction in repetitions: scores = iu.compute_final_score_per_turn(interaction) diffs.append(scores[1] - scores[0]) @@ -501,7 +501,7 @@ def build_cooperation(self): if (player, opponent) == index_pair: for interaction in repetitions: coop_count += iu.compute_cooperations(interaction)[0] - if (opponent, player) == index_pair: + elif (opponent, player) == index_pair: for interaction in repetitions: coop_count += iu.compute_cooperations(interaction)[1] @@ -625,7 +625,7 @@ def build_good_partner_matrix(self): if coops[0] >= coops[1]: good_partner_matrix[player][opponent] += 1 - if (opponent, player) == index_pair: + elif (opponent, player) == index_pair: for interaction in repetitions: coops = iu.compute_cooperations(interaction) if coops[0] <= coops[1]: From 7733d86e8e37195b0a6169e4454841056eb8f127 Mon Sep 17 00:00:00 2001 From: Nikoleta Glynatsi Date: Tue, 28 Jun 2016 10:57:48 +0100 Subject: [PATCH 10/25] Adding three tests for spatial. These need to be refactored into test_resultsset.py --- axelrod/tests/unit/test_spatial_one.py | 360 +++++++++++++++++++++ axelrod/tests/unit/test_spatial_three.py | 366 ++++++++++++++++++++++ axelrod/tests/unit/test_spatial_two.py | 382 +++++++++++++++++++++++ 3 files changed, 1108 insertions(+) create mode 100644 axelrod/tests/unit/test_spatial_one.py create mode 100644 axelrod/tests/unit/test_spatial_three.py create mode 100644 axelrod/tests/unit/test_spatial_two.py diff --git a/axelrod/tests/unit/test_spatial_one.py b/axelrod/tests/unit/test_spatial_one.py new file mode 100644 index 000000000..4f452c11d --- /dev/null +++ b/axelrod/tests/unit/test_spatial_one.py @@ -0,0 +1,360 @@ +import unittest +import axelrod + +from numpy import mean, std + +import tempfile + +from hypothesis import given +from hypothesis.strategies import floats, integers + +class TestResultSet_SpatialStructure(unittest.TestCase): + + @classmethod + def setUpClass(cls): + + cls.players = (axelrod.Alternator(), axelrod.TitForTat(), axelrod.Defector()) + cls.turns = 5 + cls.edges = [(0, 1), (0, 2)] + cls.matches = { (0,1): [axelrod.Match((cls.players[0], cls.players[1]), + turns=cls.turns) for _ in range(3)], + (0,2): [axelrod.Match((cls.players[0], cls.players[2]), + turns=cls.turns) for _ in range(3)]} + + cls.interactions = {} + for index_pair, matches in cls.matches.items(): + for match in matches: + match.play() + try: + cls.interactions[index_pair].append(match.result) + except KeyError: + cls.interactions[index_pair] = [match.result] + + + cls.expected_players_to_match_dicts = {0: cls.matches[(0, 1)] + cls.matches[(0, 2)], + 1: cls.matches[(0, 1)] , + 2: cls.matches[(0, 2)]} + + + + cls.expected_match_lengths =[ + [[0, 5, 5], [5, 0, 0], [5, 0, 0]] + for _ in range(3) + ] + + cls.expected_scores =[ + [15, 15, 15], + [13, 13, 13], + [17, 17, 17] + ] + + cls.expected_wins =[ + [0, 0, 0], + [0, 0, 0], + [1, 1, 1] + ] + + cls.expected_normalised_scores =[ + [3.0 / 2 for _ in range(3)], + [(13.0 / 5 ) for _ in range(3)], + [(17.0 / 5 ) for _ in range(3)], + ] + + cls.expected_ranking = [2, 1, 0] + + cls.expected_ranked_names = ['Defector', 'Tit For Tat', 'Alternator'] + + cls.expected_null_results_matrix = [ + [[0, 0, 0], [0, 0, 0], [0, 0, 0]], + [[0, 0, 0], [0, 0, 0], [0, 0, 0]], + [[0, 0, 0], [0, 0, 0], [0, 0, 0]], + ] + + cls.expected_payoffs = [ + [[], [13/5.0 for _ in range(3)], [2/5.0 for _ in range(3)]], + [[13/5.0 for _ in range(3)], [], []], + [[17/5.0 for _ in range(3)], [], []] + ] + + norm_scores = cls.expected_normalised_scores + cls.expected_score_diffs = [ + [[0.0, 0.0, 0.0], + [0.0, 0.0, 0.0], + [-3.0, -3.0, -3.0]], + [[0.0, 0.0, 0.0], + [0.0, 0.0, 0.0], + [0.0, 0.0, 0.0]], + [[3.0, 3.0, 3.0], + [0.0, 0.0, 0.0], + [0.0, 0.0, 0.0]], + ] + + cls.expected_payoff_diffs_means = [ + [0.0, 0.0, -3.0], + [0.0, 0.0, 0.0], + [3.0, 0.0, 0.0] + ] + + # Recalculating to deal with numeric imprecision + cls.expected_payoff_matrix = [ + [0, mean([13/5.0 for _ in range(3)]), mean([2/5.0 for _ in range(3)])], + [mean([13/5.0 for _ in range(3)]), 0, 0 ], + [mean([17/5.0 for _ in range(3)]), 0 , 0] + ] + + cls.expected_payoff_stddevs = [ + [0, std([13/5.0 for _ in range(3)]), std([2/5.0 for _ in range(3)])], + [std([13/5.0 for _ in range(3)]), 0, 0 ], + [std([17/5.0 for _ in range(3)]), 0, 0 ] + ] + + cls.expected_cooperation = [ + [0, 9, 9], + [9, 0, 0], + [0, 0, 0], + ] + + cls.expected_normalised_cooperation = [ + [0, mean([3 / 5.0 for _ in range(3)]), mean([3 / 5.0 for _ in range(3)])], + [mean([3 / 5.0 for _ in range(3)]), 0, 0 ], + [0, 0, 0], + ] + + cls.expected_vengeful_cooperation = [[2 * element - 1 for element in row] + for row in cls.expected_normalised_cooperation] + + cls.expected_cooperating_rating = [ + 18.0 / 30, + 9.0 / 15, + 0 + ] + + cls.expected_good_partner_matrix = [ + [0, 3, 3], + [3, 0, 0], + [0, 0, 0] + ] + + cls.expected_good_partner_rating = [ + 1.0, + 1.0, + 0 + ] + + cls.expected_eigenjesus_rating = [ + 0.447213595499958, + 0.894427190999916, + 0.0 + ] + + cls.expected_eigenmoses_rating = [ + -0.32929277996907086, + 0.7683498199278325, + 0.5488212999484519 + ] + + #cls.expected_csv = ( + # 'Defector,Tit For Tat,Alternator\n2.6,1.7,1.5\n2.6,1.7,1.5\n2.6,1.7,1.5\n') + + def test_init(self): + rs = axelrod.ResultSet(self.players, self.interactions, + progress_bar=False) + self.assertFalse(rs.progress_bar) + self.assertEqual(rs.players, self.players) + self.assertEqual(rs.nplayers, len(self.players)) + self.assertEqual(rs.interactions, self.interactions) + for inter in self.interactions.values(): + self.assertEqual(rs.nrepetitions, len(inter)) + + # Test structure of matches + # This is really a test of the test + for index_pair, repetitions in rs.interactions.items(): + self.assertIsInstance(repetitions, list) + self.assertIsInstance(index_pair, tuple) + for interaction in repetitions: + self.assertIsInstance(interaction, list) + self.assertEqual(len(interaction), self.turns) + + def test_with_progress_bar(self): + rs = axelrod.ResultSet(self.players, self.interactions) + self.assertTrue(rs.progress_bar) + self.assertEqual(rs.progress_bar.total, 19) + + rs = axelrod.ResultSet(self.players, self.interactions, + progress_bar=True) + self.assertTrue(rs.progress_bar) + self.assertEqual(rs.progress_bar.total, 19) + + def test_null_results_matrix(self): + rs = axelrod.ResultSet(self.players, self.interactions, + progress_bar=False) + self.assertEqual( + rs._null_results_matrix, self.expected_null_results_matrix) + + def test_match_lengths(self): + rs = axelrod.ResultSet(self.players, self.interactions, + progress_bar=False) + self.assertIsInstance(rs.match_lengths, list) + self.assertEqual(len(rs.match_lengths), rs.nrepetitions) + self.assertEqual(rs.match_lengths, self.expected_match_lengths) + + for rep in rs.match_lengths: + self.assertIsInstance(rep, list) + self.assertEqual(len(rep), len(self.players)) + + for i, opp in enumerate(rep): + self.assertIsInstance(opp, list) + self.assertEqual(len(opp), len(self.players)) + + for j, length in enumerate(opp): + edge = (i, j) + if edge in self.edges or edge[::-1] in self.edges : # Specific test for example match setup + self.assertEqual(length, self.turns) + else: + self.assertEqual(length, 0) + + def test_scores(self): + rs = axelrod.ResultSet(self.players, self.interactions, + progress_bar=False) + self.assertIsInstance(rs.scores, list) + self.assertEqual(len(rs.scores), rs.nplayers) + self.assertEqual(rs.scores, self.expected_scores) + + def test_ranking(self): + rs = axelrod.ResultSet(self.players, self.interactions, + progress_bar=False) + self.assertIsInstance(rs.ranking, list) + self.assertEqual(len(rs.ranking), rs.nplayers) + self.assertEqual(rs.ranking, self.expected_ranking) + + def test_ranked_names(self): + rs = axelrod.ResultSet(self.players, self.interactions, + progress_bar=False) + self.assertIsInstance(rs.ranked_names, list) + self.assertEqual(len(rs.ranked_names), rs.nplayers) + self.assertEqual(rs.ranked_names, self.expected_ranked_names) + + def test_wins(self): + rs = axelrod.ResultSet(self.players, self.interactions, + progress_bar=False) + self.assertIsInstance(rs.wins, list) + self.assertEqual(len(rs.wins), rs.nplayers) + self.assertEqual(rs.wins, self.expected_wins) + + def test_normalised_scores(self): + rs = axelrod.ResultSet(self.players, self.interactions, + progress_bar=False) + self.assertIsInstance(rs.normalised_scores, list) + self.assertEqual(len(rs.normalised_scores), rs.nplayers) + self.assertEqual(rs.normalised_scores, self.expected_normalised_scores) + + def test_payoffs(self): + rs = axelrod.ResultSet(self.players, self.interactions, + progress_bar=False) + self.assertIsInstance(rs.payoffs, list) + self.assertEqual(len(rs.payoffs), rs.nplayers) + self.assertEqual(rs.payoffs, self.expected_payoffs) + + def test_payoff_matrix(self): + rs = axelrod.ResultSet(self.players, self.interactions, + progress_bar=False) + self.assertIsInstance(rs.payoff_matrix, list) + self.assertEqual(len(rs.payoff_matrix), rs.nplayers) + self.assertEqual(rs.payoff_matrix, self.expected_payoff_matrix) + + def test_score_diffs(self): + rs = axelrod.ResultSet(self.players, self.interactions, + progress_bar=False) + self.assertIsInstance(rs.score_diffs, list) + self.assertEqual(len(rs.score_diffs), rs.nplayers) + for i, row in enumerate(rs.score_diffs): + for j, col in enumerate(row): + for k, score in enumerate(col): + self.assertAlmostEqual(score, + self.expected_score_diffs[i][j][k]) + + def test_payoff_diffs_means(self): + rs = axelrod.ResultSet(self.players, self.interactions, + progress_bar=False) + self.assertIsInstance(rs.payoff_diffs_means, list) + self.assertEqual(len(rs.payoff_diffs_means), rs.nplayers) + for i, row in enumerate(rs.payoff_diffs_means): + for j, col in enumerate(row): + self.assertAlmostEqual(col, + self.expected_payoff_diffs_means[i][j]) + + def test_payoff_stddevs(self): + rs = axelrod.ResultSet(self.players, self.interactions, + progress_bar=False) + self.assertIsInstance(rs.payoff_stddevs, list) + self.assertEqual(len(rs.payoff_stddevs), rs.nplayers) + self.assertEqual(rs.payoff_stddevs, self.expected_payoff_stddevs) + + def test_cooperation(self): + rs = axelrod.ResultSet(self.players, self.interactions, + progress_bar=False) + self.assertIsInstance(rs.cooperation, list) + self.assertEqual(len(rs.cooperation), rs.nplayers) + self.assertEqual(rs.cooperation, self.expected_cooperation) + + def test_normalised_cooperation(self): + rs = axelrod.ResultSet(self.players, self.interactions, + progress_bar=False) + self.assertIsInstance(rs.normalised_cooperation, list) + self.assertEqual(len(rs.normalised_cooperation), rs.nplayers) + self.assertEqual(rs.normalised_cooperation, + self.expected_normalised_cooperation) + + def test_vengeful_cooperation(self): + rs = axelrod.ResultSet(self.players, self.interactions, + progress_bar=False) + self.assertIsInstance(rs.vengeful_cooperation, list) + self.assertEqual(len(rs.vengeful_cooperation), rs.nplayers) + self.assertEqual(rs.vengeful_cooperation, + self.expected_vengeful_cooperation) + + def test_cooperating_rating(self): + rs = axelrod.ResultSet(self.players, self.interactions, + progress_bar=False) + self.assertIsInstance(rs.cooperating_rating, list) + self.assertEqual(len(rs.cooperating_rating), rs.nplayers) + self.assertEqual(rs.cooperating_rating, + self.expected_cooperating_rating) + def test_good_partner_matrix(self): + rs = axelrod.ResultSet(self.players, self.interactions, + progress_bar=False) + self.assertIsInstance(rs.good_partner_matrix, list) + self.assertEqual(len(rs.good_partner_matrix), rs.nplayers) + self.assertEqual(rs.good_partner_matrix, + self.expected_good_partner_matrix) + + def test_good_partner_rating(self): + rs = axelrod.ResultSet(self.players, self.interactions, + progress_bar=False) + self.assertIsInstance(rs.good_partner_rating, list) + self.assertEqual(len(rs.good_partner_rating), rs.nplayers) + self.assertEqual(rs.good_partner_rating, + self.expected_good_partner_rating) + + def test_eigenjesus_rating(self): + rs = axelrod.ResultSet(self.players, self.interactions, + progress_bar=False) + self.assertIsInstance(rs.eigenjesus_rating, list) + self.assertEqual(len(rs.eigenjesus_rating), rs.nplayers) + for j, rate in enumerate(rs.eigenjesus_rating): + self.assertAlmostEqual(rate, self.expected_eigenjesus_rating[j]) + + def test_eigenmoses_rating(self): + rs = axelrod.ResultSet(self.players, self.interactions, + progress_bar=False) + self.assertIsInstance(rs.eigenmoses_rating, list) + self.assertEqual(len(rs.eigenmoses_rating), rs.nplayers) + for j, rate in enumerate(rs.eigenmoses_rating): + self.assertAlmostEqual(rate, self.expected_eigenmoses_rating[j]) + + """ + def test_csv(self): + rs = axelrod.ResultSet(self.players, self.interactions, + progress_bar=False) + self.assertEqual(rs.csv(), self.expected_csv) + """ diff --git a/axelrod/tests/unit/test_spatial_three.py b/axelrod/tests/unit/test_spatial_three.py new file mode 100644 index 000000000..0d9a2b367 --- /dev/null +++ b/axelrod/tests/unit/test_spatial_three.py @@ -0,0 +1,366 @@ +import unittest +import axelrod + +from numpy import mean, std, float64 + +import tempfile + +from hypothesis import given +from hypothesis.strategies import floats, integers + +class TestResultSet_SpatialStructure(unittest.TestCase): + + @classmethod + def setUpClass(cls): + + cls.players = (axelrod.Alternator(), axelrod.TitForTat(), + axelrod.Defector(), axelrod.Cooperator()) + cls.turns = 5 + cls.edges = [(0, 0), (1, 1), (2, 2), (3, 3)] + cls.matches = {(i, i): [axelrod.Match((cls.players[i], + cls.players[i].clone()), + turns=cls.turns) + for _ in range(3)] for i in range(4)} + + + cls.interactions = {} + for index_pair, matches in cls.matches.items(): + for match in matches: + match.play() + + try: + cls.interactions[index_pair].append(match.result) + except KeyError: + cls.interactions[index_pair] = [match.result] + + cls.expected_players_to_match_dicts = {0: cls.matches[(0, 0)] , + 1: cls.matches[(1, 1)] , + 2: cls.matches[(2, 2)], + 3: cls.matches[(3, 3)]} + + cls.expected_match_lengths =[ + [[5, 0, 0, 0], [0, 5, 0, 0], [0, 0, 5, 0], [0, 0, 0, 5]] + for _ in range(3) + ] + + cls.expected_scores =[ + [0, 0, 0], + [0, 0, 0], + [0, 0, 0], + [0, 0, 0], + ] + + cls.expected_wins =[ + [0, 0, 0], + [0, 0, 0], + [0, 0, 0], + [0, 0, 0] + ] + + cls.expected_normalised_scores =[ + ["nan" for _ in range(3)] for i in range(4) + ] + + cls.expected_ranking = [0, 1, 2, 3] + + cls.expected_ranked_names = ['Alternator','Tit For Tat','Defector','Cooperator'] + + cls.expected_null_results_matrix = [ + [[0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0]], + [[0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0]], + [[0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0]], + ] + + cls.expected_payoffs = [ + [[11 /5.0 for _ in range(3)], [], [], []], + [[], [15 /5.0 for _ in range(3)], [], []], + [[], [], [5 /5.0 for _ in range(3)], []], + [[], [], [], [15 /5.0 for _ in range(3)]] + ] + + norm_scores = cls.expected_normalised_scores + cls.expected_score_diffs = [ + [[0.0 for _ in range(3)] for _ in range(4) ] for _ in range(4) + ] + + cls.expected_payoff_diffs_means = [ + [0.0, 0.0, 0.0, 0.0], + [0.0, 0.0, 0.0, 0.0], + [0.0, 0.0, 0.0, 0.0], + [0.0, 0.0, 0.0, 0.0] + + ] + + # Recalculating to deal with numeric imprecision + cls.expected_payoff_matrix = [ + [mean([11/5.0 for _ in range(3)]),0, 0, 0], + [0, mean([15/5.0 for _ in range(3)]), 0, 0], + [0, 0, mean([5/5.0 for _ in range(3)]), 0], + [0, 0, 0, mean([15/5.0 for _ in range(3)])] + ] + + cls.expected_payoff_stddevs = [ + [std([11/5.0 for _ in range(3)]),0, 0, 0], + [0, std([15/5.0 for _ in range(3)]), 0, 0], + [0, 0, std([5/5.0 for _ in range(3)]), 0], + [0, 0, 0, std([15/5.0 for _ in range(3)])] + ] + + cls.expected_cooperation = [ + [0, 0, 0, 0], + [0, 0, 0, 0], + [0, 0, 0, 0], + [0, 0, 0, 0] + ] + + cls.expected_normalised_cooperation = [ + [mean([3 / 5.0 for _ in range(3)]), 0.0, 0.0, 0.0], + [0.0, mean([5 / 5.0 for _ in range(3)]), 0.0, 0.0], + [0.0, 0.0, 0.0, 0.0], + [0.0, 0.0, 0.0, mean([5 / 5.0 for _ in range(3)])] + ] + + cls.expected_vengeful_cooperation = [[2 * element - 1 for element in row] + for row in cls.expected_normalised_cooperation] + + cls.expected_cooperating_rating = [ + 0, + 0, + 0, + 0, + ] + + cls.expected_good_partner_matrix = [ + [0, 0, 0, 0], + [0, 0, 0, 0], + [0, 0, 0, 0], + [0, 0, 0, 0] + ] + + cls.expected_good_partner_rating = [ + 0, + 0, + 0, + 0 + ] + + cls.expected_eigenjesus_rating = [ + 0.0009235301367282831, + 0.7071064796379986, + 0.0, + 0.7071064796379986, + ] + + cls.expected_eigenmoses_rating = [ + 0.4765940316018446, + 0.3985944056208427, + 0.6746133178770147, + 0.3985944056208427 + ] + + #cls.expected_csv = ( + # 'Defector,Tit For Tat,Alternator\n2.6,1.7,1.5\n2.6,1.7,1.5\n2.6,1.7,1.5\n') + + def test_init(self): + rs = axelrod.ResultSet(self.players, self.interactions, + progress_bar=False) + self.assertFalse(rs.progress_bar) + self.assertEqual(rs.players, self.players) + self.assertEqual(rs.nplayers, len(self.players)) + self.assertEqual(rs.interactions, self.interactions) + for inter in self.interactions.values(): + self.assertEqual(rs.nrepetitions, len(inter)) + + # Test structure of matches + # This is really a test of the test + for index_pair, repetitions in rs.interactions.items(): + self.assertIsInstance(repetitions, list) + self.assertIsInstance(index_pair, tuple) + for interaction in repetitions: + self.assertIsInstance(interaction, list) + self.assertEqual(len(interaction), self.turns) + + def test_with_progress_bar(self): + rs = axelrod.ResultSet(self.players, self.interactions) + self.assertTrue(rs.progress_bar) + self.assertEqual(rs.progress_bar.total, 19) + + rs = axelrod.ResultSet(self.players, self.interactions, + progress_bar=True) + self.assertTrue(rs.progress_bar) + self.assertEqual(rs.progress_bar.total, 19) + + def test_null_results_matrix(self): + rs = axelrod.ResultSet(self.players, self.interactions, + progress_bar=False) + self.assertEqual( + rs._null_results_matrix, self.expected_null_results_matrix) + + def test_match_lengths(self): + rs = axelrod.ResultSet(self.players, self.interactions, + progress_bar=False) + self.assertIsInstance(rs.match_lengths, list) + self.assertEqual(len(rs.match_lengths), rs.nrepetitions) + self.assertEqual(rs.match_lengths, self.expected_match_lengths) + + for rep in rs.match_lengths: + self.assertIsInstance(rep, list) + self.assertEqual(len(rep), len(self.players)) + + for i, opp in enumerate(rep): + self.assertIsInstance(opp, list) + self.assertEqual(len(opp), len(self.players)) + + for j, length in enumerate(opp): + k = (i, j) + if k in self.edges or k[::-1] in self.edges : # Specific test for example match setup + self.assertEqual(length, self.turns) + else: + self.assertEqual(length, 0) + + def test_scores(self): + rs = axelrod.ResultSet(self.players, self.interactions, + progress_bar=False) + self.assertIsInstance(rs.scores, list) + self.assertEqual(len(rs.scores), rs.nplayers) + self.assertEqual(rs.scores, self.expected_scores) + + def test_ranking(self): + rs = axelrod.ResultSet(self.players, self.interactions, + progress_bar=False) + self.assertIsInstance(rs.ranking, list) + self.assertEqual(len(rs.ranking), rs.nplayers) + self.assertEqual(rs.ranking, self.expected_ranking) + + def test_ranked_names(self): + rs = axelrod.ResultSet(self.players, self.interactions, + progress_bar=False) + self.assertIsInstance(rs.ranked_names, list) + self.assertEqual(len(rs.ranked_names), rs.nplayers) + self.assertEqual(rs.ranked_names, self.expected_ranked_names) + + def test_wins(self): + rs = axelrod.ResultSet(self.players, self.interactions, + progress_bar=False) + self.assertIsInstance(rs.wins, list) + self.assertEqual(len(rs.wins), rs.nplayers) + self.assertEqual(rs.wins, self.expected_wins) + + def test_normalised_scores(self): + rs = axelrod.ResultSet(self.players, self.interactions, + progress_bar=False) + self.assertIsInstance(rs.normalised_scores, list) + self.assertEqual(len(rs.normalised_scores), rs.nplayers) + self.assertEqual([[str(s) for s in player] for player in rs.normalised_scores] + , self.expected_normalised_scores) + + def test_payoffs(self): + rs = axelrod.ResultSet(self.players, self.interactions, + progress_bar=False) + self.assertIsInstance(rs.payoffs, list) + self.assertEqual(len(rs.payoffs), rs.nplayers) + self.assertEqual(rs.payoffs, self.expected_payoffs) + + def test_payoff_matrix(self): + rs = axelrod.ResultSet(self.players, self.interactions, + progress_bar=False) + self.assertIsInstance(rs.payoff_matrix, list) + self.assertEqual(len(rs.payoff_matrix), rs.nplayers) + self.assertEqual(rs.payoff_matrix, self.expected_payoff_matrix) + + def test_score_diffs(self): + rs = axelrod.ResultSet(self.players, self.interactions, + progress_bar=False) + self.assertIsInstance(rs.score_diffs, list) + self.assertEqual(len(rs.score_diffs), rs.nplayers) + for i, row in enumerate(rs.score_diffs): + for j, col in enumerate(row): + for k, score in enumerate(col): + self.assertAlmostEqual(score, + self.expected_score_diffs[i][j][k]) + + def test_payoff_diffs_means(self): + rs = axelrod.ResultSet(self.players, self.interactions, + progress_bar=False) + self.assertIsInstance(rs.payoff_diffs_means, list) + self.assertEqual(len(rs.payoff_diffs_means), rs.nplayers) + for i, row in enumerate(rs.payoff_diffs_means): + for j, col in enumerate(row): + self.assertAlmostEqual(col, + self.expected_payoff_diffs_means[i][j]) + + def test_payoff_stddevs(self): + rs = axelrod.ResultSet(self.players, self.interactions, + progress_bar=False) + self.assertIsInstance(rs.payoff_stddevs, list) + self.assertEqual(len(rs.payoff_stddevs), rs.nplayers) + self.assertEqual(rs.payoff_stddevs, self.expected_payoff_stddevs) + + def test_cooperation(self): + rs = axelrod.ResultSet(self.players, self.interactions, + progress_bar=False) + self.assertIsInstance(rs.cooperation, list) + self.assertEqual(len(rs.cooperation), rs.nplayers) + self.assertEqual(rs.cooperation, self.expected_cooperation) + + def test_normalised_cooperation(self): + rs = axelrod.ResultSet(self.players, self.interactions, + progress_bar=False) + self.assertIsInstance(rs.normalised_cooperation, list) + self.assertEqual(len(rs.normalised_cooperation), rs.nplayers) + self.assertEqual(rs.normalised_cooperation, + self.expected_normalised_cooperation) + + def test_vengeful_cooperation(self): + rs = axelrod.ResultSet(self.players, self.interactions, + progress_bar=False) + self.assertIsInstance(rs.vengeful_cooperation, list) + self.assertEqual(len(rs.vengeful_cooperation), rs.nplayers) + self.assertEqual(rs.vengeful_cooperation, + self.expected_vengeful_cooperation) + + def test_cooperating_rating(self): + rs = axelrod.ResultSet(self.players, self.interactions, + progress_bar=False) + self.assertIsInstance(rs.cooperating_rating, list) + self.assertEqual(len(rs.cooperating_rating), rs.nplayers) + self.assertEqual(rs.cooperating_rating, + self.expected_cooperating_rating) + def test_good_partner_matrix(self): + rs = axelrod.ResultSet(self.players, self.interactions, + progress_bar=False) + self.assertIsInstance(rs.good_partner_matrix, list) + self.assertEqual(len(rs.good_partner_matrix), rs.nplayers) + self.assertEqual(rs.good_partner_matrix, + self.expected_good_partner_matrix) + + def test_good_partner_rating(self): + rs = axelrod.ResultSet(self.players, self.interactions, + progress_bar=False) + self.assertIsInstance(rs.good_partner_rating, list) + self.assertEqual(len(rs.good_partner_rating), rs.nplayers) + self.assertEqual(rs.good_partner_rating, + self.expected_good_partner_rating) + + def test_eigenjesus_rating(self): + rs = axelrod.ResultSet(self.players, self.interactions, + progress_bar=False) + self.assertIsInstance(rs.eigenjesus_rating, list) + self.assertEqual(len(rs.eigenjesus_rating), rs.nplayers) + for j, rate in enumerate(rs.eigenjesus_rating): + self.assertAlmostEqual(rate, self.expected_eigenjesus_rating[j]) + + def test_eigenmoses_rating(self): + rs = axelrod.ResultSet(self.players, self.interactions, + progress_bar=False) + self.assertIsInstance(rs.eigenmoses_rating, list) + self.assertEqual(len(rs.eigenmoses_rating), rs.nplayers) + for j, rate in enumerate(rs.eigenmoses_rating): + self.assertAlmostEqual(rate, self.expected_eigenmoses_rating[j]) + + """ + def test_csv(self): + rs = axelrod.ResultSet(self.players, self.interactions, + progress_bar=False) + self.assertEqual(rs.csv(), self.expected_csv) + """ diff --git a/axelrod/tests/unit/test_spatial_two.py b/axelrod/tests/unit/test_spatial_two.py new file mode 100644 index 000000000..df85cc199 --- /dev/null +++ b/axelrod/tests/unit/test_spatial_two.py @@ -0,0 +1,382 @@ +import unittest +import axelrod + +from numpy import mean, std + +import tempfile + +from hypothesis import given +from hypothesis.strategies import floats, integers + +class TestResultSet_SpatialStructure(unittest.TestCase): + + @classmethod + def setUpClass(cls): + + cls.players = (axelrod.Alternator(), axelrod.TitForTat(), + axelrod.Defector(), axelrod.Cooperator()) + cls.turns = 5 + cls.edges = [(0, 1), (2, 3)] + cls.matches = { (0,1): [axelrod.Match((cls.players[0], cls.players[1]), + turns=cls.turns) for _ in range(3)], + (2,3): [axelrod.Match((cls.players[2], cls.players[3]), + turns=cls.turns) for _ in range(3)]} + + cls.interactions = {} + for index_pair, matches in cls.matches.items(): + for match in matches: + match.play() + try: + cls.interactions[index_pair].append(match.result) + except KeyError: + cls.interactions[index_pair] = [match.result] + + + cls.expected_players_to_match_dicts = {0: cls.matches[(0, 1)] , + 1: cls.matches[(0, 1)] , + 2: cls.matches[(2, 3)], + 3: cls.matches[(2, 3)]} + + cls.expected_match_lengths =[ + [[0, 5, 0, 0], [5, 0, 0, 0], [0, 0, 0, 5], [0, 0, 5, 0]] + for _ in range(3) + ] + + cls.expected_scores =[ + [13, 13, 13], + [13, 13, 13], + [25, 25, 25], + [0, 0, 0] + ] + + cls.expected_wins =[ + [0, 0, 0], + [0, 0, 0], + [1, 1, 1], + [0, 0, 0] + ] + + cls.expected_normalised_scores =[ + [(13.0 / 5 ) for _ in range(3)], + [(13.0 / 5 ) for _ in range(3)], + [(25.0 / 5 ) for _ in range(3)], + [0 for _ in range(3)] + ] + + cls.expected_ranking = [2, 0, 1, 3] + + cls.expected_ranked_names = ['Defector','Alternator','Tit For Tat','Cooperator'] + + cls.expected_null_results_matrix = [ + [[0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0]], + [[0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0]], + [[0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0]], + ] + + cls.expected_payoffs = [ + [[], [13/5.0 for _ in range(3)], [], []], + [[13/5.0 for _ in range(3)], [], [], []], + [[], [], [], [25/5.0 for _ in range(3)]], + [[], [], [0 for _ in range(3)], []] + ] + + norm_scores = cls.expected_normalised_scores + cls.expected_score_diffs = [ + [[0.0, 0.0, 0.0], + [0.0, 0.0, 0.0], + [0.0, 0.0, 0.0], + [0.0, 0.0, 0.0]], + [[0.0, 0.0, 0.0], + [0.0, 0.0, 0.0], + [0.0, 0.0, 0.0], + [0.0, 0.0, 0.0]], + [[0.0, 0.0, 0.0], + [0.0, 0.0, 0.0], + [0.0, 0.0, 0.0], + [5.0, 5.0, 5.0]], + [[0.0, 0.0, 0.0], + [0.0, 0.0, 0.0], + [-5.0, -5.0, -5.0], + [0.0, 0.0, 0.0]] + ] + + cls.expected_payoff_diffs_means = [ + [0.0, 0.0, 0.0, 0.0], + [0.0, 0.0, 0.0, 0.0], + [0.0, 0.0, 0.0, 5.0], + [0.0, 0.0, -5.0, 0.0] + + ] + + # Recalculating to deal with numeric imprecision + cls.expected_payoff_matrix = [ + [0, mean([13/5.0 for _ in range(3)]), 0, 0], + [mean([13/5.0 for _ in range(3)]), 0, 0, 0], + [0, 0, 0, mean([25/5.0 for _ in range(3)])], + [0, 0, 0, 0] + ] + + cls.expected_payoff_stddevs = [ + [0, std([13/5.0 for _ in range(3)]), 0, 0], + [std([13/5.0 for _ in range(3)]), 0, 0, 0], + [0, 0, 0, std([25/5.0 for _ in range(3)])], + [0, 0, 0, 0] + ] + + cls.expected_cooperation = [ + [0, 9, 0, 0], + [9, 0, 0, 0], + [0, 0, 0, 0], + [0, 0, 15, 0] + ] + + cls.expected_normalised_cooperation = [ + [0.0, mean([3 / 5.0 for _ in range(3)]), 0.0, 0.0], + [mean([3 / 5.0 for _ in range(3)]), 0.0, 0.0, 0.0], + [0.0, 0.0, 0.0, 0.0], + [0.0, 0.0, mean([5 / 5.0 for _ in range(3)]), 0.0] + ] + + cls.expected_vengeful_cooperation = [[2 * element - 1 for element in row] + for row in cls.expected_normalised_cooperation] + + cls.expected_cooperating_rating = [ + 18.0 / 30, + 18.0 / 30, + 0, + 30 /30 + ] + + cls.expected_good_partner_matrix = [ + [0, 3, 0, 0], + [3, 0, 0, 0], + [0, 0, 0, 0], + [0, 0, 3, 0] + ] + + cls.expected_good_partner_rating = [ + 1.0, + 1.0, + 0, + 1.0 + ] + + cls.expected_eigenjesus_rating = [ + 0.7071067811865476, + 0.7071067811865476, + 0.0, + 0.0, + ] + + cls.expected_eigenmoses_rating = [ + 0.48505781033492573, + 0.48505781033492573, + 0.7090603855860735, + 0.1633132292825755 + ] + + #cls.expected_csv = ( + # 'Defector,Tit For Tat,Alternator\n2.6,1.7,1.5\n2.6,1.7,1.5\n2.6,1.7,1.5\n') + + def test_init(self): + rs = axelrod.ResultSet(self.players, self.interactions, + progress_bar=False) + self.assertFalse(rs.progress_bar) + self.assertEqual(rs.players, self.players) + self.assertEqual(rs.nplayers, len(self.players)) + self.assertEqual(rs.interactions, self.interactions) + for inter in self.interactions.values(): + self.assertEqual(rs.nrepetitions, len(inter)) + + # Test structure of matches + # This is really a test of the test + for index_pair, repetitions in rs.interactions.items(): + self.assertIsInstance(repetitions, list) + self.assertIsInstance(index_pair, tuple) + for interaction in repetitions: + self.assertIsInstance(interaction, list) + self.assertEqual(len(interaction), self.turns) + + def test_with_progress_bar(self): + rs = axelrod.ResultSet(self.players, self.interactions) + self.assertTrue(rs.progress_bar) + self.assertEqual(rs.progress_bar.total, 19) + + rs = axelrod.ResultSet(self.players, self.interactions, + progress_bar=True) + self.assertTrue(rs.progress_bar) + self.assertEqual(rs.progress_bar.total, 19) + + def test_null_results_matrix(self): + rs = axelrod.ResultSet(self.players, self.interactions, + progress_bar=False) + self.assertEqual( + rs._null_results_matrix, self.expected_null_results_matrix) + + def test_match_lengths(self): + rs = axelrod.ResultSet(self.players, self.interactions, + progress_bar=False) + self.assertIsInstance(rs.match_lengths, list) + self.assertEqual(len(rs.match_lengths), rs.nrepetitions) + self.assertEqual(rs.match_lengths, self.expected_match_lengths) + + for rep in rs.match_lengths: + self.assertIsInstance(rep, list) + self.assertEqual(len(rep), len(self.players)) + + for i, opp in enumerate(rep): + self.assertIsInstance(opp, list) + self.assertEqual(len(opp), len(self.players)) + + for j, length in enumerate(opp): + k = (i, j) + if k in self.edges or k[::-1] in self.edges : # Specific test for example match setup + self.assertEqual(length, self.turns) + else: + self.assertEqual(length, 0) + + def test_scores(self): + rs = axelrod.ResultSet(self.players, self.interactions, + progress_bar=False) + self.assertIsInstance(rs.scores, list) + self.assertEqual(len(rs.scores), rs.nplayers) + self.assertEqual(rs.scores, self.expected_scores) + + def test_ranking(self): + rs = axelrod.ResultSet(self.players, self.interactions, + progress_bar=False) + self.assertIsInstance(rs.ranking, list) + self.assertEqual(len(rs.ranking), rs.nplayers) + self.assertEqual(rs.ranking, self.expected_ranking) + + def test_ranked_names(self): + rs = axelrod.ResultSet(self.players, self.interactions, + progress_bar=False) + self.assertIsInstance(rs.ranked_names, list) + self.assertEqual(len(rs.ranked_names), rs.nplayers) + self.assertEqual(rs.ranked_names, self.expected_ranked_names) + + def test_wins(self): + rs = axelrod.ResultSet(self.players, self.interactions, + progress_bar=False) + self.assertIsInstance(rs.wins, list) + self.assertEqual(len(rs.wins), rs.nplayers) + self.assertEqual(rs.wins, self.expected_wins) + + def test_normalised_scores(self): + rs = axelrod.ResultSet(self.players, self.interactions, + progress_bar=False) + self.assertIsInstance(rs.normalised_scores, list) + self.assertEqual(len(rs.normalised_scores), rs.nplayers) + self.assertEqual(rs.normalised_scores, self.expected_normalised_scores) + + def test_payoffs(self): + rs = axelrod.ResultSet(self.players, self.interactions, + progress_bar=False) + self.assertIsInstance(rs.payoffs, list) + self.assertEqual(len(rs.payoffs), rs.nplayers) + self.assertEqual(rs.payoffs, self.expected_payoffs) + + def test_payoff_matrix(self): + rs = axelrod.ResultSet(self.players, self.interactions, + progress_bar=False) + self.assertIsInstance(rs.payoff_matrix, list) + self.assertEqual(len(rs.payoff_matrix), rs.nplayers) + self.assertEqual(rs.payoff_matrix, self.expected_payoff_matrix) + + def test_score_diffs(self): + rs = axelrod.ResultSet(self.players, self.interactions, + progress_bar=False) + self.assertIsInstance(rs.score_diffs, list) + self.assertEqual(len(rs.score_diffs), rs.nplayers) + for i, row in enumerate(rs.score_diffs): + for j, col in enumerate(row): + for k, score in enumerate(col): + self.assertAlmostEqual(score, + self.expected_score_diffs[i][j][k]) + + def test_payoff_diffs_means(self): + rs = axelrod.ResultSet(self.players, self.interactions, + progress_bar=False) + self.assertIsInstance(rs.payoff_diffs_means, list) + self.assertEqual(len(rs.payoff_diffs_means), rs.nplayers) + for i, row in enumerate(rs.payoff_diffs_means): + for j, col in enumerate(row): + self.assertAlmostEqual(col, + self.expected_payoff_diffs_means[i][j]) + + def test_payoff_stddevs(self): + rs = axelrod.ResultSet(self.players, self.interactions, + progress_bar=False) + self.assertIsInstance(rs.payoff_stddevs, list) + self.assertEqual(len(rs.payoff_stddevs), rs.nplayers) + self.assertEqual(rs.payoff_stddevs, self.expected_payoff_stddevs) + + def test_cooperation(self): + rs = axelrod.ResultSet(self.players, self.interactions, + progress_bar=False) + self.assertIsInstance(rs.cooperation, list) + self.assertEqual(len(rs.cooperation), rs.nplayers) + self.assertEqual(rs.cooperation, self.expected_cooperation) + + def test_normalised_cooperation(self): + rs = axelrod.ResultSet(self.players, self.interactions, + progress_bar=False) + self.assertIsInstance(rs.normalised_cooperation, list) + self.assertEqual(len(rs.normalised_cooperation), rs.nplayers) + self.assertEqual(rs.normalised_cooperation, + self.expected_normalised_cooperation) + + def test_vengeful_cooperation(self): + rs = axelrod.ResultSet(self.players, self.interactions, + progress_bar=False) + self.assertIsInstance(rs.vengeful_cooperation, list) + self.assertEqual(len(rs.vengeful_cooperation), rs.nplayers) + self.assertEqual(rs.vengeful_cooperation, + self.expected_vengeful_cooperation) + + def test_cooperating_rating(self): + rs = axelrod.ResultSet(self.players, self.interactions, + progress_bar=False) + self.assertIsInstance(rs.cooperating_rating, list) + self.assertEqual(len(rs.cooperating_rating), rs.nplayers) + self.assertEqual(rs.cooperating_rating, + self.expected_cooperating_rating) + def test_good_partner_matrix(self): + rs = axelrod.ResultSet(self.players, self.interactions, + progress_bar=False) + self.assertIsInstance(rs.good_partner_matrix, list) + self.assertEqual(len(rs.good_partner_matrix), rs.nplayers) + self.assertEqual(rs.good_partner_matrix, + self.expected_good_partner_matrix) + + def test_good_partner_rating(self): + rs = axelrod.ResultSet(self.players, self.interactions, + progress_bar=False) + self.assertIsInstance(rs.good_partner_rating, list) + self.assertEqual(len(rs.good_partner_rating), rs.nplayers) + self.assertEqual(rs.good_partner_rating, + self.expected_good_partner_rating) + + def test_eigenjesus_rating(self): + rs = axelrod.ResultSet(self.players, self.interactions, + progress_bar=False) + self.assertIsInstance(rs.eigenjesus_rating, list) + self.assertEqual(len(rs.eigenjesus_rating), rs.nplayers) + for j, rate in enumerate(rs.eigenjesus_rating): + self.assertAlmostEqual(rate, self.expected_eigenjesus_rating[j]) + + def test_eigenmoses_rating(self): + rs = axelrod.ResultSet(self.players, self.interactions, + progress_bar=False) + self.assertIsInstance(rs.eigenmoses_rating, list) + self.assertEqual(len(rs.eigenmoses_rating), rs.nplayers) + for j, rate in enumerate(rs.eigenmoses_rating): + self.assertAlmostEqual(rate, self.expected_eigenmoses_rating[j]) + + """ + def test_csv(self): + rs = axelrod.ResultSet(self.players, self.interactions, + progress_bar=False) + self.assertEqual(rs.csv(), self.expected_csv) + """ From 27dc71eeac91d817478893f785a65fd57d2e92ec Mon Sep 17 00:00:00 2001 From: Nikoleta Glynatsi Date: Tue, 28 Jun 2016 10:58:49 +0100 Subject: [PATCH 11/25] Adding test property based test for spatial. Currently the underlying graph is cyclic it needs to be random. --- axelrod/tests/property.py | 49 +++++++++++++++++++++++++++++ axelrod/tests/unit/test_property.py | 41 +++++++++++++++++++++++- 2 files changed, 89 insertions(+), 1 deletion(-) diff --git a/axelrod/tests/property.py b/axelrod/tests/property.py index 113cd5cf6..a4cfa9931 100644 --- a/axelrod/tests/property.py +++ b/axelrod/tests/property.py @@ -144,6 +144,55 @@ def prob_end_tournaments(draw, strategies=axelrod.strategies, return tournament +@composite +def spatial_tournaments(draw, strategies=axelrod.strategies, + min_size=2, max_size=10, + min_turns=1, max_turns=200, + min_noise=0, max_noise=1, + min_repetitions=1, max_repetitions=20): + """ + A hypothesis decorator to return a tournament and a random seed (to ensure + reproducibility for strategies that make use of the random module when + initiating). + + Parameters + ---------- + min_size : integer + The minimum number of strategies to include + max_size : integer + The maximum number of strategies to include + min_noise : float + The minimum noise value + min_noise : float + The maximum noise value + min_repetitions : integer + The minimum number of repetitions + max_repetitions : integer + The maximum number of repetitions + edges : list + The edges to include + """ + strategies = draw(strategy_lists(strategies=strategies, + min_size=min_size, + max_size=max_size)) + players = [s() for s in strategies] + turns = draw(integers(min_value=min_turns, max_value=max_turns)) + + edges= [] + for i in range (0, len(players)-1): + temp=(i, i+1) + edges.append(temp) + print(players) + print(edges) + + repetitions = draw(integers(min_value=min_repetitions, + max_value=max_repetitions)) + noise = draw(floats(min_value=min_noise, max_value=max_noise)) + + tournament = axelrod.SpatialTournament(players, edges=edges, turns=turns, + repetitions=repetitions, noise=noise) + return tournament + @composite def games(draw, prisoners_dilemma=True, max_value=100): """ diff --git a/axelrod/tests/unit/test_property.py b/axelrod/tests/unit/test_property.py index 1b1af4ddc..589ac7b22 100644 --- a/axelrod/tests/unit/test_property.py +++ b/axelrod/tests/unit/test_property.py @@ -3,7 +3,9 @@ import axelrod from axelrod.tests.property import (strategy_lists, matches, tournaments, - prob_end_tournaments, games) + prob_end_tournaments, + spatial_tournaments, + games) from hypothesis import given, settings @@ -159,6 +161,43 @@ def test_decorator_with_stochastic_strategies(self, tournament): for p in tournament.players: self.assertIn(str(p), stochastic_player_names) +class TestSpatialTournament(unittest.TestCase): + + def test_call(self): + tournament = tournaments().example() + self.assertIsInstance(tournament, axelrod.Tournament) + + @given(tournament=spatial_tournaments(min_turns=2, max_turns=50, min_noise=0, + max_noise=1, min_repetitions=2, + max_repetitions=50, + max_size=3)) + + @settings(max_examples=10, timeout=0) + def test_decorator(self, tournament): + self.assertIsInstance(tournament, axelrod.Tournament) + self.assertLessEqual(tournament.turns, 50) + self.assertGreaterEqual(tournament.turns, 2) + self.assertLessEqual(tournament.noise, 1) + self.assertGreaterEqual(tournament.noise, 0) + self.assertLessEqual(tournament.repetitions, 50) + self.assertGreaterEqual(tournament.repetitions, 2) + + @given(tournament=spatial_tournaments(strategies=axelrod.basic_strategies)) + @settings(max_examples=10, timeout=0) + def test_decorator_with_given_strategies(self, tournament): + self.assertIsInstance(tournament, axelrod.SpatialTournament) + basic_player_names = [str(s()) for s in axelrod.basic_strategies] + for p in tournament.players: + self.assertIn(str(p), basic_player_names) + + @given(tournament=spatial_tournaments(strategies=stochastic_strategies)) + @settings(max_examples=10, timeout=0) + def test_decorator_with_stochastic_strategies(self, tournament): + self.assertIsInstance(tournament, axelrod.SpatialTournament) + stochastic_player_names = [str(s()) for s in stochastic_strategies] + for p in tournament.players: + self.assertIn(str(p), stochastic_player_names) + class TestGame(unittest.TestCase): def test_call(self): From 6526c3bb3e4ad518f789b046cace4f702b6c0b6c Mon Sep 17 00:00:00 2001 From: Nikoleta Glynatsi Date: Tue, 28 Jun 2016 11:24:13 +0100 Subject: [PATCH 12/25] Refactored tests. --- axelrod/tests/unit/test_resultset.py | 512 +++++++++++++++++++++++ axelrod/tests/unit/test_spatial_one.py | 360 ---------------- axelrod/tests/unit/test_spatial_three.py | 366 ---------------- axelrod/tests/unit/test_spatial_two.py | 382 ----------------- 4 files changed, 512 insertions(+), 1108 deletions(-) delete mode 100644 axelrod/tests/unit/test_spatial_one.py delete mode 100644 axelrod/tests/unit/test_spatial_three.py delete mode 100644 axelrod/tests/unit/test_spatial_two.py diff --git a/axelrod/tests/unit/test_resultset.py b/axelrod/tests/unit/test_resultset.py index bdd8a2e90..b9148db76 100644 --- a/axelrod/tests/unit/test_resultset.py +++ b/axelrod/tests/unit/test_resultset.py @@ -395,3 +395,515 @@ class TestDecorator(unittest.TestCase): def test_update_progress_bar(self): method = lambda x: None self.assertEqual(axelrod.result_set.update_progress_bar(method)(1), None) + + +class TestResultSet_SpatialStructure(TestResultSet): + """ + Specific test for some spatial tournament. + """ + + @classmethod + def setUpClass(cls): + + cls.players = (axelrod.Alternator(), axelrod.TitForTat(), axelrod.Defector()) + cls.turns = 5 + cls.edges = [(0, 1), (0, 2)] + cls.matches = { (0,1): [axelrod.Match((cls.players[0], cls.players[1]), + turns=cls.turns) for _ in range(3)], + (0,2): [axelrod.Match((cls.players[0], cls.players[2]), + turns=cls.turns) for _ in range(3)]} + + cls.interactions = {} + for index_pair, matches in cls.matches.items(): + for match in matches: + match.play() + try: + cls.interactions[index_pair].append(match.result) + except KeyError: + cls.interactions[index_pair] = [match.result] + + + cls.expected_players_to_match_dicts = {0: cls.matches[(0, 1)] + cls.matches[(0, 2)], + 1: cls.matches[(0, 1)] , + 2: cls.matches[(0, 2)]} + + + + cls.expected_match_lengths =[ + [[0, 5, 5], [5, 0, 0], [5, 0, 0]] + for _ in range(3) + ] + + cls.expected_scores =[ + [15, 15, 15], + [13, 13, 13], + [17, 17, 17] + ] + + cls.expected_wins =[ + [0, 0, 0], + [0, 0, 0], + [1, 1, 1] + ] + + cls.expected_normalised_scores =[ + [3.0 / 2 for _ in range(3)], + [(13.0 / 5 ) for _ in range(3)], + [(17.0 / 5 ) for _ in range(3)], + ] + + cls.expected_ranking = [2, 1, 0] + + cls.expected_ranked_names = ['Defector', 'Tit For Tat', 'Alternator'] + + cls.expected_null_results_matrix = [ + [[0, 0, 0], [0, 0, 0], [0, 0, 0]], + [[0, 0, 0], [0, 0, 0], [0, 0, 0]], + [[0, 0, 0], [0, 0, 0], [0, 0, 0]], + ] + + cls.expected_payoffs = [ + [[], [13/5.0 for _ in range(3)], [2/5.0 for _ in range(3)]], + [[13/5.0 for _ in range(3)], [], []], + [[17/5.0 for _ in range(3)], [], []] + ] + + norm_scores = cls.expected_normalised_scores + cls.expected_score_diffs = [ + [[0.0, 0.0, 0.0], + [0.0, 0.0, 0.0], + [-3.0, -3.0, -3.0]], + [[0.0, 0.0, 0.0], + [0.0, 0.0, 0.0], + [0.0, 0.0, 0.0]], + [[3.0, 3.0, 3.0], + [0.0, 0.0, 0.0], + [0.0, 0.0, 0.0]], + ] + + cls.expected_payoff_diffs_means = [ + [0.0, 0.0, -3.0], + [0.0, 0.0, 0.0], + [3.0, 0.0, 0.0] + ] + + # Recalculating to deal with numeric imprecision + cls.expected_payoff_matrix = [ + [0, mean([13/5.0 for _ in range(3)]), mean([2/5.0 for _ in range(3)])], + [mean([13/5.0 for _ in range(3)]), 0, 0 ], + [mean([17/5.0 for _ in range(3)]), 0 , 0] + ] + + cls.expected_payoff_stddevs = [ + [0, std([13/5.0 for _ in range(3)]), std([2/5.0 for _ in range(3)])], + [std([13/5.0 for _ in range(3)]), 0, 0 ], + [std([17/5.0 for _ in range(3)]), 0, 0 ] + ] + + cls.expected_cooperation = [ + [0, 9, 9], + [9, 0, 0], + [0, 0, 0], + ] + + cls.expected_normalised_cooperation = [ + [0, mean([3 / 5.0 for _ in range(3)]), mean([3 / 5.0 for _ in range(3)])], + [mean([3 / 5.0 for _ in range(3)]), 0, 0 ], + [0, 0, 0], + ] + + cls.expected_vengeful_cooperation = [[2 * element - 1 for element in row] + for row in cls.expected_normalised_cooperation] + + cls.expected_cooperating_rating = [ + 18.0 / 30, + 9.0 / 15, + 0 + ] + + cls.expected_good_partner_matrix = [ + [0, 3, 3], + [3, 0, 0], + [0, 0, 0] + ] + + cls.expected_good_partner_rating = [ + 1.0, + 1.0, + 0 + ] + + cls.expected_eigenjesus_rating = [ + 0.447213595499958, + 0.894427190999916, + 0.0 + ] + + cls.expected_eigenmoses_rating = [ + -0.32929277996907086, + 0.7683498199278325, + 0.5488212999484519 + ] + + cls.expected_csv = ( + 'Defector,Tit For Tat,Alternator\n3.4,2.6,1.5\n3.4,2.6,1.5\n3.4,2.6,1.5\n') + + + def test_match_lengths(self): + """ + Overwriting match_lenghts because of edges + """ + rs = axelrod.ResultSet(self.players, self.interactions, + progress_bar=False) + self.assertIsInstance(rs.match_lengths, list) + self.assertEqual(len(rs.match_lengths), rs.nrepetitions) + self.assertEqual(rs.match_lengths, self.expected_match_lengths) + + for rep in rs.match_lengths: + self.assertIsInstance(rep, list) + self.assertEqual(len(rep), len(self.players)) + + for i, opp in enumerate(rep): + self.assertIsInstance(opp, list) + self.assertEqual(len(opp), len(self.players)) + + for j, length in enumerate(opp): + edge = (i, j) + if edge in self.edges or edge[::-1] in self.edges : # Specific test for example match setup + self.assertEqual(length, self.turns) + else: + self.assertEqual(length, 0) + +class TestResultSet_SpatialStructure_Two(TestResultSet_SpatialStructure): + + @classmethod + def setUpClass(cls): + + cls.players = (axelrod.Alternator(), axelrod.TitForTat(), + axelrod.Defector(), axelrod.Cooperator()) + cls.turns = 5 + cls.edges = [(0, 1), (2, 3)] + cls.matches = { (0,1): [axelrod.Match((cls.players[0], cls.players[1]), + turns=cls.turns) for _ in range(3)], + (2,3): [axelrod.Match((cls.players[2], cls.players[3]), + turns=cls.turns) for _ in range(3)]} + + cls.interactions = {} + for index_pair, matches in cls.matches.items(): + for match in matches: + match.play() + try: + cls.interactions[index_pair].append(match.result) + except KeyError: + cls.interactions[index_pair] = [match.result] + + + cls.expected_players_to_match_dicts = {0: cls.matches[(0, 1)] , + 1: cls.matches[(0, 1)] , + 2: cls.matches[(2, 3)], + 3: cls.matches[(2, 3)]} + + cls.expected_match_lengths =[ + [[0, 5, 0, 0], [5, 0, 0, 0], [0, 0, 0, 5], [0, 0, 5, 0]] + for _ in range(3) + ] + + cls.expected_scores =[ + [13, 13, 13], + [13, 13, 13], + [25, 25, 25], + [0, 0, 0] + ] + + cls.expected_wins =[ + [0, 0, 0], + [0, 0, 0], + [1, 1, 1], + [0, 0, 0] + ] + + cls.expected_normalised_scores =[ + [(13.0 / 5 ) for _ in range(3)], + [(13.0 / 5 ) for _ in range(3)], + [(25.0 / 5 ) for _ in range(3)], + [0 for _ in range(3)] + ] + + cls.expected_ranking = [2, 0, 1, 3] + + cls.expected_ranked_names = ['Defector','Alternator','Tit For Tat','Cooperator'] + + cls.expected_null_results_matrix = [ + [[0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0]], + [[0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0]], + [[0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0]], + ] + + cls.expected_payoffs = [ + [[], [13/5.0 for _ in range(3)], [], []], + [[13/5.0 for _ in range(3)], [], [], []], + [[], [], [], [25/5.0 for _ in range(3)]], + [[], [], [0 for _ in range(3)], []] + ] + + norm_scores = cls.expected_normalised_scores + cls.expected_score_diffs = [ + [[0.0, 0.0, 0.0], + [0.0, 0.0, 0.0], + [0.0, 0.0, 0.0], + [0.0, 0.0, 0.0]], + [[0.0, 0.0, 0.0], + [0.0, 0.0, 0.0], + [0.0, 0.0, 0.0], + [0.0, 0.0, 0.0]], + [[0.0, 0.0, 0.0], + [0.0, 0.0, 0.0], + [0.0, 0.0, 0.0], + [5.0, 5.0, 5.0]], + [[0.0, 0.0, 0.0], + [0.0, 0.0, 0.0], + [-5.0, -5.0, -5.0], + [0.0, 0.0, 0.0]] + ] + + cls.expected_payoff_diffs_means = [ + [0.0, 0.0, 0.0, 0.0], + [0.0, 0.0, 0.0, 0.0], + [0.0, 0.0, 0.0, 5.0], + [0.0, 0.0, -5.0, 0.0] + + ] + + # Recalculating to deal with numeric imprecision + cls.expected_payoff_matrix = [ + [0, mean([13/5.0 for _ in range(3)]), 0, 0], + [mean([13/5.0 for _ in range(3)]), 0, 0, 0], + [0, 0, 0, mean([25/5.0 for _ in range(3)])], + [0, 0, 0, 0] + ] + + cls.expected_payoff_stddevs = [ + [0, std([13/5.0 for _ in range(3)]), 0, 0], + [std([13/5.0 for _ in range(3)]), 0, 0, 0], + [0, 0, 0, std([25/5.0 for _ in range(3)])], + [0, 0, 0, 0] + ] + + cls.expected_cooperation = [ + [0, 9, 0, 0], + [9, 0, 0, 0], + [0, 0, 0, 0], + [0, 0, 15, 0] + ] + + cls.expected_normalised_cooperation = [ + [0.0, mean([3 / 5.0 for _ in range(3)]), 0.0, 0.0], + [mean([3 / 5.0 for _ in range(3)]), 0.0, 0.0, 0.0], + [0.0, 0.0, 0.0, 0.0], + [0.0, 0.0, mean([5 / 5.0 for _ in range(3)]), 0.0] + ] + + cls.expected_vengeful_cooperation = [[2 * element - 1 for element in row] + for row in cls.expected_normalised_cooperation] + + cls.expected_cooperating_rating = [ + 18.0 / 30, + 18.0 / 30, + 0, + 30 /30 + ] + + cls.expected_good_partner_matrix = [ + [0, 3, 0, 0], + [3, 0, 0, 0], + [0, 0, 0, 0], + [0, 0, 3, 0] + ] + + cls.expected_good_partner_rating = [ + 1.0, + 1.0, + 0, + 1.0 + ] + + cls.expected_eigenjesus_rating = [ + 0.7071067811865476, + 0.7071067811865476, + 0.0, + 0.0, + ] + + cls.expected_eigenmoses_rating = [ + 0.48505781033492573, + 0.48505781033492573, + 0.7090603855860735, + 0.1633132292825755 + ] + + cls.expected_csv = ( + 'Defector,Alternator,Tit For Tat,Cooperator\n5.0,2.6,2.6,0.0\n5.0,2.6,2.6,0.0\n5.0,2.6,2.6,0.0\n') + +class TestResultSet_SpatialStructure_Three(TestResultSet_SpatialStructure): + + @classmethod + def setUpClass(cls): + + cls.players = (axelrod.Alternator(), axelrod.TitForTat(), + axelrod.Defector(), axelrod.Cooperator()) + cls.turns = 5 + cls.edges = [(0, 0), (1, 1), (2, 2), (3, 3)] + cls.matches = {(i, i): [axelrod.Match((cls.players[i], + cls.players[i].clone()), + turns=cls.turns) + for _ in range(3)] for i in range(4)} + + + cls.interactions = {} + for index_pair, matches in cls.matches.items(): + for match in matches: + match.play() + + try: + cls.interactions[index_pair].append(match.result) + except KeyError: + cls.interactions[index_pair] = [match.result] + + cls.expected_players_to_match_dicts = {0: cls.matches[(0, 0)] , + 1: cls.matches[(1, 1)] , + 2: cls.matches[(2, 2)], + 3: cls.matches[(3, 3)]} + + cls.expected_match_lengths =[ + [[5, 0, 0, 0], [0, 5, 0, 0], [0, 0, 5, 0], [0, 0, 0, 5]] + for _ in range(3) + ] + + cls.expected_scores =[ + [0, 0, 0], + [0, 0, 0], + [0, 0, 0], + [0, 0, 0], + ] + + cls.expected_wins =[ + [0, 0, 0], + [0, 0, 0], + [0, 0, 0], + [0, 0, 0] + ] + + cls.expected_normalised_scores =[ + ["nan" for _ in range(3)] for i in range(4) + ] + + cls.expected_ranking = [0, 1, 2, 3] + + cls.expected_ranked_names = ['Alternator','Tit For Tat','Defector','Cooperator'] + + cls.expected_null_results_matrix = [ + [[0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0]], + [[0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0]], + [[0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0]], + ] + + cls.expected_payoffs = [ + [[11 /5.0 for _ in range(3)], [], [], []], + [[], [15 /5.0 for _ in range(3)], [], []], + [[], [], [5 /5.0 for _ in range(3)], []], + [[], [], [], [15 /5.0 for _ in range(3)]] + ] + + norm_scores = cls.expected_normalised_scores + cls.expected_score_diffs = [ + [[0.0 for _ in range(3)] for _ in range(4) ] for _ in range(4) + ] + + cls.expected_payoff_diffs_means = [ + [0.0, 0.0, 0.0, 0.0], + [0.0, 0.0, 0.0, 0.0], + [0.0, 0.0, 0.0, 0.0], + [0.0, 0.0, 0.0, 0.0] + + ] + + # Recalculating to deal with numeric imprecision + cls.expected_payoff_matrix = [ + [mean([11/5.0 for _ in range(3)]),0, 0, 0], + [0, mean([15/5.0 for _ in range(3)]), 0, 0], + [0, 0, mean([5/5.0 for _ in range(3)]), 0], + [0, 0, 0, mean([15/5.0 for _ in range(3)])] + ] + + cls.expected_payoff_stddevs = [ + [std([11/5.0 for _ in range(3)]),0, 0, 0], + [0, std([15/5.0 for _ in range(3)]), 0, 0], + [0, 0, std([5/5.0 for _ in range(3)]), 0], + [0, 0, 0, std([15/5.0 for _ in range(3)])] + ] + + cls.expected_cooperation = [ + [0, 0, 0, 0], + [0, 0, 0, 0], + [0, 0, 0, 0], + [0, 0, 0, 0] + ] + + cls.expected_normalised_cooperation = [ + [mean([3 / 5.0 for _ in range(3)]), 0.0, 0.0, 0.0], + [0.0, mean([5 / 5.0 for _ in range(3)]), 0.0, 0.0], + [0.0, 0.0, 0.0, 0.0], + [0.0, 0.0, 0.0, mean([5 / 5.0 for _ in range(3)])] + ] + + cls.expected_vengeful_cooperation = [[2 * element - 1 for element in row] + for row in cls.expected_normalised_cooperation] + + cls.expected_cooperating_rating = [ + 0, + 0, + 0, + 0, + ] + + cls.expected_good_partner_matrix = [ + [0, 0, 0, 0], + [0, 0, 0, 0], + [0, 0, 0, 0], + [0, 0, 0, 0] + ] + + cls.expected_good_partner_rating = [ + 0, + 0, + 0, + 0 + ] + + cls.expected_eigenjesus_rating = [ + 0.0009235301367282831, + 0.7071064796379986, + 0.0, + 0.7071064796379986, + ] + + cls.expected_eigenmoses_rating = [ + 0.4765940316018446, + 0.3985944056208427, + 0.6746133178770147, + 0.3985944056208427 + ] + + cls.expected_csv = ( + 'Alternator,Tit For Tat,Defector,Cooperator\nnan,nan,nan,nan\nnan,nan,nan,nan\nnan,nan,nan,nan\n') + + def test_normalised_scores(self): + """ + Need to test string representation because of nan + """ + rs = axelrod.ResultSet(self.players, self.interactions, + progress_bar=False) + self.assertIsInstance(rs.normalised_scores, list) + self.assertEqual(len(rs.normalised_scores), rs.nplayers) + self.assertEqual([[str(s) for s in player] for player in rs.normalised_scores] + , self.expected_normalised_scores) diff --git a/axelrod/tests/unit/test_spatial_one.py b/axelrod/tests/unit/test_spatial_one.py deleted file mode 100644 index 4f452c11d..000000000 --- a/axelrod/tests/unit/test_spatial_one.py +++ /dev/null @@ -1,360 +0,0 @@ -import unittest -import axelrod - -from numpy import mean, std - -import tempfile - -from hypothesis import given -from hypothesis.strategies import floats, integers - -class TestResultSet_SpatialStructure(unittest.TestCase): - - @classmethod - def setUpClass(cls): - - cls.players = (axelrod.Alternator(), axelrod.TitForTat(), axelrod.Defector()) - cls.turns = 5 - cls.edges = [(0, 1), (0, 2)] - cls.matches = { (0,1): [axelrod.Match((cls.players[0], cls.players[1]), - turns=cls.turns) for _ in range(3)], - (0,2): [axelrod.Match((cls.players[0], cls.players[2]), - turns=cls.turns) for _ in range(3)]} - - cls.interactions = {} - for index_pair, matches in cls.matches.items(): - for match in matches: - match.play() - try: - cls.interactions[index_pair].append(match.result) - except KeyError: - cls.interactions[index_pair] = [match.result] - - - cls.expected_players_to_match_dicts = {0: cls.matches[(0, 1)] + cls.matches[(0, 2)], - 1: cls.matches[(0, 1)] , - 2: cls.matches[(0, 2)]} - - - - cls.expected_match_lengths =[ - [[0, 5, 5], [5, 0, 0], [5, 0, 0]] - for _ in range(3) - ] - - cls.expected_scores =[ - [15, 15, 15], - [13, 13, 13], - [17, 17, 17] - ] - - cls.expected_wins =[ - [0, 0, 0], - [0, 0, 0], - [1, 1, 1] - ] - - cls.expected_normalised_scores =[ - [3.0 / 2 for _ in range(3)], - [(13.0 / 5 ) for _ in range(3)], - [(17.0 / 5 ) for _ in range(3)], - ] - - cls.expected_ranking = [2, 1, 0] - - cls.expected_ranked_names = ['Defector', 'Tit For Tat', 'Alternator'] - - cls.expected_null_results_matrix = [ - [[0, 0, 0], [0, 0, 0], [0, 0, 0]], - [[0, 0, 0], [0, 0, 0], [0, 0, 0]], - [[0, 0, 0], [0, 0, 0], [0, 0, 0]], - ] - - cls.expected_payoffs = [ - [[], [13/5.0 for _ in range(3)], [2/5.0 for _ in range(3)]], - [[13/5.0 for _ in range(3)], [], []], - [[17/5.0 for _ in range(3)], [], []] - ] - - norm_scores = cls.expected_normalised_scores - cls.expected_score_diffs = [ - [[0.0, 0.0, 0.0], - [0.0, 0.0, 0.0], - [-3.0, -3.0, -3.0]], - [[0.0, 0.0, 0.0], - [0.0, 0.0, 0.0], - [0.0, 0.0, 0.0]], - [[3.0, 3.0, 3.0], - [0.0, 0.0, 0.0], - [0.0, 0.0, 0.0]], - ] - - cls.expected_payoff_diffs_means = [ - [0.0, 0.0, -3.0], - [0.0, 0.0, 0.0], - [3.0, 0.0, 0.0] - ] - - # Recalculating to deal with numeric imprecision - cls.expected_payoff_matrix = [ - [0, mean([13/5.0 for _ in range(3)]), mean([2/5.0 for _ in range(3)])], - [mean([13/5.0 for _ in range(3)]), 0, 0 ], - [mean([17/5.0 for _ in range(3)]), 0 , 0] - ] - - cls.expected_payoff_stddevs = [ - [0, std([13/5.0 for _ in range(3)]), std([2/5.0 for _ in range(3)])], - [std([13/5.0 for _ in range(3)]), 0, 0 ], - [std([17/5.0 for _ in range(3)]), 0, 0 ] - ] - - cls.expected_cooperation = [ - [0, 9, 9], - [9, 0, 0], - [0, 0, 0], - ] - - cls.expected_normalised_cooperation = [ - [0, mean([3 / 5.0 for _ in range(3)]), mean([3 / 5.0 for _ in range(3)])], - [mean([3 / 5.0 for _ in range(3)]), 0, 0 ], - [0, 0, 0], - ] - - cls.expected_vengeful_cooperation = [[2 * element - 1 for element in row] - for row in cls.expected_normalised_cooperation] - - cls.expected_cooperating_rating = [ - 18.0 / 30, - 9.0 / 15, - 0 - ] - - cls.expected_good_partner_matrix = [ - [0, 3, 3], - [3, 0, 0], - [0, 0, 0] - ] - - cls.expected_good_partner_rating = [ - 1.0, - 1.0, - 0 - ] - - cls.expected_eigenjesus_rating = [ - 0.447213595499958, - 0.894427190999916, - 0.0 - ] - - cls.expected_eigenmoses_rating = [ - -0.32929277996907086, - 0.7683498199278325, - 0.5488212999484519 - ] - - #cls.expected_csv = ( - # 'Defector,Tit For Tat,Alternator\n2.6,1.7,1.5\n2.6,1.7,1.5\n2.6,1.7,1.5\n') - - def test_init(self): - rs = axelrod.ResultSet(self.players, self.interactions, - progress_bar=False) - self.assertFalse(rs.progress_bar) - self.assertEqual(rs.players, self.players) - self.assertEqual(rs.nplayers, len(self.players)) - self.assertEqual(rs.interactions, self.interactions) - for inter in self.interactions.values(): - self.assertEqual(rs.nrepetitions, len(inter)) - - # Test structure of matches - # This is really a test of the test - for index_pair, repetitions in rs.interactions.items(): - self.assertIsInstance(repetitions, list) - self.assertIsInstance(index_pair, tuple) - for interaction in repetitions: - self.assertIsInstance(interaction, list) - self.assertEqual(len(interaction), self.turns) - - def test_with_progress_bar(self): - rs = axelrod.ResultSet(self.players, self.interactions) - self.assertTrue(rs.progress_bar) - self.assertEqual(rs.progress_bar.total, 19) - - rs = axelrod.ResultSet(self.players, self.interactions, - progress_bar=True) - self.assertTrue(rs.progress_bar) - self.assertEqual(rs.progress_bar.total, 19) - - def test_null_results_matrix(self): - rs = axelrod.ResultSet(self.players, self.interactions, - progress_bar=False) - self.assertEqual( - rs._null_results_matrix, self.expected_null_results_matrix) - - def test_match_lengths(self): - rs = axelrod.ResultSet(self.players, self.interactions, - progress_bar=False) - self.assertIsInstance(rs.match_lengths, list) - self.assertEqual(len(rs.match_lengths), rs.nrepetitions) - self.assertEqual(rs.match_lengths, self.expected_match_lengths) - - for rep in rs.match_lengths: - self.assertIsInstance(rep, list) - self.assertEqual(len(rep), len(self.players)) - - for i, opp in enumerate(rep): - self.assertIsInstance(opp, list) - self.assertEqual(len(opp), len(self.players)) - - for j, length in enumerate(opp): - edge = (i, j) - if edge in self.edges or edge[::-1] in self.edges : # Specific test for example match setup - self.assertEqual(length, self.turns) - else: - self.assertEqual(length, 0) - - def test_scores(self): - rs = axelrod.ResultSet(self.players, self.interactions, - progress_bar=False) - self.assertIsInstance(rs.scores, list) - self.assertEqual(len(rs.scores), rs.nplayers) - self.assertEqual(rs.scores, self.expected_scores) - - def test_ranking(self): - rs = axelrod.ResultSet(self.players, self.interactions, - progress_bar=False) - self.assertIsInstance(rs.ranking, list) - self.assertEqual(len(rs.ranking), rs.nplayers) - self.assertEqual(rs.ranking, self.expected_ranking) - - def test_ranked_names(self): - rs = axelrod.ResultSet(self.players, self.interactions, - progress_bar=False) - self.assertIsInstance(rs.ranked_names, list) - self.assertEqual(len(rs.ranked_names), rs.nplayers) - self.assertEqual(rs.ranked_names, self.expected_ranked_names) - - def test_wins(self): - rs = axelrod.ResultSet(self.players, self.interactions, - progress_bar=False) - self.assertIsInstance(rs.wins, list) - self.assertEqual(len(rs.wins), rs.nplayers) - self.assertEqual(rs.wins, self.expected_wins) - - def test_normalised_scores(self): - rs = axelrod.ResultSet(self.players, self.interactions, - progress_bar=False) - self.assertIsInstance(rs.normalised_scores, list) - self.assertEqual(len(rs.normalised_scores), rs.nplayers) - self.assertEqual(rs.normalised_scores, self.expected_normalised_scores) - - def test_payoffs(self): - rs = axelrod.ResultSet(self.players, self.interactions, - progress_bar=False) - self.assertIsInstance(rs.payoffs, list) - self.assertEqual(len(rs.payoffs), rs.nplayers) - self.assertEqual(rs.payoffs, self.expected_payoffs) - - def test_payoff_matrix(self): - rs = axelrod.ResultSet(self.players, self.interactions, - progress_bar=False) - self.assertIsInstance(rs.payoff_matrix, list) - self.assertEqual(len(rs.payoff_matrix), rs.nplayers) - self.assertEqual(rs.payoff_matrix, self.expected_payoff_matrix) - - def test_score_diffs(self): - rs = axelrod.ResultSet(self.players, self.interactions, - progress_bar=False) - self.assertIsInstance(rs.score_diffs, list) - self.assertEqual(len(rs.score_diffs), rs.nplayers) - for i, row in enumerate(rs.score_diffs): - for j, col in enumerate(row): - for k, score in enumerate(col): - self.assertAlmostEqual(score, - self.expected_score_diffs[i][j][k]) - - def test_payoff_diffs_means(self): - rs = axelrod.ResultSet(self.players, self.interactions, - progress_bar=False) - self.assertIsInstance(rs.payoff_diffs_means, list) - self.assertEqual(len(rs.payoff_diffs_means), rs.nplayers) - for i, row in enumerate(rs.payoff_diffs_means): - for j, col in enumerate(row): - self.assertAlmostEqual(col, - self.expected_payoff_diffs_means[i][j]) - - def test_payoff_stddevs(self): - rs = axelrod.ResultSet(self.players, self.interactions, - progress_bar=False) - self.assertIsInstance(rs.payoff_stddevs, list) - self.assertEqual(len(rs.payoff_stddevs), rs.nplayers) - self.assertEqual(rs.payoff_stddevs, self.expected_payoff_stddevs) - - def test_cooperation(self): - rs = axelrod.ResultSet(self.players, self.interactions, - progress_bar=False) - self.assertIsInstance(rs.cooperation, list) - self.assertEqual(len(rs.cooperation), rs.nplayers) - self.assertEqual(rs.cooperation, self.expected_cooperation) - - def test_normalised_cooperation(self): - rs = axelrod.ResultSet(self.players, self.interactions, - progress_bar=False) - self.assertIsInstance(rs.normalised_cooperation, list) - self.assertEqual(len(rs.normalised_cooperation), rs.nplayers) - self.assertEqual(rs.normalised_cooperation, - self.expected_normalised_cooperation) - - def test_vengeful_cooperation(self): - rs = axelrod.ResultSet(self.players, self.interactions, - progress_bar=False) - self.assertIsInstance(rs.vengeful_cooperation, list) - self.assertEqual(len(rs.vengeful_cooperation), rs.nplayers) - self.assertEqual(rs.vengeful_cooperation, - self.expected_vengeful_cooperation) - - def test_cooperating_rating(self): - rs = axelrod.ResultSet(self.players, self.interactions, - progress_bar=False) - self.assertIsInstance(rs.cooperating_rating, list) - self.assertEqual(len(rs.cooperating_rating), rs.nplayers) - self.assertEqual(rs.cooperating_rating, - self.expected_cooperating_rating) - def test_good_partner_matrix(self): - rs = axelrod.ResultSet(self.players, self.interactions, - progress_bar=False) - self.assertIsInstance(rs.good_partner_matrix, list) - self.assertEqual(len(rs.good_partner_matrix), rs.nplayers) - self.assertEqual(rs.good_partner_matrix, - self.expected_good_partner_matrix) - - def test_good_partner_rating(self): - rs = axelrod.ResultSet(self.players, self.interactions, - progress_bar=False) - self.assertIsInstance(rs.good_partner_rating, list) - self.assertEqual(len(rs.good_partner_rating), rs.nplayers) - self.assertEqual(rs.good_partner_rating, - self.expected_good_partner_rating) - - def test_eigenjesus_rating(self): - rs = axelrod.ResultSet(self.players, self.interactions, - progress_bar=False) - self.assertIsInstance(rs.eigenjesus_rating, list) - self.assertEqual(len(rs.eigenjesus_rating), rs.nplayers) - for j, rate in enumerate(rs.eigenjesus_rating): - self.assertAlmostEqual(rate, self.expected_eigenjesus_rating[j]) - - def test_eigenmoses_rating(self): - rs = axelrod.ResultSet(self.players, self.interactions, - progress_bar=False) - self.assertIsInstance(rs.eigenmoses_rating, list) - self.assertEqual(len(rs.eigenmoses_rating), rs.nplayers) - for j, rate in enumerate(rs.eigenmoses_rating): - self.assertAlmostEqual(rate, self.expected_eigenmoses_rating[j]) - - """ - def test_csv(self): - rs = axelrod.ResultSet(self.players, self.interactions, - progress_bar=False) - self.assertEqual(rs.csv(), self.expected_csv) - """ diff --git a/axelrod/tests/unit/test_spatial_three.py b/axelrod/tests/unit/test_spatial_three.py deleted file mode 100644 index 0d9a2b367..000000000 --- a/axelrod/tests/unit/test_spatial_three.py +++ /dev/null @@ -1,366 +0,0 @@ -import unittest -import axelrod - -from numpy import mean, std, float64 - -import tempfile - -from hypothesis import given -from hypothesis.strategies import floats, integers - -class TestResultSet_SpatialStructure(unittest.TestCase): - - @classmethod - def setUpClass(cls): - - cls.players = (axelrod.Alternator(), axelrod.TitForTat(), - axelrod.Defector(), axelrod.Cooperator()) - cls.turns = 5 - cls.edges = [(0, 0), (1, 1), (2, 2), (3, 3)] - cls.matches = {(i, i): [axelrod.Match((cls.players[i], - cls.players[i].clone()), - turns=cls.turns) - for _ in range(3)] for i in range(4)} - - - cls.interactions = {} - for index_pair, matches in cls.matches.items(): - for match in matches: - match.play() - - try: - cls.interactions[index_pair].append(match.result) - except KeyError: - cls.interactions[index_pair] = [match.result] - - cls.expected_players_to_match_dicts = {0: cls.matches[(0, 0)] , - 1: cls.matches[(1, 1)] , - 2: cls.matches[(2, 2)], - 3: cls.matches[(3, 3)]} - - cls.expected_match_lengths =[ - [[5, 0, 0, 0], [0, 5, 0, 0], [0, 0, 5, 0], [0, 0, 0, 5]] - for _ in range(3) - ] - - cls.expected_scores =[ - [0, 0, 0], - [0, 0, 0], - [0, 0, 0], - [0, 0, 0], - ] - - cls.expected_wins =[ - [0, 0, 0], - [0, 0, 0], - [0, 0, 0], - [0, 0, 0] - ] - - cls.expected_normalised_scores =[ - ["nan" for _ in range(3)] for i in range(4) - ] - - cls.expected_ranking = [0, 1, 2, 3] - - cls.expected_ranked_names = ['Alternator','Tit For Tat','Defector','Cooperator'] - - cls.expected_null_results_matrix = [ - [[0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0]], - [[0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0]], - [[0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0]], - ] - - cls.expected_payoffs = [ - [[11 /5.0 for _ in range(3)], [], [], []], - [[], [15 /5.0 for _ in range(3)], [], []], - [[], [], [5 /5.0 for _ in range(3)], []], - [[], [], [], [15 /5.0 for _ in range(3)]] - ] - - norm_scores = cls.expected_normalised_scores - cls.expected_score_diffs = [ - [[0.0 for _ in range(3)] for _ in range(4) ] for _ in range(4) - ] - - cls.expected_payoff_diffs_means = [ - [0.0, 0.0, 0.0, 0.0], - [0.0, 0.0, 0.0, 0.0], - [0.0, 0.0, 0.0, 0.0], - [0.0, 0.0, 0.0, 0.0] - - ] - - # Recalculating to deal with numeric imprecision - cls.expected_payoff_matrix = [ - [mean([11/5.0 for _ in range(3)]),0, 0, 0], - [0, mean([15/5.0 for _ in range(3)]), 0, 0], - [0, 0, mean([5/5.0 for _ in range(3)]), 0], - [0, 0, 0, mean([15/5.0 for _ in range(3)])] - ] - - cls.expected_payoff_stddevs = [ - [std([11/5.0 for _ in range(3)]),0, 0, 0], - [0, std([15/5.0 for _ in range(3)]), 0, 0], - [0, 0, std([5/5.0 for _ in range(3)]), 0], - [0, 0, 0, std([15/5.0 for _ in range(3)])] - ] - - cls.expected_cooperation = [ - [0, 0, 0, 0], - [0, 0, 0, 0], - [0, 0, 0, 0], - [0, 0, 0, 0] - ] - - cls.expected_normalised_cooperation = [ - [mean([3 / 5.0 for _ in range(3)]), 0.0, 0.0, 0.0], - [0.0, mean([5 / 5.0 for _ in range(3)]), 0.0, 0.0], - [0.0, 0.0, 0.0, 0.0], - [0.0, 0.0, 0.0, mean([5 / 5.0 for _ in range(3)])] - ] - - cls.expected_vengeful_cooperation = [[2 * element - 1 for element in row] - for row in cls.expected_normalised_cooperation] - - cls.expected_cooperating_rating = [ - 0, - 0, - 0, - 0, - ] - - cls.expected_good_partner_matrix = [ - [0, 0, 0, 0], - [0, 0, 0, 0], - [0, 0, 0, 0], - [0, 0, 0, 0] - ] - - cls.expected_good_partner_rating = [ - 0, - 0, - 0, - 0 - ] - - cls.expected_eigenjesus_rating = [ - 0.0009235301367282831, - 0.7071064796379986, - 0.0, - 0.7071064796379986, - ] - - cls.expected_eigenmoses_rating = [ - 0.4765940316018446, - 0.3985944056208427, - 0.6746133178770147, - 0.3985944056208427 - ] - - #cls.expected_csv = ( - # 'Defector,Tit For Tat,Alternator\n2.6,1.7,1.5\n2.6,1.7,1.5\n2.6,1.7,1.5\n') - - def test_init(self): - rs = axelrod.ResultSet(self.players, self.interactions, - progress_bar=False) - self.assertFalse(rs.progress_bar) - self.assertEqual(rs.players, self.players) - self.assertEqual(rs.nplayers, len(self.players)) - self.assertEqual(rs.interactions, self.interactions) - for inter in self.interactions.values(): - self.assertEqual(rs.nrepetitions, len(inter)) - - # Test structure of matches - # This is really a test of the test - for index_pair, repetitions in rs.interactions.items(): - self.assertIsInstance(repetitions, list) - self.assertIsInstance(index_pair, tuple) - for interaction in repetitions: - self.assertIsInstance(interaction, list) - self.assertEqual(len(interaction), self.turns) - - def test_with_progress_bar(self): - rs = axelrod.ResultSet(self.players, self.interactions) - self.assertTrue(rs.progress_bar) - self.assertEqual(rs.progress_bar.total, 19) - - rs = axelrod.ResultSet(self.players, self.interactions, - progress_bar=True) - self.assertTrue(rs.progress_bar) - self.assertEqual(rs.progress_bar.total, 19) - - def test_null_results_matrix(self): - rs = axelrod.ResultSet(self.players, self.interactions, - progress_bar=False) - self.assertEqual( - rs._null_results_matrix, self.expected_null_results_matrix) - - def test_match_lengths(self): - rs = axelrod.ResultSet(self.players, self.interactions, - progress_bar=False) - self.assertIsInstance(rs.match_lengths, list) - self.assertEqual(len(rs.match_lengths), rs.nrepetitions) - self.assertEqual(rs.match_lengths, self.expected_match_lengths) - - for rep in rs.match_lengths: - self.assertIsInstance(rep, list) - self.assertEqual(len(rep), len(self.players)) - - for i, opp in enumerate(rep): - self.assertIsInstance(opp, list) - self.assertEqual(len(opp), len(self.players)) - - for j, length in enumerate(opp): - k = (i, j) - if k in self.edges or k[::-1] in self.edges : # Specific test for example match setup - self.assertEqual(length, self.turns) - else: - self.assertEqual(length, 0) - - def test_scores(self): - rs = axelrod.ResultSet(self.players, self.interactions, - progress_bar=False) - self.assertIsInstance(rs.scores, list) - self.assertEqual(len(rs.scores), rs.nplayers) - self.assertEqual(rs.scores, self.expected_scores) - - def test_ranking(self): - rs = axelrod.ResultSet(self.players, self.interactions, - progress_bar=False) - self.assertIsInstance(rs.ranking, list) - self.assertEqual(len(rs.ranking), rs.nplayers) - self.assertEqual(rs.ranking, self.expected_ranking) - - def test_ranked_names(self): - rs = axelrod.ResultSet(self.players, self.interactions, - progress_bar=False) - self.assertIsInstance(rs.ranked_names, list) - self.assertEqual(len(rs.ranked_names), rs.nplayers) - self.assertEqual(rs.ranked_names, self.expected_ranked_names) - - def test_wins(self): - rs = axelrod.ResultSet(self.players, self.interactions, - progress_bar=False) - self.assertIsInstance(rs.wins, list) - self.assertEqual(len(rs.wins), rs.nplayers) - self.assertEqual(rs.wins, self.expected_wins) - - def test_normalised_scores(self): - rs = axelrod.ResultSet(self.players, self.interactions, - progress_bar=False) - self.assertIsInstance(rs.normalised_scores, list) - self.assertEqual(len(rs.normalised_scores), rs.nplayers) - self.assertEqual([[str(s) for s in player] for player in rs.normalised_scores] - , self.expected_normalised_scores) - - def test_payoffs(self): - rs = axelrod.ResultSet(self.players, self.interactions, - progress_bar=False) - self.assertIsInstance(rs.payoffs, list) - self.assertEqual(len(rs.payoffs), rs.nplayers) - self.assertEqual(rs.payoffs, self.expected_payoffs) - - def test_payoff_matrix(self): - rs = axelrod.ResultSet(self.players, self.interactions, - progress_bar=False) - self.assertIsInstance(rs.payoff_matrix, list) - self.assertEqual(len(rs.payoff_matrix), rs.nplayers) - self.assertEqual(rs.payoff_matrix, self.expected_payoff_matrix) - - def test_score_diffs(self): - rs = axelrod.ResultSet(self.players, self.interactions, - progress_bar=False) - self.assertIsInstance(rs.score_diffs, list) - self.assertEqual(len(rs.score_diffs), rs.nplayers) - for i, row in enumerate(rs.score_diffs): - for j, col in enumerate(row): - for k, score in enumerate(col): - self.assertAlmostEqual(score, - self.expected_score_diffs[i][j][k]) - - def test_payoff_diffs_means(self): - rs = axelrod.ResultSet(self.players, self.interactions, - progress_bar=False) - self.assertIsInstance(rs.payoff_diffs_means, list) - self.assertEqual(len(rs.payoff_diffs_means), rs.nplayers) - for i, row in enumerate(rs.payoff_diffs_means): - for j, col in enumerate(row): - self.assertAlmostEqual(col, - self.expected_payoff_diffs_means[i][j]) - - def test_payoff_stddevs(self): - rs = axelrod.ResultSet(self.players, self.interactions, - progress_bar=False) - self.assertIsInstance(rs.payoff_stddevs, list) - self.assertEqual(len(rs.payoff_stddevs), rs.nplayers) - self.assertEqual(rs.payoff_stddevs, self.expected_payoff_stddevs) - - def test_cooperation(self): - rs = axelrod.ResultSet(self.players, self.interactions, - progress_bar=False) - self.assertIsInstance(rs.cooperation, list) - self.assertEqual(len(rs.cooperation), rs.nplayers) - self.assertEqual(rs.cooperation, self.expected_cooperation) - - def test_normalised_cooperation(self): - rs = axelrod.ResultSet(self.players, self.interactions, - progress_bar=False) - self.assertIsInstance(rs.normalised_cooperation, list) - self.assertEqual(len(rs.normalised_cooperation), rs.nplayers) - self.assertEqual(rs.normalised_cooperation, - self.expected_normalised_cooperation) - - def test_vengeful_cooperation(self): - rs = axelrod.ResultSet(self.players, self.interactions, - progress_bar=False) - self.assertIsInstance(rs.vengeful_cooperation, list) - self.assertEqual(len(rs.vengeful_cooperation), rs.nplayers) - self.assertEqual(rs.vengeful_cooperation, - self.expected_vengeful_cooperation) - - def test_cooperating_rating(self): - rs = axelrod.ResultSet(self.players, self.interactions, - progress_bar=False) - self.assertIsInstance(rs.cooperating_rating, list) - self.assertEqual(len(rs.cooperating_rating), rs.nplayers) - self.assertEqual(rs.cooperating_rating, - self.expected_cooperating_rating) - def test_good_partner_matrix(self): - rs = axelrod.ResultSet(self.players, self.interactions, - progress_bar=False) - self.assertIsInstance(rs.good_partner_matrix, list) - self.assertEqual(len(rs.good_partner_matrix), rs.nplayers) - self.assertEqual(rs.good_partner_matrix, - self.expected_good_partner_matrix) - - def test_good_partner_rating(self): - rs = axelrod.ResultSet(self.players, self.interactions, - progress_bar=False) - self.assertIsInstance(rs.good_partner_rating, list) - self.assertEqual(len(rs.good_partner_rating), rs.nplayers) - self.assertEqual(rs.good_partner_rating, - self.expected_good_partner_rating) - - def test_eigenjesus_rating(self): - rs = axelrod.ResultSet(self.players, self.interactions, - progress_bar=False) - self.assertIsInstance(rs.eigenjesus_rating, list) - self.assertEqual(len(rs.eigenjesus_rating), rs.nplayers) - for j, rate in enumerate(rs.eigenjesus_rating): - self.assertAlmostEqual(rate, self.expected_eigenjesus_rating[j]) - - def test_eigenmoses_rating(self): - rs = axelrod.ResultSet(self.players, self.interactions, - progress_bar=False) - self.assertIsInstance(rs.eigenmoses_rating, list) - self.assertEqual(len(rs.eigenmoses_rating), rs.nplayers) - for j, rate in enumerate(rs.eigenmoses_rating): - self.assertAlmostEqual(rate, self.expected_eigenmoses_rating[j]) - - """ - def test_csv(self): - rs = axelrod.ResultSet(self.players, self.interactions, - progress_bar=False) - self.assertEqual(rs.csv(), self.expected_csv) - """ diff --git a/axelrod/tests/unit/test_spatial_two.py b/axelrod/tests/unit/test_spatial_two.py deleted file mode 100644 index df85cc199..000000000 --- a/axelrod/tests/unit/test_spatial_two.py +++ /dev/null @@ -1,382 +0,0 @@ -import unittest -import axelrod - -from numpy import mean, std - -import tempfile - -from hypothesis import given -from hypothesis.strategies import floats, integers - -class TestResultSet_SpatialStructure(unittest.TestCase): - - @classmethod - def setUpClass(cls): - - cls.players = (axelrod.Alternator(), axelrod.TitForTat(), - axelrod.Defector(), axelrod.Cooperator()) - cls.turns = 5 - cls.edges = [(0, 1), (2, 3)] - cls.matches = { (0,1): [axelrod.Match((cls.players[0], cls.players[1]), - turns=cls.turns) for _ in range(3)], - (2,3): [axelrod.Match((cls.players[2], cls.players[3]), - turns=cls.turns) for _ in range(3)]} - - cls.interactions = {} - for index_pair, matches in cls.matches.items(): - for match in matches: - match.play() - try: - cls.interactions[index_pair].append(match.result) - except KeyError: - cls.interactions[index_pair] = [match.result] - - - cls.expected_players_to_match_dicts = {0: cls.matches[(0, 1)] , - 1: cls.matches[(0, 1)] , - 2: cls.matches[(2, 3)], - 3: cls.matches[(2, 3)]} - - cls.expected_match_lengths =[ - [[0, 5, 0, 0], [5, 0, 0, 0], [0, 0, 0, 5], [0, 0, 5, 0]] - for _ in range(3) - ] - - cls.expected_scores =[ - [13, 13, 13], - [13, 13, 13], - [25, 25, 25], - [0, 0, 0] - ] - - cls.expected_wins =[ - [0, 0, 0], - [0, 0, 0], - [1, 1, 1], - [0, 0, 0] - ] - - cls.expected_normalised_scores =[ - [(13.0 / 5 ) for _ in range(3)], - [(13.0 / 5 ) for _ in range(3)], - [(25.0 / 5 ) for _ in range(3)], - [0 for _ in range(3)] - ] - - cls.expected_ranking = [2, 0, 1, 3] - - cls.expected_ranked_names = ['Defector','Alternator','Tit For Tat','Cooperator'] - - cls.expected_null_results_matrix = [ - [[0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0]], - [[0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0]], - [[0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0]], - ] - - cls.expected_payoffs = [ - [[], [13/5.0 for _ in range(3)], [], []], - [[13/5.0 for _ in range(3)], [], [], []], - [[], [], [], [25/5.0 for _ in range(3)]], - [[], [], [0 for _ in range(3)], []] - ] - - norm_scores = cls.expected_normalised_scores - cls.expected_score_diffs = [ - [[0.0, 0.0, 0.0], - [0.0, 0.0, 0.0], - [0.0, 0.0, 0.0], - [0.0, 0.0, 0.0]], - [[0.0, 0.0, 0.0], - [0.0, 0.0, 0.0], - [0.0, 0.0, 0.0], - [0.0, 0.0, 0.0]], - [[0.0, 0.0, 0.0], - [0.0, 0.0, 0.0], - [0.0, 0.0, 0.0], - [5.0, 5.0, 5.0]], - [[0.0, 0.0, 0.0], - [0.0, 0.0, 0.0], - [-5.0, -5.0, -5.0], - [0.0, 0.0, 0.0]] - ] - - cls.expected_payoff_diffs_means = [ - [0.0, 0.0, 0.0, 0.0], - [0.0, 0.0, 0.0, 0.0], - [0.0, 0.0, 0.0, 5.0], - [0.0, 0.0, -5.0, 0.0] - - ] - - # Recalculating to deal with numeric imprecision - cls.expected_payoff_matrix = [ - [0, mean([13/5.0 for _ in range(3)]), 0, 0], - [mean([13/5.0 for _ in range(3)]), 0, 0, 0], - [0, 0, 0, mean([25/5.0 for _ in range(3)])], - [0, 0, 0, 0] - ] - - cls.expected_payoff_stddevs = [ - [0, std([13/5.0 for _ in range(3)]), 0, 0], - [std([13/5.0 for _ in range(3)]), 0, 0, 0], - [0, 0, 0, std([25/5.0 for _ in range(3)])], - [0, 0, 0, 0] - ] - - cls.expected_cooperation = [ - [0, 9, 0, 0], - [9, 0, 0, 0], - [0, 0, 0, 0], - [0, 0, 15, 0] - ] - - cls.expected_normalised_cooperation = [ - [0.0, mean([3 / 5.0 for _ in range(3)]), 0.0, 0.0], - [mean([3 / 5.0 for _ in range(3)]), 0.0, 0.0, 0.0], - [0.0, 0.0, 0.0, 0.0], - [0.0, 0.0, mean([5 / 5.0 for _ in range(3)]), 0.0] - ] - - cls.expected_vengeful_cooperation = [[2 * element - 1 for element in row] - for row in cls.expected_normalised_cooperation] - - cls.expected_cooperating_rating = [ - 18.0 / 30, - 18.0 / 30, - 0, - 30 /30 - ] - - cls.expected_good_partner_matrix = [ - [0, 3, 0, 0], - [3, 0, 0, 0], - [0, 0, 0, 0], - [0, 0, 3, 0] - ] - - cls.expected_good_partner_rating = [ - 1.0, - 1.0, - 0, - 1.0 - ] - - cls.expected_eigenjesus_rating = [ - 0.7071067811865476, - 0.7071067811865476, - 0.0, - 0.0, - ] - - cls.expected_eigenmoses_rating = [ - 0.48505781033492573, - 0.48505781033492573, - 0.7090603855860735, - 0.1633132292825755 - ] - - #cls.expected_csv = ( - # 'Defector,Tit For Tat,Alternator\n2.6,1.7,1.5\n2.6,1.7,1.5\n2.6,1.7,1.5\n') - - def test_init(self): - rs = axelrod.ResultSet(self.players, self.interactions, - progress_bar=False) - self.assertFalse(rs.progress_bar) - self.assertEqual(rs.players, self.players) - self.assertEqual(rs.nplayers, len(self.players)) - self.assertEqual(rs.interactions, self.interactions) - for inter in self.interactions.values(): - self.assertEqual(rs.nrepetitions, len(inter)) - - # Test structure of matches - # This is really a test of the test - for index_pair, repetitions in rs.interactions.items(): - self.assertIsInstance(repetitions, list) - self.assertIsInstance(index_pair, tuple) - for interaction in repetitions: - self.assertIsInstance(interaction, list) - self.assertEqual(len(interaction), self.turns) - - def test_with_progress_bar(self): - rs = axelrod.ResultSet(self.players, self.interactions) - self.assertTrue(rs.progress_bar) - self.assertEqual(rs.progress_bar.total, 19) - - rs = axelrod.ResultSet(self.players, self.interactions, - progress_bar=True) - self.assertTrue(rs.progress_bar) - self.assertEqual(rs.progress_bar.total, 19) - - def test_null_results_matrix(self): - rs = axelrod.ResultSet(self.players, self.interactions, - progress_bar=False) - self.assertEqual( - rs._null_results_matrix, self.expected_null_results_matrix) - - def test_match_lengths(self): - rs = axelrod.ResultSet(self.players, self.interactions, - progress_bar=False) - self.assertIsInstance(rs.match_lengths, list) - self.assertEqual(len(rs.match_lengths), rs.nrepetitions) - self.assertEqual(rs.match_lengths, self.expected_match_lengths) - - for rep in rs.match_lengths: - self.assertIsInstance(rep, list) - self.assertEqual(len(rep), len(self.players)) - - for i, opp in enumerate(rep): - self.assertIsInstance(opp, list) - self.assertEqual(len(opp), len(self.players)) - - for j, length in enumerate(opp): - k = (i, j) - if k in self.edges or k[::-1] in self.edges : # Specific test for example match setup - self.assertEqual(length, self.turns) - else: - self.assertEqual(length, 0) - - def test_scores(self): - rs = axelrod.ResultSet(self.players, self.interactions, - progress_bar=False) - self.assertIsInstance(rs.scores, list) - self.assertEqual(len(rs.scores), rs.nplayers) - self.assertEqual(rs.scores, self.expected_scores) - - def test_ranking(self): - rs = axelrod.ResultSet(self.players, self.interactions, - progress_bar=False) - self.assertIsInstance(rs.ranking, list) - self.assertEqual(len(rs.ranking), rs.nplayers) - self.assertEqual(rs.ranking, self.expected_ranking) - - def test_ranked_names(self): - rs = axelrod.ResultSet(self.players, self.interactions, - progress_bar=False) - self.assertIsInstance(rs.ranked_names, list) - self.assertEqual(len(rs.ranked_names), rs.nplayers) - self.assertEqual(rs.ranked_names, self.expected_ranked_names) - - def test_wins(self): - rs = axelrod.ResultSet(self.players, self.interactions, - progress_bar=False) - self.assertIsInstance(rs.wins, list) - self.assertEqual(len(rs.wins), rs.nplayers) - self.assertEqual(rs.wins, self.expected_wins) - - def test_normalised_scores(self): - rs = axelrod.ResultSet(self.players, self.interactions, - progress_bar=False) - self.assertIsInstance(rs.normalised_scores, list) - self.assertEqual(len(rs.normalised_scores), rs.nplayers) - self.assertEqual(rs.normalised_scores, self.expected_normalised_scores) - - def test_payoffs(self): - rs = axelrod.ResultSet(self.players, self.interactions, - progress_bar=False) - self.assertIsInstance(rs.payoffs, list) - self.assertEqual(len(rs.payoffs), rs.nplayers) - self.assertEqual(rs.payoffs, self.expected_payoffs) - - def test_payoff_matrix(self): - rs = axelrod.ResultSet(self.players, self.interactions, - progress_bar=False) - self.assertIsInstance(rs.payoff_matrix, list) - self.assertEqual(len(rs.payoff_matrix), rs.nplayers) - self.assertEqual(rs.payoff_matrix, self.expected_payoff_matrix) - - def test_score_diffs(self): - rs = axelrod.ResultSet(self.players, self.interactions, - progress_bar=False) - self.assertIsInstance(rs.score_diffs, list) - self.assertEqual(len(rs.score_diffs), rs.nplayers) - for i, row in enumerate(rs.score_diffs): - for j, col in enumerate(row): - for k, score in enumerate(col): - self.assertAlmostEqual(score, - self.expected_score_diffs[i][j][k]) - - def test_payoff_diffs_means(self): - rs = axelrod.ResultSet(self.players, self.interactions, - progress_bar=False) - self.assertIsInstance(rs.payoff_diffs_means, list) - self.assertEqual(len(rs.payoff_diffs_means), rs.nplayers) - for i, row in enumerate(rs.payoff_diffs_means): - for j, col in enumerate(row): - self.assertAlmostEqual(col, - self.expected_payoff_diffs_means[i][j]) - - def test_payoff_stddevs(self): - rs = axelrod.ResultSet(self.players, self.interactions, - progress_bar=False) - self.assertIsInstance(rs.payoff_stddevs, list) - self.assertEqual(len(rs.payoff_stddevs), rs.nplayers) - self.assertEqual(rs.payoff_stddevs, self.expected_payoff_stddevs) - - def test_cooperation(self): - rs = axelrod.ResultSet(self.players, self.interactions, - progress_bar=False) - self.assertIsInstance(rs.cooperation, list) - self.assertEqual(len(rs.cooperation), rs.nplayers) - self.assertEqual(rs.cooperation, self.expected_cooperation) - - def test_normalised_cooperation(self): - rs = axelrod.ResultSet(self.players, self.interactions, - progress_bar=False) - self.assertIsInstance(rs.normalised_cooperation, list) - self.assertEqual(len(rs.normalised_cooperation), rs.nplayers) - self.assertEqual(rs.normalised_cooperation, - self.expected_normalised_cooperation) - - def test_vengeful_cooperation(self): - rs = axelrod.ResultSet(self.players, self.interactions, - progress_bar=False) - self.assertIsInstance(rs.vengeful_cooperation, list) - self.assertEqual(len(rs.vengeful_cooperation), rs.nplayers) - self.assertEqual(rs.vengeful_cooperation, - self.expected_vengeful_cooperation) - - def test_cooperating_rating(self): - rs = axelrod.ResultSet(self.players, self.interactions, - progress_bar=False) - self.assertIsInstance(rs.cooperating_rating, list) - self.assertEqual(len(rs.cooperating_rating), rs.nplayers) - self.assertEqual(rs.cooperating_rating, - self.expected_cooperating_rating) - def test_good_partner_matrix(self): - rs = axelrod.ResultSet(self.players, self.interactions, - progress_bar=False) - self.assertIsInstance(rs.good_partner_matrix, list) - self.assertEqual(len(rs.good_partner_matrix), rs.nplayers) - self.assertEqual(rs.good_partner_matrix, - self.expected_good_partner_matrix) - - def test_good_partner_rating(self): - rs = axelrod.ResultSet(self.players, self.interactions, - progress_bar=False) - self.assertIsInstance(rs.good_partner_rating, list) - self.assertEqual(len(rs.good_partner_rating), rs.nplayers) - self.assertEqual(rs.good_partner_rating, - self.expected_good_partner_rating) - - def test_eigenjesus_rating(self): - rs = axelrod.ResultSet(self.players, self.interactions, - progress_bar=False) - self.assertIsInstance(rs.eigenjesus_rating, list) - self.assertEqual(len(rs.eigenjesus_rating), rs.nplayers) - for j, rate in enumerate(rs.eigenjesus_rating): - self.assertAlmostEqual(rate, self.expected_eigenjesus_rating[j]) - - def test_eigenmoses_rating(self): - rs = axelrod.ResultSet(self.players, self.interactions, - progress_bar=False) - self.assertIsInstance(rs.eigenmoses_rating, list) - self.assertEqual(len(rs.eigenmoses_rating), rs.nplayers) - for j, rate in enumerate(rs.eigenmoses_rating): - self.assertAlmostEqual(rate, self.expected_eigenmoses_rating[j]) - - """ - def test_csv(self): - rs = axelrod.ResultSet(self.players, self.interactions, - progress_bar=False) - self.assertEqual(rs.csv(), self.expected_csv) - """ From 613b924313bb9ec18134deb831aee37a39ed0eb9 Mon Sep 17 00:00:00 2001 From: Nikoleta Glynatsi Date: Tue, 28 Jun 2016 15:37:41 +0100 Subject: [PATCH 13/25] Removed a print command that was accidentally left here. --- axelrod/tests/property.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/axelrod/tests/property.py b/axelrod/tests/property.py index a4cfa9931..73a05173a 100644 --- a/axelrod/tests/property.py +++ b/axelrod/tests/property.py @@ -182,8 +182,6 @@ def spatial_tournaments(draw, strategies=axelrod.strategies, for i in range (0, len(players)-1): temp=(i, i+1) edges.append(temp) - print(players) - print(edges) repetitions = draw(integers(min_value=min_repetitions, max_value=max_repetitions)) From a71c65f915b405c11c92c10b5c4e0d188a9ec46d Mon Sep 17 00:00:00 2001 From: Nikoleta Glynatsi Date: Tue, 28 Jun 2016 15:39:47 +0100 Subject: [PATCH 14/25] Pep tests. --- axelrod/tests/unit/test_resultset.py | 86 +++++++++------------------- 1 file changed, 28 insertions(+), 58 deletions(-) diff --git a/axelrod/tests/unit/test_resultset.py b/axelrod/tests/unit/test_resultset.py index b9148db76..620776928 100644 --- a/axelrod/tests/unit/test_resultset.py +++ b/axelrod/tests/unit/test_resultset.py @@ -38,8 +38,6 @@ def setUpClass(cls): 1: cls.matches[(0, 1)] + cls.matches[(1, 2)], 2: cls.matches[(1, 2)] + cls.matches[(0, 2)]} - - cls.expected_match_lengths =[ [[0, 5, 5], [5, 0, 5], [5, 5, 0]] for _ in range(3) @@ -143,8 +141,7 @@ def setUpClass(cls): 1.0, 0 ] - - + cls.expected_eigenjesus_rating = [ 0.5547001962252291, 0.8320502943378436, @@ -401,7 +398,6 @@ class TestResultSet_SpatialStructure(TestResultSet): """ Specific test for some spatial tournament. """ - @classmethod def setUpClass(cls): @@ -422,13 +418,10 @@ def setUpClass(cls): except KeyError: cls.interactions[index_pair] = [match.result] - cls.expected_players_to_match_dicts = {0: cls.matches[(0, 1)] + cls.matches[(0, 2)], 1: cls.matches[(0, 1)] , 2: cls.matches[(0, 2)]} - - cls.expected_match_lengths =[ [[0, 5, 5], [5, 0, 0], [5, 0, 0]] for _ in range(3) @@ -507,9 +500,9 @@ def setUpClass(cls): ] cls.expected_normalised_cooperation = [ - [0, mean([3 / 5.0 for _ in range(3)]), mean([3 / 5.0 for _ in range(3)])], - [mean([3 / 5.0 for _ in range(3)]), 0, 0 ], - [0, 0, 0], + [0, mean([3 / 5.0 for _ in range(3)]), mean([3 / 5.0 for _ in range(3)])], + [mean([3 / 5.0 for _ in range(3)]), 0, 0 ], + [0, 0, 0], ] cls.expected_vengeful_cooperation = [[2 * element - 1 for element in row] @@ -530,7 +523,7 @@ def setUpClass(cls): cls.expected_good_partner_rating = [ 1.0, 1.0, - 0 + 0.0 ] cls.expected_eigenjesus_rating = [ @@ -548,10 +541,9 @@ def setUpClass(cls): cls.expected_csv = ( 'Defector,Tit For Tat,Alternator\n3.4,2.6,1.5\n3.4,2.6,1.5\n3.4,2.6,1.5\n') - def test_match_lengths(self): """ - Overwriting match_lenghts because of edges + Overwriting match lengths because of edges """ rs = axelrod.ResultSet(self.players, self.interactions, progress_bar=False) @@ -569,7 +561,8 @@ def test_match_lengths(self): for j, length in enumerate(opp): edge = (i, j) - if edge in self.edges or edge[::-1] in self.edges : # Specific test for example match setup + # Specific test for example match setup + if edge in self.edges or edge[::-1] in self.edges : self.assertEqual(length, self.turns) else: self.assertEqual(length, 0) @@ -597,7 +590,6 @@ def setUpClass(cls): except KeyError: cls.interactions[index_pair] = [match.result] - cls.expected_players_to_match_dicts = {0: cls.matches[(0, 1)] , 1: cls.matches[(0, 1)] , 2: cls.matches[(2, 3)], @@ -609,10 +601,10 @@ def setUpClass(cls): ] cls.expected_scores =[ - [13, 13, 13], - [13, 13, 13], - [25, 25, 25], - [0, 0, 0] + [ 13.0 for _ in range(3)], + [ 13.0 for _ in range(3)], + [ 25.0 for _ in range(3)], + [ 0 for _ in range(3)] ] cls.expected_wins =[ @@ -631,7 +623,8 @@ def setUpClass(cls): cls.expected_ranking = [2, 0, 1, 3] - cls.expected_ranked_names = ['Defector','Alternator','Tit For Tat','Cooperator'] + cls.expected_ranked_names = ['Defector','Alternator', + 'Tit For Tat','Cooperator'] cls.expected_null_results_matrix = [ [[0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0]], @@ -671,7 +664,6 @@ def setUpClass(cls): [0.0, 0.0, 0.0, 0.0], [0.0, 0.0, 0.0, 5.0], [0.0, 0.0, -5.0, 0.0] - ] # Recalculating to deal with numeric imprecision @@ -709,8 +701,8 @@ def setUpClass(cls): cls.expected_cooperating_rating = [ 18.0 / 30, 18.0 / 30, - 0, - 30 /30 + 0.0, + 30 / 30 ] cls.expected_good_partner_matrix = [ @@ -723,7 +715,7 @@ def setUpClass(cls): cls.expected_good_partner_rating = [ 1.0, 1.0, - 0, + 0.0, 1.0 ] @@ -742,7 +734,8 @@ def setUpClass(cls): ] cls.expected_csv = ( - 'Defector,Alternator,Tit For Tat,Cooperator\n5.0,2.6,2.6,0.0\n5.0,2.6,2.6,0.0\n5.0,2.6,2.6,0.0\n') + "Defector,Alternator,Tit For Tat,Cooperator\n5.0,2.6,2.6,0.0\n5.0,2.6,2.6,0.0\n5.0,2.6,2.6,0.0\n") + class TestResultSet_SpatialStructure_Three(TestResultSet_SpatialStructure): @@ -758,7 +751,6 @@ def setUpClass(cls): turns=cls.turns) for _ in range(3)] for i in range(4)} - cls.interactions = {} for index_pair, matches in cls.matches.items(): for match in matches: @@ -769,8 +761,8 @@ def setUpClass(cls): except KeyError: cls.interactions[index_pair] = [match.result] - cls.expected_players_to_match_dicts = {0: cls.matches[(0, 0)] , - 1: cls.matches[(1, 1)] , + cls.expected_players_to_match_dicts = {0: cls.matches[(0, 0)], + 1: cls.matches[(1, 1)], 2: cls.matches[(2, 2)], 3: cls.matches[(3, 3)]} @@ -780,17 +772,11 @@ def setUpClass(cls): ] cls.expected_scores =[ - [0, 0, 0], - [0, 0, 0], - [0, 0, 0], - [0, 0, 0], + [0 for _ in range(3)] for _ in range(4) ] cls.expected_wins =[ - [0, 0, 0], - [0, 0, 0], - [0, 0, 0], - [0, 0, 0] + [0 for _ in range(3)] for _ in range(4) ] cls.expected_normalised_scores =[ @@ -820,11 +806,7 @@ def setUpClass(cls): ] cls.expected_payoff_diffs_means = [ - [0.0, 0.0, 0.0, 0.0], - [0.0, 0.0, 0.0, 0.0], - [0.0, 0.0, 0.0, 0.0], - [0.0, 0.0, 0.0, 0.0] - + [0.0 for _ in range(4)] for _ in range(4) ] # Recalculating to deal with numeric imprecision @@ -843,10 +825,7 @@ def setUpClass(cls): ] cls.expected_cooperation = [ - [0, 0, 0, 0], - [0, 0, 0, 0], - [0, 0, 0, 0], - [0, 0, 0, 0] + [0.0 for _ in range(4)] for _ in range(4) ] cls.expected_normalised_cooperation = [ @@ -860,24 +839,15 @@ def setUpClass(cls): for row in cls.expected_normalised_cooperation] cls.expected_cooperating_rating = [ - 0, - 0, - 0, - 0, + 0.0 for _ in range(4) ] cls.expected_good_partner_matrix = [ - [0, 0, 0, 0], - [0, 0, 0, 0], - [0, 0, 0, 0], - [0, 0, 0, 0] + [0.0 for _ in range(4)] for _ in range(4) ] cls.expected_good_partner_rating = [ - 0, - 0, - 0, - 0 + 0.0 for _ in range(4) ] cls.expected_eigenjesus_rating = [ From e525ca1eb71678a22451ae04f893ca255fd5015f Mon Sep 17 00:00:00 2001 From: Nikoleta Glynatsi Date: Mon, 11 Jul 2016 23:09:22 +0100 Subject: [PATCH 15/25] Created a documentation for the spatial tournament. --- .../_static/spatial_tournaments/spatial.png | Bin 0 -> 20591 bytes .../spatial_tournaments/spatial_results.png | Bin 0 -> 5763 bytes docs/tutorials/further_topics/index.rst | 1 + .../further_topics/spatial_tournaments.rst | 71 ++++++++++++++++++ 4 files changed, 72 insertions(+) create mode 100644 docs/tutorials/further_topics/_static/spatial_tournaments/spatial.png create mode 100644 docs/tutorials/further_topics/_static/spatial_tournaments/spatial_results.png create mode 100644 docs/tutorials/further_topics/spatial_tournaments.rst diff --git a/docs/tutorials/further_topics/_static/spatial_tournaments/spatial.png b/docs/tutorials/further_topics/_static/spatial_tournaments/spatial.png new file mode 100644 index 0000000000000000000000000000000000000000..1d6985e75e9a2cb108b285b61190a5dc1bcb7829 GIT binary patch literal 20591 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 literal 0 HcmV?d00001 diff --git a/docs/tutorials/further_topics/_static/spatial_tournaments/spatial_results.png b/docs/tutorials/further_topics/_static/spatial_tournaments/spatial_results.png new file mode 100644 index 0000000000000000000000000000000000000000..ff64c744486659e6b6ca32d9ede14f2da0b65004 GIT binary patch literal 5763 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 literal 0 HcmV?d00001 diff --git a/docs/tutorials/further_topics/index.rst b/docs/tutorials/further_topics/index.rst index 2eb9e817f..e404fe4ed 100644 --- a/docs/tutorials/further_topics/index.rst +++ b/docs/tutorials/further_topics/index.rst @@ -11,5 +11,6 @@ Contents: noisy_tournaments.rst probabilistict_end_tournaments.rst + spatial_tournaments.rst morality_metrics.rst ecological_variant.rst diff --git a/docs/tutorials/further_topics/spatial_tournaments.rst b/docs/tutorials/further_topics/spatial_tournaments.rst new file mode 100644 index 000000000..06a3a82c3 --- /dev/null +++ b/docs/tutorials/further_topics/spatial_tournaments.rst @@ -0,0 +1,71 @@ +Spatial tournaments +=================== + +In a spatial topology tournament the connectivity between players is given by +a graph where the nodes represent players, and the edges, connecting the nodes, +refer to the connection between the corresponding players. + +The initial work was done by Nowak and May in 1992s paper, "Evolutionary games +and spatial chaos", introducing a spatial topology as a square lattice. (The +paper can be found here : http://www.nature.com/nature/journal/v359/n6398/abs/359826a0.html). + +Additionally, Szabó and Fáth 2007 in their paper consider a variate of graphs, +such as lattices small world, scale-free graphs and evolving networks. (Their +paper can be found here : https://arxiv.org/abs/cond-mat/0607344 ). + +Eves so, here it is possible to create a tournament where the players are +allocated to any given graph and the only interact with other player that they +have a connection - edge. + +Let's create a tournament where :code:`Cooperator` and :code:`Defector` do not +play each other neither :code:`TitForTat` and :code:`Grudger` : + +.. image:: _static/spatial_tournaments/spatial.png + :width: 80% + :align: center + +Note that the edges have to be given as a list argument:: + + >>> import axelrod as axl + >>> players = [axl.Cooperator(), axl.Defector(), + ... axl.TitForTat(), axl.Grudger()] + >>> edges = [(0, 2), (0, 3), (1, 2), (1, 3)] + +To create a spatial tournament you call the :code:`SpatialTournamnent` class:: + + >>> spatial_tournament = axl.SpatialTournament(players, edges=edges) + >>> results = spatial_tournament.play() + +We can plot the results:: + + >>> plot = axl.Plot(results) + >>> p = plot.boxplot() + >>> p.show() + + +.. image:: _static/spatial_tournaments/spatial_results.png + :width: 50% + :align: center + +We can, like any other tournament, obtain the ranks for our players:: + + >>> results.ranked_names + ['Cooperator', 'Tit For Tat', 'Grudger', 'Defector'] + +Let's run small tournament of 2 :code:`turns` and 5 :code:`repetitions` +and obtain the interactions:: + + >>> spatial_tournament = axl.SpatialTournament(players ,turns=2, repetitions=2, edges=edges) + >>> results = spatial_tournament.play() + >>> for index_pair, interaction in results.interactions.items(): + ... player1 = spatial_tournament.players[index_pair[0]] + ... player2 = spatial_tournament.players[index_pair[1]] + ... print('%s vs %s: %s' % (player1, player2, interaction)) + + Defector vs Tit For Tat: [[('D', 'C'), ('D', 'D')], [('D', 'C'), ('D', 'D')]] + Cooperator vs Grudger: [[('C', 'C'), ('C', 'C')], [('C', 'C'), ('C', 'C')]] + Defector vs Grudger: [[('D', 'C'), ('D', 'D')], [('D', 'C'), ('D', 'D')]] + Cooperator vs Tit For Tat: [[('C', 'C'), ('C', 'C')], [('C', 'C'), ('C', 'C')]] + +As anticipated :code:`Cooperator` does not interact with :code:`Defector` neither +:code:`TitForTat` with :code:`Grudger`. From cbc445d4da8e0142129b82f4b08ab5b97ed63bc8 Mon Sep 17 00:00:00 2001 From: Nikoleta Glynatsi Date: Wed, 13 Jul 2016 10:40:21 +0100 Subject: [PATCH 16/25] Last corrections on the spatial tournament docs. --- .../further_topics/spatial_tournaments.rst | 22 +++++++++---------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/docs/tutorials/further_topics/spatial_tournaments.rst b/docs/tutorials/further_topics/spatial_tournaments.rst index 06a3a82c3..bc35c3352 100644 --- a/docs/tutorials/further_topics/spatial_tournaments.rst +++ b/docs/tutorials/further_topics/spatial_tournaments.rst @@ -5,26 +5,27 @@ In a spatial topology tournament the connectivity between players is given by a graph where the nodes represent players, and the edges, connecting the nodes, refer to the connection between the corresponding players. -The initial work was done by Nowak and May in 1992s paper, "Evolutionary games -and spatial chaos", introducing a spatial topology as a square lattice. (The -paper can be found here : http://www.nature.com/nature/journal/v359/n6398/abs/359826a0.html). +The initial work was done by Nowak and May in a 1992 paper, "Evolutionary games +and spatial chaos", introducing spatial topology as a square lattice. (The +paper can be found here: http://www.nature.com/nature/journal/v359/n6398/abs/359826a0.html). -Additionally, Szabó and Fáth 2007 in their paper consider a variate of graphs, -such as lattices small world, scale-free graphs and evolving networks. (Their -paper can be found here : https://arxiv.org/abs/cond-mat/0607344 ). +Additionally, Szabó and Fáth in their 2007 paper consider a variety of graphs, +such as lattices, small world, scale-free graphs and evolving networks. (Their +paper can be found here: https://arxiv.org/abs/cond-mat/0607344). -Eves so, here it is possible to create a tournament where the players are -allocated to any given graph and the only interact with other player that they +Even so, here it is possible to create a tournament where the players are +allocated to any given graph and they only interact with players to which they have a connection - edge. Let's create a tournament where :code:`Cooperator` and :code:`Defector` do not -play each other neither :code:`TitForTat` and :code:`Grudger` : +play each other and neither do :code:`TitForTat` and :code:`Grudger` : .. image:: _static/spatial_tournaments/spatial.png :width: 80% :align: center -Note that the edges have to be given as a list argument:: +Note that the edges have to be given as a list of tuples of player +indices:: >>> import axelrod as axl >>> players = [axl.Cooperator(), axl.Defector(), @@ -61,7 +62,6 @@ and obtain the interactions:: ... player1 = spatial_tournament.players[index_pair[0]] ... player2 = spatial_tournament.players[index_pair[1]] ... print('%s vs %s: %s' % (player1, player2, interaction)) - Defector vs Tit For Tat: [[('D', 'C'), ('D', 'D')], [('D', 'C'), ('D', 'D')]] Cooperator vs Grudger: [[('C', 'C'), ('C', 'C')], [('C', 'C'), ('C', 'C')]] Defector vs Grudger: [[('D', 'C'), ('D', 'D')], [('D', 'C'), ('D', 'D')]] From f94d0224c0577073df65651cc053bdaced21b02c Mon Sep 17 00:00:00 2001 From: Nikoleta Glynatsi Date: Wed, 13 Jul 2016 10:41:07 +0100 Subject: [PATCH 17/25] Adding an extra test for a complete multigraph. In a complete multigraph alla the nodes are connected to each other and to themselves. Which in a round robin topology. Therefore, a test to make sure that the results procuded by a complete multigraph and a round robin are equivalent. --- axelrod/tests/unit/test_tournament.py | 43 ++++++++++++++++++++++++++- 1 file changed, 42 insertions(+), 1 deletion(-) diff --git a/axelrod/tests/unit/test_tournament.py b/axelrod/tests/unit/test_tournament.py index 4ab0877e2..62fb4eb6e 100644 --- a/axelrod/tests/unit/test_tournament.py +++ b/axelrod/tests/unit/test_tournament.py @@ -9,7 +9,9 @@ from hypothesis import given, example, settings from hypothesis.strategies import integers -from axelrod.tests.property import tournaments, prob_end_tournaments +from axelrod.tests.property import (tournaments, + prob_end_tournaments, + strategy_lists) import axelrod @@ -33,6 +35,8 @@ test_edges = [(0, 1), (1, 2), (3, 4)] +deterministic_strategies = [s for s in axelrod.ordinary_strategies + if not s().classifier['stochastic']] class TestTournament(unittest.TestCase): @@ -581,3 +585,40 @@ def test_init(self): 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) From 3a44249f68b85d71120db6a2ffebe7c587216330 Mon Sep 17 00:00:00 2001 From: Nikoleta Glynatsi Date: Wed, 13 Jul 2016 16:48:13 +0100 Subject: [PATCH 18/25] Removing property and property tests for Spatial tournament. After running the tests with Travis has returned the following error: Data generation is extremely slow. Decided to simply remove the tests. --- axelrod/tests/property.py | 47 ----------------------------- axelrod/tests/unit/test_property.py | 36 ---------------------- 2 files changed, 83 deletions(-) diff --git a/axelrod/tests/property.py b/axelrod/tests/property.py index 73a05173a..113cd5cf6 100644 --- a/axelrod/tests/property.py +++ b/axelrod/tests/property.py @@ -144,53 +144,6 @@ def prob_end_tournaments(draw, strategies=axelrod.strategies, return tournament -@composite -def spatial_tournaments(draw, strategies=axelrod.strategies, - min_size=2, max_size=10, - min_turns=1, max_turns=200, - min_noise=0, max_noise=1, - min_repetitions=1, max_repetitions=20): - """ - A hypothesis decorator to return a tournament and a random seed (to ensure - reproducibility for strategies that make use of the random module when - initiating). - - Parameters - ---------- - min_size : integer - The minimum number of strategies to include - max_size : integer - The maximum number of strategies to include - min_noise : float - The minimum noise value - min_noise : float - The maximum noise value - min_repetitions : integer - The minimum number of repetitions - max_repetitions : integer - The maximum number of repetitions - edges : list - The edges to include - """ - strategies = draw(strategy_lists(strategies=strategies, - min_size=min_size, - max_size=max_size)) - players = [s() for s in strategies] - turns = draw(integers(min_value=min_turns, max_value=max_turns)) - - edges= [] - for i in range (0, len(players)-1): - temp=(i, i+1) - edges.append(temp) - - repetitions = draw(integers(min_value=min_repetitions, - max_value=max_repetitions)) - noise = draw(floats(min_value=min_noise, max_value=max_noise)) - - tournament = axelrod.SpatialTournament(players, edges=edges, turns=turns, - repetitions=repetitions, noise=noise) - return tournament - @composite def games(draw, prisoners_dilemma=True, max_value=100): """ diff --git a/axelrod/tests/unit/test_property.py b/axelrod/tests/unit/test_property.py index 589ac7b22..3174d764d 100644 --- a/axelrod/tests/unit/test_property.py +++ b/axelrod/tests/unit/test_property.py @@ -161,42 +161,6 @@ def test_decorator_with_stochastic_strategies(self, tournament): for p in tournament.players: self.assertIn(str(p), stochastic_player_names) -class TestSpatialTournament(unittest.TestCase): - - def test_call(self): - tournament = tournaments().example() - self.assertIsInstance(tournament, axelrod.Tournament) - - @given(tournament=spatial_tournaments(min_turns=2, max_turns=50, min_noise=0, - max_noise=1, min_repetitions=2, - max_repetitions=50, - max_size=3)) - - @settings(max_examples=10, timeout=0) - def test_decorator(self, tournament): - self.assertIsInstance(tournament, axelrod.Tournament) - self.assertLessEqual(tournament.turns, 50) - self.assertGreaterEqual(tournament.turns, 2) - self.assertLessEqual(tournament.noise, 1) - self.assertGreaterEqual(tournament.noise, 0) - self.assertLessEqual(tournament.repetitions, 50) - self.assertGreaterEqual(tournament.repetitions, 2) - - @given(tournament=spatial_tournaments(strategies=axelrod.basic_strategies)) - @settings(max_examples=10, timeout=0) - def test_decorator_with_given_strategies(self, tournament): - self.assertIsInstance(tournament, axelrod.SpatialTournament) - basic_player_names = [str(s()) for s in axelrod.basic_strategies] - for p in tournament.players: - self.assertIn(str(p), basic_player_names) - - @given(tournament=spatial_tournaments(strategies=stochastic_strategies)) - @settings(max_examples=10, timeout=0) - def test_decorator_with_stochastic_strategies(self, tournament): - self.assertIsInstance(tournament, axelrod.SpatialTournament) - stochastic_player_names = [str(s()) for s in stochastic_strategies] - for p in tournament.players: - self.assertIn(str(p), stochastic_player_names) class TestGame(unittest.TestCase): From dfe7755b5a2d810d73eded71868add1c1f5a198e Mon Sep 17 00:00:00 2001 From: Nikoleta Glynatsi Date: Wed, 13 Jul 2016 17:09:43 +0100 Subject: [PATCH 19/25] Removing spatial tournament from import. --- axelrod/tests/unit/test_property.py | 1 - 1 file changed, 1 deletion(-) diff --git a/axelrod/tests/unit/test_property.py b/axelrod/tests/unit/test_property.py index 3174d764d..84ec142c5 100644 --- a/axelrod/tests/unit/test_property.py +++ b/axelrod/tests/unit/test_property.py @@ -4,7 +4,6 @@ from axelrod.tests.property import (strategy_lists, matches, tournaments, prob_end_tournaments, - spatial_tournaments, games) from hypothesis import given, settings From 16d7178ec64aca481d7763f43364daf3c37bf3aa Mon Sep 17 00:00:00 2001 From: Nikoleta Glynatsi Date: Thu, 14 Jul 2016 00:04:19 +0100 Subject: [PATCH 20/25] Changing the word "dictionary" to "list". --- axelrod/match_generator.py | 4 ++-- axelrod/tournament.py | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/axelrod/match_generator.py b/axelrod/match_generator.py index 426b19723..62434f8b1 100644 --- a/axelrod/match_generator.py +++ b/axelrod/match_generator.py @@ -214,8 +214,8 @@ def __init__(self, players, turns, game, repetitions, edges): The game object used to score the match repetitions : int The number of repetitions of a given match - edges : dictionary - A dictionary containing the existing edges + edges : list + A list of tuples containing the existing edges """ def build_match_chunks(self): for edge in self.edges: diff --git a/axelrod/tournament.py b/axelrod/tournament.py index 2b5f8666e..0c7afbd59 100644 --- a/axelrod/tournament.py +++ b/axelrod/tournament.py @@ -357,8 +357,8 @@ def __init__(self, players, edges, match_generator=SpatialMatches, A name for the tournament game : axelrod.Game The game object used to score the tournament - edges : dictionary - A dictionary containing the existing edges + edges : list + A list of tuples containing the existing edges repetitions : integer The number of times the round robin should be repeated processes : integer From 1e64dbcfb7143dc1dd7c2854a4d2314879f4d33b Mon Sep 17 00:00:00 2001 From: Nikoleta Glynatsi Date: Thu, 14 Jul 2016 00:30:16 +0100 Subject: [PATCH 21/25] Fixing doc string for SpatialMatches class. --- axelrod/match_generator.py | 56 +++++++++++++------------------------- 1 file changed, 19 insertions(+), 37 deletions(-) diff --git a/axelrod/match_generator.py b/axelrod/match_generator.py index 62434f8b1..11c1061f0 100644 --- a/axelrod/match_generator.py +++ b/axelrod/match_generator.py @@ -169,6 +169,25 @@ def estimated_size(self): return size class SpatialMatches(RoundRobinMatches): + """ + A class that generates spatially-structured matches. + In these matches, players interact only with their neighbors rather than the + entire population. This reduces to a well-mixed population when the spatial + graph is a complete graph. + + Parameters + ---------- + players : list + A list of axelrod.Player objects + turns : integer + The number of turns per match + game : axelrod.Game + The game object used to score the match + repetitions : int + The number of repetitions of a given match + edges : list + A list of tuples containing the existing edges + """ def __init__(self, players, turns, game, repetitions, edges): @@ -179,44 +198,7 @@ def __init__(self, players, turns, game, repetitions, edges): self.edges = edges super(SpatialMatches, self).__init__(players, turns, game, repetitions) - """ - A class that generates spatial structure matches. In spatial structure - matches the players do not play against every other player, instead they - only play their neighbors. - - In literature the authors interpreted spatial tournaments topology - as a 2D square lattice. We want to create a class that will not take as - an argument only a 2D lattice but any given graph. - - After considering various python packages for graphs, we ended up using - a simple dictionary that includes the edges.So the players - nodes will - only play players that are connected to with an edge. - - We have chosen to implement spatial structure tournaments because - it has spon various tournaments after the work of Nowak and May 1992, - - which proved that in PD cooperation behavior can merge for spatial - games. - - Moreover, IPD tournaments with this topology have been conducted by - various researchers such as Lindgren and Nordahl in 1994 - - and Brauchli, Killingback and Doebeli 1999. - - Parameters - ---------- - players : list - A list of axelrod.Player objects - turns : integer - The number of turns per match - game : axelrod.Game - The game object used to score the match - repetitions : int - The number of repetitions of a given match - edges : list - A list of tuples containing the existing edges - """ def build_match_chunks(self): for edge in self.edges: match_params = self.build_single_match_params() From 0c6580489162f898e7eb2c3f4b9e65bf60f08e6b Mon Sep 17 00:00:00 2001 From: Nikoleta Glynatsi Date: Thu, 14 Jul 2016 00:35:23 +0100 Subject: [PATCH 22/25] Removed a forgotten test which is not being used. --- axelrod/tests/unit/test_match_generator.py | 7 ------- 1 file changed, 7 deletions(-) diff --git a/axelrod/tests/unit/test_match_generator.py b/axelrod/tests/unit/test_match_generator.py index 4790a6d55..739db5e4d 100644 --- a/axelrod/tests/unit/test_match_generator.py +++ b/axelrod/tests/unit/test_match_generator.py @@ -236,10 +236,3 @@ def test_len(self): self.players, test_turns, test_game, test_repetitions, edges) self.assertEqual(len(sp), len(list(sp.build_match_chunks()))) self.assertEqual(len(sp), len(edges)) - -""" - def test_edges_that_do_not_include_all_players(self): - edges = [(0, 1)] - self.assertRaises(ValueError, axelrod.SpatialMatches, - self.players, test_turns, test_game, test_repetitions, edges) -""" From 7a82a2c799e8d71b7b44316d5437e3c2919fcb4f Mon Sep 17 00:00:00 2001 From: Nikoleta Glynatsi Date: Thu, 14 Jul 2016 00:39:06 +0100 Subject: [PATCH 23/25] PEP8 corrections that were pointed out. --- axelrod/tests/unit/test_property.py | 3 +-- axelrod/tests/unit/test_resultset.py | 8 ++++---- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/axelrod/tests/unit/test_property.py b/axelrod/tests/unit/test_property.py index 84ec142c5..4497efc13 100644 --- a/axelrod/tests/unit/test_property.py +++ b/axelrod/tests/unit/test_property.py @@ -3,8 +3,7 @@ import axelrod from axelrod.tests.property import (strategy_lists, matches, tournaments, - prob_end_tournaments, - games) + prob_end_tournaments, games) from hypothesis import given, settings diff --git a/axelrod/tests/unit/test_resultset.py b/axelrod/tests/unit/test_resultset.py index 620776928..de92b3968 100644 --- a/axelrod/tests/unit/test_resultset.py +++ b/axelrod/tests/unit/test_resultset.py @@ -141,7 +141,7 @@ def setUpClass(cls): 1.0, 0 ] - + cls.expected_eigenjesus_rating = [ 0.5547001962252291, 0.8320502943378436, @@ -394,7 +394,7 @@ def test_update_progress_bar(self): self.assertEqual(axelrod.result_set.update_progress_bar(method)(1), None) -class TestResultSet_SpatialStructure(TestResultSet): +class TestResultSetSpatialStructure(TestResultSet): """ Specific test for some spatial tournament. """ @@ -567,7 +567,7 @@ def test_match_lengths(self): else: self.assertEqual(length, 0) -class TestResultSet_SpatialStructure_Two(TestResultSet_SpatialStructure): +class TestResultSetSpatialStructureTwo(TestResultSet_SpatialStructure): @classmethod def setUpClass(cls): @@ -737,7 +737,7 @@ def setUpClass(cls): "Defector,Alternator,Tit For Tat,Cooperator\n5.0,2.6,2.6,0.0\n5.0,2.6,2.6,0.0\n5.0,2.6,2.6,0.0\n") -class TestResultSet_SpatialStructure_Three(TestResultSet_SpatialStructure): +class TestResultSetSpatialStructureThree(TestResultSet_SpatialStructure): @classmethod def setUpClass(cls): From 5b3f81ec5f75b0d000eeec245a54054b470241fc Mon Sep 17 00:00:00 2001 From: Nikoleta Glynatsi Date: Thu, 14 Jul 2016 11:51:43 +0100 Subject: [PATCH 24/25] Expanding the doc string of the test_match_lenghts. Which is for the TestResultSet_SpatialStructure is the test_resultset file. --- axelrod/tests/unit/test_resultset.py | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/axelrod/tests/unit/test_resultset.py b/axelrod/tests/unit/test_resultset.py index de92b3968..4ef5fa50f 100644 --- a/axelrod/tests/unit/test_resultset.py +++ b/axelrod/tests/unit/test_resultset.py @@ -543,7 +543,17 @@ def setUpClass(cls): def test_match_lengths(self): """ - Overwriting match lengths because of edges + Overwriting match lengths test. This method, among other things, checks + that if two players interacted the length of that interaction equals the + number of turns. + + Implementing this for the round robin tournament meant checking the + interactions between each strategy and the rest strategies of the + tournament. + + In a spatial tournament we need to check that: The length of interaction + of players-nodes that are end vertices of an edge is equal to the + number of turns. Otherwise it is 0. """ rs = axelrod.ResultSet(self.players, self.interactions, progress_bar=False) @@ -567,6 +577,7 @@ def test_match_lengths(self): else: self.assertEqual(length, 0) + class TestResultSetSpatialStructureTwo(TestResultSet_SpatialStructure): @classmethod From 9fcaaa5e42225cc3453ba343001af576cb9d917f Mon Sep 17 00:00:00 2001 From: Nikoleta Glynatsi Date: Thu, 14 Jul 2016 12:00:04 +0100 Subject: [PATCH 25/25] Replacing "TestResult_SpatialStructure" to "TestResultSpatialStructure". --- axelrod/tests/unit/test_resultset.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/axelrod/tests/unit/test_resultset.py b/axelrod/tests/unit/test_resultset.py index 4ef5fa50f..125e0a00c 100644 --- a/axelrod/tests/unit/test_resultset.py +++ b/axelrod/tests/unit/test_resultset.py @@ -578,7 +578,7 @@ def test_match_lengths(self): self.assertEqual(length, 0) -class TestResultSetSpatialStructureTwo(TestResultSet_SpatialStructure): +class TestResultSetSpatialStructureTwo(TestResultSetSpatialStructure): @classmethod def setUpClass(cls): @@ -748,7 +748,7 @@ def setUpClass(cls): "Defector,Alternator,Tit For Tat,Cooperator\n5.0,2.6,2.6,0.0\n5.0,2.6,2.6,0.0\n5.0,2.6,2.6,0.0\n") -class TestResultSetSpatialStructureThree(TestResultSet_SpatialStructure): +class TestResultSetSpatialStructureThree(TestResultSetSpatialStructure): @classmethod def setUpClass(cls):