Skip to content

Commit 0f30f65

Browse files
zewaywongdrvinceknight
authored andcommitted
Documentation for custom heterogeneous matches
1 parent 68a1f06 commit 0f30f65

File tree

2 files changed

+66
-0
lines changed

2 files changed

+66
-0
lines changed

docs/how-to/heterogeneous_matches.rst

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
.. _heterogeneous-matches:
2+
3+
Heterogeneous Matches
4+
=====================
5+
6+
Axelrod Matches are homogeneous by nature but can be extended to utilize additional attributes of heterogeneous players.
7+
This tutorial indicates how the Axelrod :code:`Match` class can be manipulated in order to play heterogeneous tournaments and Moran processes using country mass as a score modifier.
8+
9+
The following lines of code creates a list of players from the available demo strategies along with an ascending list of values we will use for the players::
10+
11+
>>> import axelrod as axl
12+
>>> players = [player() for player in axl.demo_strategies]
13+
>>> masses = [1 * i for i in range(len(players))]
14+
>>> players
15+
[Cooperator, Defector, Tit For Tat, Grudger, Random: 0.5]
16+
17+
Using the :code:`setattr()` method, additional attributes can be passed to players to enable access during matches and tournaments without manual modification of individual strategies::
18+
19+
>>> def set_player_mass(players, masses):
20+
>>> """Add mass attribute to player strategy classes to be accessable via self.mass"""
21+
>>> for player, mass in zip(players, masses):
22+
>>> setattr(player, "mass", mass)
23+
>>>
24+
>>> set_player_mass(players, masses)
25+
26+
The :code:`Match` class can be partially altered to enable different behaviour. Here we extend :code:`axl.Match` and overwrite its :code:`final_score_per_turn()`
27+
function to utilize the player mass attribute als a multiplier for the final score::
28+
29+
>>> class MassBaseMatch(axl.Match):
30+
>>> """Axelrod Match object with a modified final score function to enable mass to influence the final score as a multiplier"""
31+
>>> def final_score_per_turn(self):
32+
>>> base_scores = axl.Match.final_score_per_turn(self)
33+
>>> return [player.mass * score for player, score in zip(self.players, base_scores)]
34+
35+
We can now create a tournament like we normally would and pass our custom :code:`MassBaseMatch` to the tournament with the :code:`match_class` keyword argument::
36+
37+
>>> tournament = axl.Tournament(players=players, match_class=MassBaseMatch)
38+
>>> results = tournament.play()
39+
>>> print(results.ranked_names)
40+
['Defector', 'Grudger', 'Tit For Tat', 'Cooperator', 'Random: 0.5']
41+
42+
Additionally, Moran Processes can also be altered to incorporate heterogeneous matches. In order to
43+
use our previously defined :code:`MassBaseMatch`, we require one additional change to the :code:`MoranProcess` class::
44+
45+
>>> class MassBasedMoranProcess(axl.MoranProcess):
46+
>>> """Axelrod MoranProcess class """
47+
>>> def __next__(self):
48+
>>> set_player_mass(self.players, masses)
49+
>>> super().__next__()
50+
>>> return self
51+
52+
With this code snippet we can override the :code:`__next__()` call within the MoranProcess to include :code:`set_player_mass()`
53+
every round. This ensures that every player has mass attributes after the Moran process is triggered.
54+
Subsequently, with :code:`super().__next__()` the base MoranProcess :code:`__next__()` call is triggered. This method enables quick
55+
modifications to tournaments and moran processes with minimal repetitive code.
56+
57+
We can now create a Moran process as we normally would, with the inclusion of the match class as a keyword argument::
58+
59+
>>> mp = MassBasedMoranProcess(players, match_class=MassBaseMatch)
60+
>>> mp.play()
61+
>>> print(mp.winning_strategy_name)
62+
Grudger
63+
64+
Note that the snippets here only influence the final score of matches. The behavior of matches, tournaments and moran
65+
processes can be more heavily influenced by partially overwriting other :code:`match` functions or :code:`birth` and :code:`death` functions within :code:`MoranProcess`.

docs/how-to/index.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,5 +27,6 @@ with the Axelrod library.
2727
set_a_seed.rst
2828
set_player_information.rst
2929
check_player_equality.rst
30+
heterogeneous_matches.rst
3031
cite_the_library.rst
3132
contributing/index.rst

0 commit comments

Comments
 (0)