Skip to content

Commit 131c5aa

Browse files
committed
Merge pull request #514 from Axelrod-Python/509
Add prob end tournament type to run_axelrod
2 parents dd81e9b + defaf81 commit 131c5aa

11 files changed

+392
-47
lines changed

axelrod/__init__.py

+4-3
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,9 @@
1111
from .strategies import *
1212
from .tournament_type import *
1313
from .tournament import Tournament, ProbEndTournament
14-
from .tournament_manager import TournamentManager
15-
from .tournament_manager_factory import TournamentManagerFactory
14+
from .tournament_manager import TournamentManager, ProbEndTournamentManager
15+
from .tournament_manager_factory import (TournamentManagerFactory,
16+
ProbEndTournamentManagerFactory)
1617
from .result_set import ResultSet
1718
from .ecosystem import Ecosystem
18-
from .utils import run_tournaments, setup_logging
19+
from .utils import run_tournaments, run_prob_end_tournaments, setup_logging

axelrod/tests/integration/test_tournament.py

+44-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import unittest
22
import axelrod
33

4-
from axelrod.utils import setup_logging, run_tournaments
4+
from axelrod.utils import setup_logging, run_tournaments, run_prob_end_tournaments
55

66
class TestTournament(unittest.TestCase):
77

@@ -96,3 +96,46 @@ def test_utils(self):
9696
exclude_cheating=True,
9797
exclude_ordinary=True,
9898
noise=0)
99+
100+
101+
class TestProbEndTournamentManager(unittest.TestCase):
102+
103+
@classmethod
104+
def setUpClass(cls):
105+
cls.game = axelrod.Game()
106+
cls.players = [s() for s in axelrod.demo_strategies]
107+
108+
def test_tournament_manager(self):
109+
strategies = [s() for s in axelrod.demo_strategies]
110+
tm = axelrod.ProbEndTournamentManager("./", False, save_cache=False)
111+
tm.add_tournament("test-prob-end", strategies, repetitions=2, prob_end=.5,
112+
noise=0.05)
113+
tm.run_tournaments()
114+
115+
strategies = [s() for s in axelrod.basic_strategies]
116+
tm = axelrod.ProbEndTournamentManager("./", False, load_cache=False,
117+
save_cache=True)
118+
tm.add_tournament("test-prob-end", strategies, repetitions=2,
119+
prob_end=.5, noise=0.)
120+
tm.run_tournaments()
121+
122+
tm = axelrod.ProbEndTournamentManager("./", False, load_cache=True,
123+
save_cache=True)
124+
tm.add_tournament("test-prob-end", strategies, repetitions=2,
125+
prob_end=.5, noise=0.)
126+
tm.run_tournaments()
127+
128+
def test_utils(self):
129+
setup_logging(logging_destination="none")
130+
run_prob_end_tournaments(cache_file='./cache.txt',
131+
output_directory='./',
132+
repetitions=2,
133+
prob_end=.5,
134+
processes=None,
135+
no_ecological=False,
136+
rebuild_cache=False,
137+
exclude_combined=True,
138+
exclude_basic=False,
139+
exclude_cheating=True,
140+
exclude_ordinary=True,
141+
noise=0)

axelrod/tests/unit/test_tournament_manager.py

+44-6
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,10 @@ def setUpClass(cls):
1515
cls.test_players = [axelrod.Defector(), axelrod.Cooperator()]
1616

1717
cls.expected_output_file_path = './assets/test_file_name.png'
18+
cls.mgr_class = axelrod.TournamentManager
1819

1920
def test_init(self):
20-
mgr = axelrod.TournamentManager(
21+
mgr = self.mgr_class(
2122
self.test_output_directory,
2223
self.test_with_ecological)
2324
self.assertEqual(mgr._output_directory, self.test_output_directory)
@@ -26,23 +27,23 @@ def test_init(self):
2627
self.assertTrue(mgr._pass_cache)
2728

2829
def test_one_player_per_strategy(self):
29-
mgr = axelrod.TournamentManager(
30+
mgr = self.mgr_class(
3031
self.test_output_directory,
3132
self.test_with_ecological)
3233
players = mgr.one_player_per_strategy(self.test_strategies)
3334
self.assertIsInstance(players[0], axelrod.Defector)
3435
self.assertIsInstance(players[1], axelrod.Cooperator)
3536

3637
def test_output_file_path(self):
37-
mgr = axelrod.TournamentManager(
38+
mgr = self.mgr_class(
3839
self.test_output_directory,
3940
self.test_with_ecological)
4041
output_file_path = mgr._output_file_path(
4142
self.test_file_name, self.test_file_extenstion)
4243
self.assertEqual(output_file_path, self.expected_output_file_path)
4344

4445
def test_add_tournament(self):
45-
mgr = axelrod.TournamentManager(
46+
mgr = self.mgr_class(
4647
self.test_output_directory,
4748
self.test_with_ecological)
4849
mgr.add_tournament(
@@ -52,7 +53,7 @@ def test_add_tournament(self):
5253
self.assertEqual(mgr._tournaments[0].name, self.test_tournament_name)
5354

5455
def test_valid_cache(self):
55-
mgr = axelrod.TournamentManager(
56+
mgr = self.mgr_class(
5657
output_directory=self.test_output_directory,
5758
with_ecological=self.test_with_ecological, load_cache=False)
5859
mgr.add_tournament(
@@ -67,10 +68,47 @@ def test_valid_cache(self):
6768
def test_tournament_label(self):
6869
tournament = axelrod.Tournament(self.test_players, turns=20,
6970
repetitions=2)
70-
mgr = axelrod.TournamentManager(
71+
mgr = self.mgr_class(
7172
output_directory=self.test_output_directory,
7273
with_ecological=self.test_with_ecological, load_cache=False)
7374
expected_label = "Turns: {}, Repetitions: {}, Strategies: {}.".format(tournament.turns,
7475
tournament.repetitions, len(tournament.players))
7576

7677
self.assertEqual(mgr._tournament_label(tournament), expected_label)
78+
79+
80+
class TestProbEndTournamentManager(unittest.TestCase):
81+
82+
@classmethod
83+
def setUpClass(cls):
84+
cls.test_output_directory = './assets/'
85+
cls.test_with_ecological = True
86+
cls.test_tournament_name = 'test_prob_tournament'
87+
cls.test_file_name = 'test_prob_end_file_name'
88+
cls.test_file_extenstion = 'png'
89+
cls.test_strategies = [axelrod.Defector, axelrod.Cooperator]
90+
cls.test_players = [axelrod.Defector(), axelrod.Cooperator()]
91+
92+
cls.expected_output_file_path = './assets/test__prob_end_file_name.png'
93+
cls.mgr_class = axelrod.ProbEndTournamentManager
94+
95+
def test_add_tournament(self):
96+
mgr = self.mgr_class(
97+
self.test_output_directory,
98+
self.test_with_ecological)
99+
mgr.add_tournament(
100+
players=self.test_players, name=self.test_tournament_name)
101+
self.assertEqual(len(mgr._tournaments), 1)
102+
self.assertIsInstance(mgr._tournaments[0], axelrod.ProbEndTournament)
103+
self.assertEqual(mgr._tournaments[0].name, self.test_tournament_name)
104+
105+
def test_tournament_label(self):
106+
tournament = axelrod.ProbEndTournament(self.test_players, prob_end=.5,
107+
repetitions=2)
108+
mgr = self.mgr_class(
109+
output_directory=self.test_output_directory,
110+
with_ecological=self.test_with_ecological, load_cache=False)
111+
expected_label = "Prob end: {}, Repetitions: {}, Strategies: {}.".format(tournament.prob_end,
112+
tournament.repetitions,
113+
len(tournament.players))
114+
self.assertEqual(mgr._tournament_label(tournament), expected_label)

axelrod/tests/unit/test_tournament_manager_factory.py

+82-5
Original file line numberDiff line numberDiff line change
@@ -21,10 +21,10 @@ def setUpClass(cls):
2121
}
2222

2323
cls.expected_basic_strategies = axelrod.basic_strategies
24-
cls.expected_strategies = (
24+
cls.expected_ordinary_strategies = (
2525
axelrod.ordinary_strategies)
2626
cls.expected_cheating_strategies = axelrod.cheating_strategies
27-
cls.expected_all_strategies = (
27+
cls.expected_strategies = (
2828
axelrod.ordinary_strategies +
2929
axelrod.cheating_strategies)
3030

@@ -37,14 +37,14 @@ def test_tournaments_dict(self):
3737
actual_strategies = self.tmf._tournaments_dict()['strategies']
3838
actual_cheating_strategies = (
3939
self.tmf._tournaments_dict()['cheating_strategies'])
40-
actual_all_strategies = self.tmf._tournaments_dict()['all_strategies']
40+
actual_all_strategies = self.tmf._tournaments_dict()['strategies']
4141

4242
self.assertEqual(
4343
actual_basic_strategies, self.expected_basic_strategies)
4444
self.assertEqual(actual_strategies, self.expected_strategies)
4545
self.assertEqual(
4646
actual_cheating_strategies, self.expected_cheating_strategies)
47-
self.assertEqual(actual_all_strategies, self.expected_all_strategies)
47+
self.assertEqual(actual_all_strategies, self.expected_strategies)
4848

4949
# Tests to ensure that the exclusions list works as intended
5050
with_exclusions = self.tmf._tournaments_dict(self.test_exclusions)
@@ -61,7 +61,84 @@ def test_add_tournaments(self):
6161
self.tmf._add_tournaments(mgr, self.test_exclusions, self.test_kwargs)
6262
self.assertEqual(len(mgr._tournaments), 2)
6363
self.assertIsInstance(mgr._tournaments[0], axelrod.Tournament)
64-
self.assertEqual(mgr._tournaments[0].name, 'strategies')
64+
self.assertEqual(mgr._tournaments[0].name, 'ordinary_strategies')
65+
66+
def test_create_tournament_manager(self):
67+
mgr = self.tmf.create_tournament_manager(
68+
output_directory=self.test_output_directory,
69+
no_ecological=False,
70+
rebuild_cache=self.test_rebuild_cache,
71+
cache_file=self.test_cache_file,
72+
exclusions=self.test_exclusions,
73+
**self.test_kwargs)
74+
75+
self.assertIsInstance(mgr, axelrod.TournamentManager)
76+
self.assertEqual(mgr._output_directory, self.test_output_directory)
77+
self.assertEqual(len(mgr._tournaments), 2)
78+
self.assertTrue(mgr._with_ecological)
79+
self.assertTrue(mgr._pass_cache)
80+
81+
82+
class TestProbEndTournamentManagerFactory(unittest.TestCase):
83+
84+
@classmethod
85+
def setUpClass(cls):
86+
cls.tmf = axelrod.ProbEndTournamentManagerFactory
87+
88+
cls.test_output_directory = './assets/'
89+
cls.test_with_ecological = True
90+
cls.test_rebuild_cache = False
91+
cls.test_cache_file = './cache.txt'
92+
cls.test_exclusions = ['basic_strategies', 'cheating_strategies']
93+
cls.test_kwargs = {
94+
'processes': 2,
95+
'prob_end': .1,
96+
'repetitions': 200,
97+
'noise': 0
98+
}
99+
100+
cls.expected_basic_strategies = axelrod.basic_strategies
101+
cls.expected_ordinary_strategies = (
102+
axelrod.ordinary_strategies)
103+
cls.expected_cheating_strategies = axelrod.cheating_strategies
104+
cls.expected_strategies = (
105+
axelrod.ordinary_strategies +
106+
axelrod.cheating_strategies)
107+
108+
def test_tournaments_dict(self):
109+
110+
# Tests to ensure that the tournaments dictionary contains the correct
111+
# keys and values
112+
actual_basic_strategies = (
113+
self.tmf._tournaments_dict()['basic_strategies_prob_end'])
114+
actual_ordinary_strategies = self.tmf._tournaments_dict()['ordinary_strategies_prob_end']
115+
actual_cheating_strategies = (
116+
self.tmf._tournaments_dict()['cheating_strategies_prob_end'])
117+
actual_all_strategies = self.tmf._tournaments_dict()['strategies_prob_end']
118+
119+
self.assertEqual(
120+
actual_basic_strategies, self.expected_basic_strategies)
121+
self.assertEqual(actual_ordinary_strategies, self.expected_ordinary_strategies)
122+
self.assertEqual(
123+
actual_cheating_strategies, self.expected_cheating_strategies)
124+
self.assertEqual(actual_all_strategies, self.expected_strategies)
125+
126+
# Tests to ensure that the exclusions list works as intended
127+
with_exclusions = self.tmf._tournaments_dict(self.test_exclusions)
128+
self.assertFalse('basic_strategies' in with_exclusions)
129+
self.assertFalse('cheating_strategies' in with_exclusions)
130+
self.assertEqual(
131+
with_exclusions['strategies_prob_end'], self.expected_strategies)
132+
133+
def test_add_tournaments(self):
134+
mgr = axelrod.ProbEndTournamentManager(
135+
self.test_output_directory,
136+
self.test_with_ecological)
137+
138+
self.tmf._add_tournaments(mgr, self.test_exclusions, self.test_kwargs)
139+
self.assertEqual(len(mgr._tournaments), 2)
140+
self.assertIsInstance(mgr._tournaments[0], axelrod.Tournament)
141+
self.assertEqual(mgr._tournaments[0].name, 'ordinary_strategies_prob_end')
65142

66143
def test_create_tournament_manager(self):
67144
mgr = self.tmf.create_tournament_manager(

axelrod/tests/unit/test_utils.py

+16-1
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
import axelrod
44
import unittest
5+
import itertools
56

67
from hypothesis import given
78
from hypothesis.strategies import floats, text
@@ -26,7 +27,6 @@ def test_time_message_example(self):
2627
self.assertGreaterEqual(float(timed_message[len(message)+4:-1]), 0)
2728

2829

29-
3030
class TestSetupLogging(unittest.TestCase):
3131

3232
def test_basic_configuration_console(self):
@@ -41,3 +41,18 @@ def test_basic_configuration_console(self):
4141
axelrod.utils.setup_logging(logging_destination='console',
4242
verbosity=level)
4343
compare(logger.level, levels[level])
44+
45+
46+
class TestBuildExclusionsDict(unittest.TestCase):
47+
def test_build_exclusions_dict(self):
48+
"""This is really a regression test to make sure the names of the
49+
tournaments stay consistent"""
50+
bools = [True, False]
51+
for (eb, eo, ec, eco) in itertools.product(bools, repeat=4):
52+
expected_dict = {
53+
'basic_strategies': eb,
54+
'ordinary_strategies': eo,
55+
'cheating_strategies': ec,
56+
'strategies': eco}
57+
self.assertEqual(axelrod.utils.build_exclusions_dict(eb, eo, ec, eco),
58+
expected_dict)

axelrod/tournament_manager.py

+41-9
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,19 @@
1010

1111

1212
class TournamentManager(object):
13+
"""A class to manage and create tournaments."""
1314

1415
plot_types = {'boxplot': "Payoffs. ", 'payoff': "Payoffs. ",
1516
'winplot': "Wins. ", 'sdvplot': "Std Payoffs. ",
1617
'pdplot': "Payoff differences. ", 'lengthplot': "Lengths. "}
1718

19+
ecoturns = {
20+
'basic_strategies': 1000,
21+
'cheating_strategies': 10,
22+
'ordinary_strategies': 1000,
23+
'strategies': 10,
24+
}
25+
1826
def __init__(self, output_directory, with_ecological,
1927
pass_cache=True, load_cache=True, save_cache=False,
2028
cache_file='./cache.txt', image_format="svg"):
@@ -61,8 +69,8 @@ def run_tournaments(self):
6169

6270
def _run_single_tournament(self, tournament):
6371
self._logger.info(
64-
'Starting %s tournament with %d round robins of %d turns per pair.'
65-
% (tournament.name, tournament.repetitions, tournament.turns))
72+
'Starting {} tournament: '.format(tournament.name) + self._tournament_label(tournament)
73+
)
6674

6775
t0 = time.time()
6876

@@ -103,13 +111,7 @@ def run_ecological_variant(self, tournament, ecosystem):
103111
self._logger.debug(
104112
'Starting ecological variant of %s' % tournament.name)
105113
t0 = time.time()
106-
ecoturns = {
107-
'basic_strategies': 1000,
108-
'cheating_strategies': 10,
109-
'strategies': 1000,
110-
'all_strategies': 10,
111-
}
112-
ecosystem.reproduce(ecoturns.get(tournament.name))
114+
ecosystem.reproduce(self.ecoturns.get(tournament.name))
113115
self._logger.debug(
114116
timed_message('Finished ecological variant of %s' % tournament.name, t0))
115117

@@ -186,6 +188,36 @@ def _load_cache_from_file(self, file_name):
186188
return False
187189

188190

191+
class ProbEndTournamentManager(TournamentManager):
192+
"""A class to manage and create probabilistic ending tournaments."""
193+
194+
ecoturns = {
195+
'basic_strategies_prob_end': 1000,
196+
'cheating_strategies_prob_end': 10,
197+
'ordinary_strategies_prob_end': 1000,
198+
'strategies_prob_end': 10,
199+
}
200+
201+
def add_tournament(self, name, players, game=None, prob_end=.01,
202+
repetitions=10, processes=None, noise=0,
203+
with_morality=True):
204+
tournament = ProbEndTournament(
205+
name=name,
206+
players=players,
207+
prob_end=prob_end,
208+
repetitions=repetitions,
209+
processes=processes,
210+
noise=noise,
211+
with_morality=with_morality)
212+
self._tournaments.append(tournament)
213+
214+
def _tournament_label(self, tournament):
215+
"""A label for the tournament for the corresponding title plots"""
216+
return "Prob end: {}, Repetitions: {}, Strategies: {}.".format(tournament.prob_end,
217+
tournament.repetitions,
218+
len(tournament.players))
219+
220+
189221
class DeterministicCache(object):
190222

191223
def __init__(self, cache, turns):

0 commit comments

Comments
 (0)