Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
58 changes: 58 additions & 0 deletions axelrod/result_set.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ def __init__(self, players, turns, repetitions, outcome,
self.ranking = None
self.ranked_names = None
self.payoff_matrix = None
self.wins = None
self.cooperation = None
self.normalised_cooperation = None
self.vengeful_cooperation = None
Expand All @@ -61,6 +62,7 @@ def __init__(self, players, turns, repetitions, outcome,
self.ranked_names = self._ranked_names(self.ranking)
self.payoff_matrix, self.payoff_stddevs = (
self._payoff_matrix(self.results['payoff']))
self.wins = self._wins(self.results['payoff'])
if 'cooperation' in self.results and with_morality:
self.cooperation = self._cooperation(self.results['cooperation'])
self.normalised_cooperation = (
Expand Down Expand Up @@ -250,6 +252,62 @@ def _payoff_matrix(self, payoff):
stddevs[-1].append(dev)
return averages, stddevs

def _wins(self, payoff):
"""
Args:
payoff (list): a matrix of the form:

[
[[a, j], [b, k], [c, l]],
[[d, m], [e, n], [f, o]],
[[g, p], [h, q], [i, r]],
]

i.e. one row per player, containing one element per opponent (in
order of player index) which lists payoffs for each repetition.

Returns:
A wins matrix of the form:

[
[player1 wins in repetition1, player1 wins in repetition2],
[player2 wins in repetition1, player2 wins in repetition2],
[player3 wins in repetition1, player3 wins in repetition2],
]

i.e. one row per player which lists the total wins for that player
in each repetition.
"""
wins = [
[0 for r in range(self.repetitions)] for p in range(self.nplayers)]
for player in range(self.nplayers):
for opponent in range(self.nplayers):
players = (player, opponent)
for repetition in range(self.repetitions):
payoffs = (
payoff[player][opponent][repetition],
payoff[opponent][player][repetition])
winner = self._winner(players, payoffs)
if winner is not None:
wins[winner][repetition] += 1
return wins

def _winner(self, players, payoffs):
"""
Args:
players (tuple): A tuple of player indexes
payoffs (tuple): A tuple of payoffs for the two players
Returns:
The index of the winning player or None if a draw
"""
if payoffs[0] == payoffs[1]:
return None
else:
winning_payoff = max(payoffs)
winning_payoff_index = payoffs.index(winning_payoff)
winner = players[winning_payoff_index]
return winner

def _cooperation(self, results):
"""
Args:
Expand Down
19 changes: 19 additions & 0 deletions axelrod/tests/unit/test_resultset.py
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ def setUpClass(cls):
]
cls.expected_ranking = [0, 2, 1]
cls.expected_ranked_names = ['Alternator', 'Random', 'TitForTat']
cls.expected_wins = [[2, 0], [0, 0], [0, 2]]
cls.expected_cooperation = [
[6, 6, 6],
[6, 10, 6],
Expand Down Expand Up @@ -154,6 +155,24 @@ def test_payoff_matrix(self):
self.assertEqual(self.round_matrix(
rs.payoff_stddevs, 2), self.expected_stddevs)

def test_wins(self):
rs = axelrod.ResultSet(self.players, 5, 2, self.test_outcome)
wins = rs.wins
self.assertEqual(wins, self.expected_wins)

def test_winner(self):
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would a docstring here be helpful? I'm just glancing and not immediately sure what's happening.

rs = axelrod.ResultSet(self.players, 5, 2, self.test_outcome)
test_players = (8, 4)
test_payoffs = (34, 44)
winner = rs._winner(test_players, test_payoffs)
self.assertEqual(winner, 4)
test_payoffs = (54, 44)
winner = rs._winner(test_players, test_payoffs)
self.assertEqual(winner, 8)
test_payoffs = (34, 34)
winner = rs._winner(test_players, test_payoffs)
self.assertEqual(winner, None)

def test_cooperation(self):
rs = axelrod.ResultSet(self.players, 5, 2, self.test_outcome)
self.assertEqual(
Expand Down
21 changes: 20 additions & 1 deletion docs/usage.rst
Original file line number Diff line number Diff line change
Expand Up @@ -257,7 +257,6 @@ this is shown here:
:width: 50%
:align: center


As an aside we can use this matrix with `gambit <http://gambit.sourceforge.net/>`_ or `sagemath <http://sagemath.org/>`_ to compute the Nash equilibria for the corresponding normal form game. Here is how to do this in Sage::

# This is not part of the Axelrod module (run in Sage)
Expand All @@ -284,6 +283,26 @@ Recall the ordering of the players::

Thus we see that there are multiple Nash equilibria for this game. Two pure equilibria that involve both players playing :code:`Defector` and both players playing :code:`TitForTat`.

The ResultSet object also includes the 'wins' attribute, which is derived from the payoff matrix and lists the number of wins for each player::

import axelrod
strategies = [s() for s in axelrod.demo_strategies]
tournament = axelrod.Tournament(strategies)
results = tournament.play()
results.wins

The resulting wins matrix is::

[
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[8, 8, 8, 8, 8, 8, 8, 8, 8, 8],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[2, 2, 2, 2, 2, 2, 2, 2, 2, 2],
[4, 2, 2, 2, 4, 4, 4, 4, 4, 4]
]

which shows, for example, that Cooperator had 0 wins, Defector won 8 times in each repetition and Random won 4 times in the first repetition and twice in the second.

Noisy Tournaments
^^^^^^^^^^^^^^^^^

Expand Down