Skip to content

Commit

Permalink
Merge pull request #654 from Nikoleta-v3/635
Browse files Browse the repository at this point in the history
635 Implementing spatial tournaments
  • Loading branch information
meatballs authored Jul 18, 2016
2 parents aa06f8b + 9fcaaa5 commit 1422925
Show file tree
Hide file tree
Showing 12 changed files with 761 additions and 11 deletions.
2 changes: 1 addition & 1 deletion axelrod/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
40 changes: 40 additions & 0 deletions axelrod/match_generator.py
Original file line number Diff line number Diff line change
Expand Up @@ -167,3 +167,43 @@ 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):
"""
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):

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)

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)
8 changes: 4 additions & 4 deletions axelrod/result_set.py
Original file line number Diff line number Diff line change
Expand Up @@ -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])

Expand Down Expand Up @@ -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])
Expand Down Expand Up @@ -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]

Expand Down Expand Up @@ -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]:
Expand Down
29 changes: 29 additions & 0 deletions axelrod/tests/unit/test_match_generator.py
Original file line number Diff line number Diff line change
Expand Up @@ -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))
1 change: 1 addition & 0 deletions axelrod/tests/unit/test_property.py
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,7 @@ def test_decorator_with_stochastic_strategies(self, tournament):
for p in tournament.players:
self.assertIn(str(p), stochastic_player_names)


class TestGame(unittest.TestCase):

def test_call(self):
Expand Down
Loading

0 comments on commit 1422925

Please sign in to comment.