Skip to content

Commit 33a595d

Browse files
authored
Merge pull request #679 from Axelrod-Python/673
Fix noise in spatial tournaments
2 parents 4aa2ab1 + d90333b commit 33a595d

File tree

4 files changed

+104
-51
lines changed

4 files changed

+104
-51
lines changed

axelrod/match_generator.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -216,12 +216,13 @@ class SpatialMatches(RoundRobinMatches):
216216
A list of tuples containing the existing edges
217217
"""
218218

219-
def __init__(self, players, turns, game, repetitions, edges):
219+
def __init__(self, players, turns, game, repetitions, edges, noise=0):
220220

221221
if not graph_is_connected(edges, players):
222222
raise ValueError("The graph edges do not include all players.")
223223
self.edges = edges
224-
super(SpatialMatches, self).__init__(players, turns, game, repetitions)
224+
super(SpatialMatches, self).__init__(players, turns, game, repetitions,
225+
noise)
225226

226227
def build_match_chunks(self):
227228
for edge in self.edges:

axelrod/tests/unit/test_match_generator.py

Lines changed: 17 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -217,19 +217,27 @@ def setUpClass(cls):
217217
cls.players = [s() for s in test_strategies]
218218

219219
@given(repetitions=integers(min_value=1, max_value=test_repetitions),
220-
turns=integers(min_value=1, max_value=test_turns))
221-
@example(repetitions=test_repetitions, turns=test_turns)
222-
def test_build_match_chunks(self, repetitions, turns):
220+
turns=integers(min_value=1, max_value=test_turns),
221+
noise=floats(min_value=0, max_value=1))
222+
@example(repetitions=test_repetitions, turns=test_turns, noise=0)
223+
def test_build_match_chunks(self, repetitions, turns, noise):
223224
edges = [(0, 1), (1, 2), (3, 4)]
224225
sp = axelrod.SpatialMatches(
225-
self.players, turns, test_game, repetitions, edges)
226+
self.players, turns, test_game, repetitions, edges, noise)
226227
chunks = list(sp.build_match_chunks())
227-
match_definitions = [tuple(list(index_pair) + [repetitions])
228-
for (index_pair, match_params, repetitions) in chunks]
229-
expected_match_definitions = [(edge[0], edge[1], repetitions)
230-
for edge in edges]
231228

232-
self.assertEqual(sorted(match_definitions), sorted(expected_match_definitions))
229+
match_definitions = set()
230+
231+
cache = None
232+
expected_params = (turns, test_game, cache, noise)
233+
for index_pair, match_params, repetitions in chunks:
234+
match_definitions.add(tuple(list(index_pair) + [repetitions]))
235+
self.assertEqual(match_params, expected_params)
236+
237+
expected_match_definitions = set((edge[0], edge[1], repetitions)
238+
for edge in edges)
239+
240+
self.assertEqual(match_definitions, expected_match_definitions)
233241

234242
def test_len(self):
235243
edges = [(0, 1), (1, 2), (3, 4)]

axelrod/tests/unit/test_tournament.py

Lines changed: 83 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -594,45 +594,82 @@ def test_init(self):
594594
self.assertTrue(tournament._with_morality)
595595
self.assertIsInstance(tournament._logger, logging.Logger)
596596
self.assertEqual(tournament.noise, 0.2)
597+
self.assertEqual(tournament.match_generator.noise, 0.2)
597598
anonymous_tournament = axelrod.Tournament(players=self.players)
598599
self.assertEqual(anonymous_tournament.name, 'axelrod')
599600

600-
@given(strategies=strategy_lists(strategies=deterministic_strategies,
601-
min_size=2, max_size=2),
602-
turns=integers(min_value=1, max_value=20))
603-
604-
def test_complete_tournament(self, strategies, turns):
605-
"""
606-
A test to check that a spatial tournament on the complete multigraph
607-
gives the same results as the round robin.
608-
"""
609-
610-
players = [s() for s in strategies]
611-
# edges
612-
edges=[]
613-
for i in range(0, len(players)) :
614-
for j in range(i, len(players)) :
615-
edges.append((i, j))
616-
# create a round robin tournament
617-
tournament = axelrod.Tournament(players, turns=turns)
618-
results = tournament.play()
619-
# create a complete spatial tournament
620-
spatial_tournament = axelrod.SpatialTournament(players, turns=turns,
621-
edges=edges)
622-
spatial_results = spatial_tournament.play()
623-
self.assertEqual(results.ranked_names, spatial_results.ranked_names)
624-
self.assertEqual(results.nplayers, spatial_results.nplayers)
625-
self.assertEqual(results.nrepetitions, spatial_results.nrepetitions)
626-
self.assertEqual(results.payoff_diffs_means, spatial_results.payoff_diffs_means)
627-
self.assertEqual(results.payoff_matrix, spatial_results.payoff_matrix)
628-
self.assertEqual(results.payoff_stddevs, spatial_results.payoff_stddevs)
629-
self.assertEqual(results.payoffs, spatial_results.payoffs)
630-
self.assertEqual(results.cooperating_rating, spatial_results.cooperating_rating)
631-
self.assertEqual(results.cooperation, spatial_results.cooperation)
632-
self.assertEqual(results.normalised_cooperation, spatial_results.normalised_cooperation)
633-
self.assertEqual(results.normalised_scores, spatial_results.normalised_scores)
634-
self.assertEqual(results.good_partner_matrix, spatial_results.good_partner_matrix)
635-
self.assertEqual(results.good_partner_rating, spatial_results.good_partner_rating)
601+
@given(strategies=strategy_lists(strategies=deterministic_strategies,
602+
min_size=2, max_size=2),
603+
turns=integers(min_value=1, max_value=20),
604+
repetitions=integers(min_value=1, max_value=5),
605+
noise=floats(min_value=0, max_value=1),
606+
seed=integers(min_value=0, max_value=4294967295))
607+
@settings(max_examples=50, timeout=0)
608+
def test_complete_tournament(self, strategies, turns, repetitions,
609+
noise, seed):
610+
"""
611+
A test to check that a spatial tournament on the complete multigraph
612+
gives the same results as the round robin.
613+
"""
614+
615+
players = [s() for s in strategies]
616+
# edges
617+
edges = []
618+
for i in range(0, len(players)):
619+
for j in range(i, len(players)):
620+
edges.append((i, j))
621+
622+
# create a round robin tournament
623+
tournament = axelrod.Tournament(players, repetitions=repetitions,
624+
turns=turns, noise=noise)
625+
# create a complete spatial tournament
626+
spatial_tournament = axelrod.SpatialTournament(players,
627+
repetitions=repetitions,
628+
turns=turns,
629+
noise=noise,
630+
edges=edges)
631+
632+
axelrod.seed(seed)
633+
results = tournament.play(progress_bar=False)
634+
axelrod.seed(seed)
635+
spatial_results = spatial_tournament.play(progress_bar=False)
636+
637+
self.assertEqual(results.ranked_names, spatial_results.ranked_names)
638+
self.assertEqual(results.nplayers, spatial_results.nplayers)
639+
self.assertEqual(results.nrepetitions, spatial_results.nrepetitions)
640+
self.assertEqual(results.payoff_diffs_means,
641+
spatial_results.payoff_diffs_means)
642+
self.assertEqual(results.payoff_matrix, spatial_results.payoff_matrix)
643+
self.assertEqual(results.payoff_stddevs, spatial_results.payoff_stddevs)
644+
self.assertEqual(results.payoffs, spatial_results.payoffs)
645+
self.assertEqual(results.cooperating_rating,
646+
spatial_results.cooperating_rating)
647+
self.assertEqual(results.cooperation, spatial_results.cooperation)
648+
self.assertEqual(results.normalised_cooperation,
649+
spatial_results.normalised_cooperation)
650+
self.assertEqual(results.normalised_scores,
651+
spatial_results.normalised_scores)
652+
self.assertEqual(results.good_partner_matrix,
653+
spatial_results.good_partner_matrix)
654+
self.assertEqual(results.good_partner_rating,
655+
spatial_results.good_partner_rating)
656+
657+
def test_particular_tournament(self):
658+
"""A test for a tournament that has caused failures during some bug
659+
fixing"""
660+
players = [axelrod.Cooperator(), axelrod.Defector(),
661+
axelrod.TitForTat(), axelrod.Grudger()]
662+
edges = [(0, 2), (0, 3), (1, 2), (1, 3)]
663+
tournament = axelrod.SpatialTournament(players, edges=edges)
664+
results = tournament.play(progress_bar=False)
665+
expected_ranked_names = ['Cooperator', 'Tit For Tat',
666+
'Grudger', 'Defector']
667+
self.assertEqual(results.ranked_names, expected_ranked_names)
668+
669+
# Check that this tournament runs with noise
670+
tournament = axelrod.SpatialTournament(players, edges=edges, noise=.5)
671+
results = tournament.play(progress_bar=False)
672+
self.assertIsInstance(results, axelrod.ResultSetFromFile)
636673

637674

638675
class TestProbEndingSpatialTournament(unittest.TestCase):
@@ -671,8 +708,11 @@ def test_init(self):
671708
@given(strategies=strategy_lists(strategies=deterministic_strategies,
672709
min_size=2, max_size=2),
673710
prob_end=floats(min_value=.1, max_value=.9),
711+
reps=integers(min_value=1, max_value=3),
674712
seed=integers(min_value=0, max_value=4294967295))
675-
def test_complete_tournament(self, strategies, prob_end, seed):
713+
@settings(max_examples=50, timeout=0)
714+
def test_complete_tournament(self, strategies, prob_end,
715+
seed, reps):
676716
"""
677717
A test to check that a spatial tournament on the complete graph
678718
gives the same results as the round robin.
@@ -683,12 +723,14 @@ def test_complete_tournament(self, strategies, prob_end, seed):
683723
for j in range(i, len(players))]
684724
# create a prob end round robin tournament
685725
axelrod.seed(seed)
686-
tournament = axelrod.ProbEndTournament(players, prob_end=prob_end)
726+
tournament = axelrod.ProbEndTournament(players, prob_end=prob_end,
727+
repetitions=reps)
687728
results = tournament.play(progress_bar=False)
688729
# create a complete spatial tournament
689730
axelrod.seed(seed)
690731
spatial_tournament = axelrod.ProbEndSpatialTournament(players,
691732
prob_end=prob_end,
733+
repetitions=reps,
692734
edges=edges)
693735
spatial_results = spatial_tournament.play(progress_bar=False)
694736
self.assertEqual(results.match_lengths, spatial_results.match_lengths)
@@ -700,8 +742,10 @@ def test_complete_tournament(self, strategies, prob_end, seed):
700742

701743

702744
@given(tournament=spatial_tournaments(strategies=axelrod.basic_strategies,
703-
max_turns=1),
745+
max_turns=1, max_noise=0,
746+
max_repetitions=3),
704747
seed=integers(min_value=0, max_value=4294967295))
748+
@settings(max_examples=50, timeout=0)
705749
def test_one_turn_tournament(self, tournament, seed):
706750
"""
707751
Tests that gives same result as the corresponding spatial round robin

axelrod/tournament.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -380,7 +380,7 @@ def __init__(self, players, edges, match_generator=SpatialMatches,
380380

381381
self.edges = edges
382382
self.match_generator = SpatialMatches(
383-
players, turns, self.game, repetitions, edges)
383+
players, turns, self.game, repetitions, edges, noise)
384384

385385

386386
class ProbEndSpatialTournament(ProbEndTournament):

0 commit comments

Comments
 (0)