Skip to content

Commit 95698d8

Browse files
committed
Modify the documentation.
1 parent dce16c4 commit 95698d8

File tree

4 files changed

+89
-0
lines changed

4 files changed

+89
-0
lines changed

docs/how-to/index.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ with the Axelrod library.
2424
use_parallel_processing.rst
2525
use_a_cache.rst
2626
use_different_stage_games.rst
27+
use_custom_matches.rst
2728
set_a_seed.rst
2829
set_player_information.rst
2930
check_player_equality.rst

docs/how-to/use_custom_matches.rst

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
.. _use-custom-matches:
2+
3+
Use custom matches
4+
==================
5+
6+
At present it is possible to use a custom match class in a Moran process. Below
7+
creates a new class of a match where both players end with a score of 2::
8+
9+
10+
>>> import axelrod as axl
11+
>>> class MassBaseMatch(axl.Match):
12+
... """Axelrod Match object with a modified final score function to enable mass to influence the final score as a multiplier"""
13+
... def final_score_per_turn(self):
14+
... return 2, 2
15+
16+
We can now create a Moran process like we normally would and pass our custom :code:`MassBaseMatch` to the moran process with the :code:`match_class` keyword argument::
17+
18+
>>> players = [axl.Cooperator(), axl.Defector(), axl.TitForTat(), axl.Grudger()]
19+
>>> mp = axl.MoranProcess(players=players, match_class=MassBaseMatch, seed=0)
20+
>>> population = mp.play()
21+
>>> print(mp.winning_strategy_name)
22+
Defector
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
.. _create-heterogeneous-moran-processes:
2+
3+
Create heterogeneous Moran Processes
4+
====================================
5+
6+
Axelrod Matches are homogeneous by nature but can be extended to utilize
7+
additional attributes of heterogeneous players. This tutorial indicates how the
8+
Axelrod :code:`Match` class can be manipulated in order to play heterogeneous
9+
tournaments and Moran processes using mass as a score modifier similarly to the
10+
work of [Krapohl2020]_.
11+
12+
The following lines of code creates a list of players from the available demo
13+
strategies along with an ascending list of masses we will use for the players.
14+
This is equivalent in principle to the country masses discussed in
15+
[Krapohl2020]_::
16+
17+
>>> import axelrod as axl
18+
>>> players = [player() for player in axl.demo_strategies]
19+
>>> masses = [1 * i for i in range(len(players))]
20+
>>> players
21+
[Cooperator, Defector, Tit For Tat, Grudger, Random: 0.5]
22+
23+
Using the :code:`setattr()` function, additional attributes can be passed to
24+
players to enable access during matches and tournaments without manual
25+
modification of individual strategies::
26+
27+
>>> def set_player_mass(players, masses):
28+
... """Add mass attribute to player strategy classes to be accessable via self.mass"""
29+
... for player, mass in zip(players, masses):
30+
... setattr(player, "mass", mass)
31+
...
32+
>>> set_player_mass(players, masses)
33+
34+
The :code:`Match` class can be partially altered to enable different behaviour
35+
(see :ref:`use-custom-matches`_).
36+
Here we extend :code:`axl.Match` and overwrite its
37+
:code:`final_score_per_turn()` function to utilize the player mass attribute as
38+
a multiplier for the final score::
39+
40+
>>> class MassBaseMatch(axl.Match):
41+
... """Axelrod Match object with a modified final score function to enable mass to influence the final score as a multiplier"""
42+
... def final_score_per_turn(self):
43+
... base_scores = axl.Match.final_score_per_turn(self)
44+
... return [player.mass * score for player, score in zip(self.players, base_scores)]
45+
46+
In [Krapohl2020]_ a non standard Moran process is used where the mass of
47+
individuals is not reproduced so we will use inheritance to create a new Moran
48+
process that keeps the mass of the individuals constant::
49+
50+
>>> class MassBasedMoranProcess(axl.MoranProcess):
51+
... """Axelrod MoranProcess class """
52+
... def __next__(self):
53+
... set_player_mass(self.players, masses)
54+
... super().__next__()
55+
... return self
56+
57+
>>> mp = MassBasedMoranProcess(players, match_class=MassBaseMatch, seed=0)
58+
>>> populations = mp.play()
59+
>>> print(mp.winning_strategy_name)
60+
Random: 0.5
61+
62+
Note that the snippets here only influence the final score of matches. The
63+
behavior of matches, and moran processes can be more heavily influenced by
64+
partially overwriting other :code:`match` functions or :code:`birth` and
65+
:code:`death` functions within :code:`MoranProcess`.

docs/tutorials/index.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,3 +12,4 @@ Contents:
1212

1313
new_to_game_theory_and_or_python/index.rst
1414
running_axelrods_first_tournament/index.rst
15+
creating_heterogenous_player_moran_process/index.rst

0 commit comments

Comments
 (0)