Skip to content

Commit

Permalink
Add default_turns and change moran default
Browse files Browse the repository at this point in the history
Have change default match length to 200 in:

- Matches
- Tournaments
- Moran Processes

Adjusted Moran process tests as a result of it.
  • Loading branch information
drvinceknight committed Jun 10, 2017
1 parent 216ff18 commit 4ce4098
Show file tree
Hide file tree
Showing 10 changed files with 58 additions and 50 deletions.
2 changes: 2 additions & 0 deletions axelrod/__init__.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import os

on_windows = os.name == 'nt'
default_turns = 200

# The order of imports matters!
from .version import __version__
Expand All @@ -23,3 +24,4 @@
from .result_set import ResultSet, ResultSetFromFile
from .ecosystem import Ecosystem
from .fingerprint import AshlockFingerprint

2 changes: 1 addition & 1 deletion axelrod/match.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ def __init__(self, players, turns=None, prob_end=None,
else:
turns = sample_length(prob_end)
elif turns is None:
turns = 20
turns = default_turns

self.turns = turns
self.result = []
Expand Down
6 changes: 4 additions & 2 deletions axelrod/moran.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

import numpy as np

from axelrod import default_turns
from .deterministic_cache import DeterministicCache
from .match import Match
from .random_ import randrange
Expand Down Expand Up @@ -30,8 +31,9 @@ def fitness_proportionate_selection(scores):


class MoranProcess(object):
def __init__(self, players, turns=100, noise=0, deterministic_cache=None,
mutation_rate=0., mode='bd', match_class=Match):
def __init__(self, players, turns=default_turns, noise=0,
deterministic_cache=None, mutation_rate=0., mode='bd',
match_class=Match):
"""
An agent based Moran process class. In each round, each player plays a
Match with each other player. Players are assigned a fitness score by
Expand Down
5 changes: 3 additions & 2 deletions axelrod/tests/unit/test_match.py
Original file line number Diff line number Diff line change
Expand Up @@ -66,9 +66,10 @@ def test_default_init(self):
match = axelrod.Match((p1, p2))
self.assertEqual(match.result, [])
self.assertEqual(match.players, [p1, p2])
self.assertEqual(match.players[0].match_attributes['length'], 20)
self.assertEqual(match.players[0].match_attributes['length'],
axelrod.default_turns)
self.assertEqual(match._cache_key, (p1, p2, match.turns))
self.assertLessEqual(match.turns, 20)
self.assertLessEqual(match.turns, axelrod.default_turns)
self.assertEqual(match._cache, {})
self.assertEqual(match.noise, 0)
self.assertEqual(match.game.RPST(), (3, 1, 0, 5))
Expand Down
2 changes: 1 addition & 1 deletion axelrod/tests/unit/test_moran.py
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ def test_two_random_players(self):
self.assertEqual(len(mp), 2)
self.assertEqual(len(populations), 2)
self.assertEqual(populations, mp.populations)
self.assertEqual(mp.winning_strategy_name, str(p1))
self.assertEqual(mp.winning_strategy_name, str(p2))

def test_two_players_with_mutation(self):
p1, p2 = axelrod.Cooperator(), axelrod.Defector()
Expand Down
32 changes: 16 additions & 16 deletions axelrod/tests/unit/test_tournament.py
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ def test_serial_play(self):
name=self.test_name,
players=self.players,
game=self.game,
turns=200,
turns=axelrod.default_turns,
repetitions=self.test_repetitions)
results = tournament.play(progress_bar=False)
self.assertIsInstance(results, axelrod.ResultSet)
Expand All @@ -116,7 +116,7 @@ def test_serial_play(self):
name=self.test_name,
players=self.players,
game=self.game,
turns=200,
turns=axelrod.default_turns,
repetitions=self.test_repetitions)
results = tournament.play(progress_bar=False)
self.assertEqual(tournament.num_interactions, 75)
Expand All @@ -139,7 +139,7 @@ def test_no_progress_bar_play(self):
name=self.test_name,
players=self.players,
game=self.game,
turns=200,
turns=axelrod.default_turns,
repetitions=self.test_repetitions)


Expand All @@ -164,7 +164,7 @@ def test_progress_bar_play(self):
name=self.test_name,
players=self.players,
game=self.game,
turns=200,
turns=axelrod.default_turns,
repetitions=self.test_repetitions)

results = tournament.play()
Expand Down Expand Up @@ -198,7 +198,7 @@ def test_progress_bar_play_parallel(self):
name=self.test_name,
players=self.players,
game=self.game,
turns=200,
turns=axelrod.default_turns,
repetitions=self.test_repetitions)

results = tournament.play(processes=2)
Expand Down Expand Up @@ -244,7 +244,7 @@ def test_parallel_play(self):
name=self.test_name,
players=self.players,
game=self.game,
turns=200,
turns=axelrod.default_turns,
repetitions=self.test_repetitions)
results = tournament.play(processes=2, progress_bar=False)
self.assertIsInstance(results, axelrod.ResultSet)
Expand All @@ -268,7 +268,7 @@ def test_run_serial(self):
name=self.test_name,
players=self.players,
game=self.game,
turns=200,
turns=axelrod.default_turns,
repetitions=self.test_repetitions)
tournament._write_interactions = MagicMock(
name='_write_interactions')
Expand All @@ -285,7 +285,7 @@ def test_run_parallel(self):
name=self.test_name,
players=self.players,
game=self.game,
turns=200,
turns=axelrod.default_turns,
repetitions=self.test_repetitions)
tournament._write_interactions = MagicMock(
name='_write_interactions')
Expand All @@ -304,15 +304,15 @@ def test_n_workers(self):
name=self.test_name,
players=self.players,
game=self.game,
turns=200,
turns=axelrod.default_turns,
repetitions=self.test_repetitions)
self.assertEqual(tournament._n_workers(processes=1), max_processes)

tournament = axelrod.Tournament(
name=self.test_name,
players=self.players,
game=self.game,
turns=200,
turns=axelrod.default_turns,
repetitions=self.test_repetitions)
self.assertEqual(tournament._n_workers(processes=max_processes+2),
max_processes)
Expand All @@ -330,7 +330,7 @@ def test_2_workers(self):
name=self.test_name,
players=self.players,
game=self.game,
turns=200,
turns=axelrod.default_turns,
repetitions=self.test_repetitions,)
self.assertEqual(tournament._n_workers(processes=2), 2)

Expand All @@ -344,7 +344,7 @@ def test_start_workers(self):
name=self.test_name,
players=self.players,
game=self.game,
turns=200,
turns=axelrod.default_turns,
repetitions=self.test_repetitions)
chunks = tournament.match_generator.build_match_chunks()
for chunk in chunks:
Expand All @@ -365,7 +365,7 @@ def test_worker(self):
name=self.test_name,
players=self.players,
game=self.game,
turns=200,
turns=axelrod.default_turns,
repetitions=self.test_repetitions)

work_queue = Queue()
Expand All @@ -391,7 +391,7 @@ def test_build_result_set(self):
name=self.test_name,
players=self.players,
game=self.game,
turns=200,
turns=axelrod.default_turns,
repetitions=self.test_repetitions)
results = tournament.play(progress_bar=False)
self.assertIsInstance(results, axelrod.ResultSet)
Expand All @@ -405,7 +405,7 @@ def test_no_build_result_set(self):
name=self.test_name,
players=self.players,
game=self.game,
turns=200,
turns=axelrod.default_turns,
repetitions=self.test_repetitions)

results = tournament.play(build_results=False, filename=self.filename,
Expand All @@ -418,7 +418,7 @@ def test_no_build_result_set(self):

@given(turns=integers(min_value=1, max_value=200))
@example(turns=3)
@example(turns=200)
@example(turns=axelrod.default_turns)
def test_play_matches(self, turns):
tournament = axelrod.Tournament(name=self.test_name,
players=self.players,
Expand Down
4 changes: 2 additions & 2 deletions axelrod/tournament.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

import tqdm

from axelrod import on_windows
from axelrod import on_windows, default_turns
from axelrod.player import Player
from .game import Game
from .match import Match
Expand Down Expand Up @@ -57,7 +57,7 @@ def __init__(self, players: List[Player],
self.edges = edges

if turns is None and prob_end is None:
turns = 200
turns = default_turns

self.turns = turns
self.prob_end = prob_end
Expand Down
6 changes: 0 additions & 6 deletions docs/tutorials/advanced/using_the_cache.rst
Original file line number Diff line number Diff line change
Expand Up @@ -87,9 +87,3 @@ particular number will depend on the stochastic behaviour of the Moran process::

>>> len(cache) # doctest: +SKIP
18

Although, in this case the length of matches are not all the same (the default
match length in the Moran process is 100)::

>>> list(set([length for p1, p2, length in cache.keys()]))
[200, 100]
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ To create a graph-based Moran process, use a graph as follows::
>>> mp = axl.MoranProcessGraph(players, interaction_graph=graph)
>>> results = mp.play()
>>> mp.population_distribution()
Counter({'Cooperator': 4})
Counter({'Defector': 4})

You can supply the `reproduction_graph` as a keyword argument. The standard Moran
process is equivalent to using a complete graph for both graphs.
47 changes: 28 additions & 19 deletions docs/tutorials/getting_started/moran.rst
Original file line number Diff line number Diff line change
Expand Up @@ -28,40 +28,49 @@ the library, proceed as follows::
>>> mp = axl.MoranProcess(players)
>>> populations = mp.play()
>>> mp.winning_strategy_name
'Grudger'
'Cooperator'

You can access some attributes of the process, such as the number of rounds::

>>> len(mp)
14
18

The sequence of populations::

>>> import pprint
>>> pprint.pprint(populations) # doctest: +SKIP
[Counter({'Grudger': 1, 'Cooperator': 1, 'Defector': 1, 'Tit For Tat': 1}),
Counter({'Grudger': 1, 'Cooperator': 1, 'Defector': 1, 'Tit For Tat': 1}),
Counter({'Grudger': 1, 'Cooperator': 1, 'Defector': 1, 'Tit For Tat': 1}),
Counter({'Tit For Tat': 2, 'Grudger': 1, 'Cooperator': 1}),
[Counter({'Cooperator': 1, 'Defector': 1, 'Tit For Tat': 1, 'Grudger': 1}),
Counter({'Grudger': 2, 'Cooperator': 1, 'Tit For Tat': 1}),
Counter({'Grudger': 3, 'Cooperator': 1}),
Counter({'Grudger': 3, 'Cooperator': 1}),
Counter({'Grudger': 3, 'Cooperator': 1}),
Counter({'Grudger': 3, 'Cooperator': 1}),
Counter({'Grudger': 3, 'Cooperator': 1}),
Counter({'Grudger': 3, 'Cooperator': 1}),
Counter({'Grudger': 3, 'Cooperator': 1}),
Counter({'Grudger': 3, 'Cooperator': 1}),
Counter({'Grudger': 4})]
Counter({'Tit For Tat': 2, 'Cooperator': 1, 'Grudger': 1}),
Counter({'Grudger': 2, 'Cooperator': 1, 'Tit For Tat': 1}),
Counter({'Tit For Tat': 2, 'Cooperator': 1, 'Grudger': 1}),
Counter({'Tit For Tat': 3, 'Cooperator': 1}),
Counter({'Cooperator': 2, 'Tit For Tat': 2}),
Counter({'Cooperator': 3, 'Tit For Tat': 1}),
Counter({'Cooperator': 3, 'Tit For Tat': 1}),
Counter({'Cooperator': 3, 'Tit For Tat': 1}),
Counter({'Cooperator': 3, 'Tit For Tat': 1}),
Counter({'Cooperator': 3, 'Tit For Tat': 1}),
Counter({'Cooperator': 3, 'Tit For Tat': 1}),
Counter({'Cooperator': 3, 'Tit For Tat': 1}),
Counter({'Cooperator': 3, 'Tit For Tat': 1}),
Counter({'Cooperator': 3, 'Tit For Tat': 1}),
Counter({'Cooperator': 3, 'Tit For Tat': 1}),
Counter({'Cooperator': 4})]



The scores in each round::

>>> for row in mp.score_history:
... print([round(element, 1) for element in row])
[6.0, 7.1, 7.0, 7.0]
[6.0, 7.1, 7.0, 7.0]
[6.0, 7.1, 7.0, 7.0]
[6.0, 7.0, 7.0, 7.0]
[9.0, 9.0, 9.0, 9.0]
[9.0, 9.0, 9.0, 9.0]
[9.0, 9.0, 9.0, 9.0]
[9.0, 9.0, 9.0, 9.0]
[9.0, 9.0, 9.0, 9.0]
[9.0, 9.0, 9.0, 9.0]
[9.0, 9.0, 9.0, 9.0]
[9.0, 9.0, 9.0, 9.0]
[9.0, 9.0, 9.0, 9.0]
Expand All @@ -88,7 +97,7 @@ function like :code:`takewhile` from :code:`itertools`)::
... if len(mp.population_distribution()) == 1:
... break
>>> mp.population_distribution()
Counter({'Cooperator': 4})
Counter({'Grudger': 4})

Other types of implemented Moran processes:

Expand Down

0 comments on commit 4ce4098

Please sign in to comment.