Skip to content

Commit 06e898b

Browse files
committed
Merge pull request #410 from Axelrod-Python/284
More refactoring of payoff.py and cooperation.py
2 parents 588b5a0 + 9c19be4 commit 06e898b

File tree

3 files changed

+69
-30
lines changed

3 files changed

+69
-30
lines changed

axelrod/cooperation.py

Lines changed: 2 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
from math import sqrt
22
from . import eigen
33
from axelrod import Actions
4+
from axelrod.payoff import player_count
45

56
C, D = Actions.C, Actions.D
67

@@ -48,31 +49,7 @@ def cooperation_matrix(interactions):
4849
and column (j) represents an individual player and the the value Cij
4950
is the number of times player i cooperated against opponent j.
5051
"""
51-
52-
# The number of ways (c) to select groups of r members from a set of n
53-
# members is given by:
54-
#
55-
# c = n! / r!(n - r)!
56-
#
57-
# In this case, we are selecting pairs of players (p) and thus r = 2,
58-
# giving:
59-
#
60-
# p = n(n-1) / 2 or p = (n^2 - n) / 2
61-
#
62-
# However, we also have the case where each player plays itself gving:
63-
#
64-
# p = (n^2 + n) / 2
65-
#
66-
# Using the quadratic equation to rearrange for n gives:
67-
#
68-
# n = (-1 +- sqrt(1 + 8p)) / 2
69-
#
70-
# Taking only the real roots allows us to derive the number of players
71-
# given the number of pairs:
72-
#
73-
# n = (sqrt(8p + 1) -1) / 2
74-
75-
nplayers = int((sqrt(len(interactions) * 8 + 1) - 1) / 2)
52+
nplayers = player_count(interactions)
7653
cooperation = [[0 for i in range(nplayers)] for j in range(nplayers)]
7754
for players, actions in interactions.items():
7855
p1_actions, p2_actions = zip(*actions)

axelrod/payoff.py

Lines changed: 57 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,63 @@
55
C, D = Actions.C, Actions.D
66

77

8+
def player_count(interactions):
9+
"""
10+
The number of players derived from a dictionary of interactions
11+
12+
Parameters
13+
----------
14+
interactions : dictionary
15+
A dictionary of the form:
16+
17+
e.g. for a round robin between Cooperator, Defector and Alternator
18+
with 2 turns per round:
19+
{
20+
(0, 0): [(C, C), (C, C)].
21+
(0, 1): [(C, D), (C, D)],
22+
(0, 2): [(C, C), (C, D)],
23+
(1, 1): [(D, D), (D, D)],
24+
(1, 2): [(D, C), (D, D)],
25+
(2, 2): [(C, C), (D, D)]
26+
}
27+
28+
i.e. the key is a pair of player index numbers and the value, a list of
29+
plays. The list contains one pair per turn in the round robin.
30+
The dictionary contains one entry for each combination of players.
31+
32+
Returns
33+
-------
34+
nplayers : integer
35+
The number of players in the round robin
36+
37+
The number of ways (c) to select groups of r members from a set of n
38+
members is given by:
39+
40+
c = n! / r!(n - r)!
41+
42+
In this case, we are selecting pairs of players (p) and thus r = 2,
43+
giving:
44+
45+
p = n(n-1) / 2 or p = (n^2 - n) / 2
46+
47+
However, we also have the case where each player plays itself gving:
48+
49+
p = (n^2 + n) / 2
50+
51+
Using the quadratic equation to rearrange for n gives:
52+
53+
n = (-1 +- sqrt(1 + 8p)) / 2
54+
55+
Taking only the real roots allows us to derive the number of players
56+
given the number of pairs:
57+
58+
n = (sqrt(8p + 1) -1) / 2
59+
"""
60+
return int((math.sqrt(len(interactions) * 8 + 1) - 1) / 2)
61+
62+
863
# As yet unused until RoundRobin returns interactions
9-
def payoff_matrix(interactions, nplayers, game):
64+
def payoff_matrix(interactions, game):
1065
"""
1166
The payoff matrix from a single round robin.
1267
@@ -50,6 +105,7 @@ def payoff_matrix(interactions, nplayers, game):
50105
and column (j) represents an individual player and the the value Pij
51106
is the payoff value for player (i) versus player (j).
52107
"""
108+
nplayers = player_count(interactions)
53109
payoffs = [[0 for i in range(nplayers)] for j in range(nplayers)]
54110
for players, actions in interactions.items():
55111
payoff = interaction_payoff(actions, game)

axelrod/tests/unit/test_payoff.py

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -63,9 +63,9 @@ def setUpClass(cls):
6363
cls.expected_wins = [[2, 0], [0, 0], [0, 2]]
6464

6565
cls.diff_means = [
66-
[ 0. , 0. , 0.5],
67-
[ 0. , 0. , -0.5],
68-
[-0.5, 0.5, 0. ]
66+
[0.0, 0.0, 0.5],
67+
[0.0, 0.0, -0.5],
68+
[-0.5, 0.5, 0.0]
6969
]
7070

7171
cls.expected_score_diffs = [
@@ -74,8 +74,14 @@ def setUpClass(cls):
7474
[-1.0, 0.0, 0.0, 1.0, 0.0, 0.0]
7575
]
7676

77+
def test_player_count(self):
78+
nplayers = ap.player_count(self.interactions)
79+
self.assertEqual(nplayers, 3)
80+
nplayers = ap.player_count({'test': 'test'})
81+
self.assertEqual(nplayers, 1)
82+
7783
def test_payoff_matrix(self):
78-
payoff_matrix = ap.payoff_matrix(self.interactions, 3, Game())
84+
payoff_matrix = ap.payoff_matrix(self.interactions, Game())
7985
self.assertEqual(payoff_matrix, self.expected_payoff_matrix)
8086

8187
def test_interaction_payoff(self):

0 commit comments

Comments
 (0)