1
1
"""
2
2
A module for creating hypothesis based strategies for property based testing
3
3
"""
4
- import axelrod
4
+ from axelrod import (strategies , Match , Game ,
5
+ Tournament , ProbEndTournament ,
6
+ SpatialTournament , ProbEndSpatialTournament )
5
7
from hypothesis .strategies import (composite , sampled_from , integers ,
6
8
floats , lists )
7
9
10
+ import itertools
11
+
8
12
9
13
@composite
10
- def strategy_lists (draw , strategies = axelrod . strategies , min_size = 1 ,
11
- max_size = len (axelrod . strategies )):
14
+ def strategy_lists (draw , strategies = strategies , min_size = 1 ,
15
+ max_size = len (strategies )):
12
16
"""
13
17
A hypothesis decorator to return a list of strategies
14
18
@@ -23,13 +27,13 @@ def strategy_lists(draw, strategies=axelrod.strategies, min_size=1,
23
27
max_size = max_size ))
24
28
return strategies
25
29
30
+
26
31
@composite
27
- def matches (draw , strategies = axelrod . strategies ,
32
+ def matches (draw , strategies = strategies ,
28
33
min_turns = 1 , max_turns = 200 ,
29
34
min_noise = 0 , max_noise = 1 ):
30
35
"""
31
- A hypothesis decorator to return a random match as well as a random seed (to
32
- ensure reproducibility when instance of class need the random library).
36
+ A hypothesis decorator to return a random match.
33
37
34
38
Parameters
35
39
----------
@@ -52,20 +56,18 @@ def matches(draw, strategies=axelrod.strategies,
52
56
players = [s () for s in strategies ]
53
57
turns = draw (integers (min_value = min_turns , max_value = max_turns ))
54
58
noise = draw (floats (min_value = min_noise , max_value = max_noise ))
55
- match = axelrod . Match (players , turns = turns , noise = noise )
59
+ match = Match (players , turns = turns , noise = noise )
56
60
return match
57
61
58
62
59
63
@composite
60
- def tournaments (draw , strategies = axelrod . strategies ,
64
+ def tournaments (draw , strategies = strategies ,
61
65
min_size = 1 , max_size = 10 ,
62
66
min_turns = 1 , max_turns = 200 ,
63
67
min_noise = 0 , max_noise = 1 ,
64
68
min_repetitions = 1 , max_repetitions = 20 ):
65
69
"""
66
- A hypothesis decorator to return a tournament and a random seed (to ensure
67
- reproducibility for strategies that make use of the random module when
68
- initiating).
70
+ A hypothesis decorator to return a tournament.
69
71
70
72
Parameters
71
73
----------
@@ -95,21 +97,119 @@ def tournaments(draw, strategies=axelrod.strategies,
95
97
max_value = max_repetitions ))
96
98
noise = draw (floats (min_value = min_noise , max_value = max_noise ))
97
99
98
- tournament = axelrod . Tournament (players , turns = turns ,
99
- repetitions = repetitions , noise = noise )
100
+ tournament = Tournament (players , turns = turns , repetitions = repetitions ,
101
+ noise = noise )
100
102
return tournament
101
103
102
104
103
105
@composite
104
- def prob_end_tournaments (draw , strategies = axelrod .strategies ,
106
+ def prob_end_tournaments (draw , strategies = strategies ,
107
+ min_size = 1 , max_size = 10 ,
108
+ min_prob_end = 0 , max_prob_end = 1 ,
109
+ min_noise = 0 , max_noise = 1 ,
110
+ min_repetitions = 1 , max_repetitions = 20 ):
111
+ """
112
+ A hypothesis decorator to return a tournament,
113
+
114
+ Parameters
115
+ ----------
116
+ min_size : integer
117
+ The minimum number of strategies to include
118
+ max_size : integer
119
+ The maximum number of strategies to include
120
+ min_prob_end : float
121
+ The minimum probability of a match ending
122
+ max_prob_end : float
123
+ The maximum probability of a match ending
124
+ min_noise : float
125
+ The minimum noise value
126
+ max_noise : float
127
+ The maximum noise value
128
+ min_repetitions : integer
129
+ The minimum number of repetitions
130
+ max_repetitions : integer
131
+ The maximum number of repetitions
132
+ """
133
+ strategies = draw (strategy_lists (strategies = strategies ,
134
+ min_size = min_size ,
135
+ max_size = max_size ))
136
+ players = [s () for s in strategies ]
137
+ prob_end = draw (floats (min_value = min_prob_end , max_value = max_prob_end ))
138
+ repetitions = draw (integers (min_value = min_repetitions ,
139
+ max_value = max_repetitions ))
140
+ noise = draw (floats (min_value = min_noise , max_value = max_noise ))
141
+
142
+ tournament = ProbEndTournament (players , prob_end = prob_end ,
143
+ repetitions = repetitions , noise = noise )
144
+ return tournament
145
+
146
+
147
+ @composite
148
+ def spatial_tournaments (draw , strategies = strategies ,
105
149
min_size = 1 , max_size = 10 ,
106
- min_prob_end = 0 , max_prob_end = 1 ,
150
+ min_turns = 1 , max_turns = 200 ,
107
151
min_noise = 0 , max_noise = 1 ,
108
152
min_repetitions = 1 , max_repetitions = 20 ):
109
153
"""
110
- A hypothesis decorator to return a tournament and a random seed (to ensure
111
- reproducibility for strategies that make use of the random module when
112
- initiating).
154
+ A hypothesis decorator to return a spatial tournament.
155
+
156
+ Parameters
157
+ ----------
158
+ min_size : integer
159
+ The minimum number of strategies to include
160
+ max_size : integer
161
+ The maximum number of strategies to include
162
+ min_turns : integer
163
+ The minimum number of turns
164
+ max_turns : integer
165
+ The maximum number of turns
166
+ min_noise : float
167
+ The minimum noise value
168
+ max_noise : float
169
+ The maximum noise value
170
+ min_repetitions : integer
171
+ The minimum number of repetitions
172
+ max_repetitions : integer
173
+ The maximum number of repetitions
174
+ """
175
+ strategies = draw (strategy_lists (strategies = strategies ,
176
+ min_size = min_size ,
177
+ max_size = max_size ))
178
+ players = [s () for s in strategies ]
179
+ player_indices = list (range (len (players )))
180
+
181
+ all_potential_edges = list (itertools .combinations (player_indices , 2 ))
182
+ all_potential_edges .extend ([(i , i ) for i in player_indices ]) # Loops
183
+ edges = draw (lists (sampled_from (all_potential_edges ), unique = True ,
184
+ average_size = 2 * len (players )))
185
+
186
+ # Ensure all players/nodes are connected:
187
+ node_indices = sorted (set ([node for edge in edges for node in edge ]))
188
+ missing_nodes = [index
189
+ for index in player_indices if index not in node_indices ]
190
+ for index in missing_nodes :
191
+ opponent = draw (sampled_from (player_indices ))
192
+ edges .append ((index , opponent ))
193
+
194
+ turns = draw (integers (min_value = min_turns , max_value = max_turns ))
195
+ repetitions = draw (integers (min_value = min_repetitions ,
196
+ max_value = max_repetitions ))
197
+ noise = draw (floats (min_value = min_noise , max_value = max_noise ))
198
+
199
+ tournament = SpatialTournament (players , turns = turns ,
200
+ repetitions = repetitions , noise = noise ,
201
+ edges = edges )
202
+ return tournament
203
+
204
+
205
+ @composite
206
+ def prob_end_spatial_tournaments (draw , strategies = strategies ,
207
+ min_size = 1 , max_size = 10 ,
208
+ min_prob_end = 0 , max_prob_end = 1 ,
209
+ min_noise = 0 , max_noise = 1 ,
210
+ min_repetitions = 1 , max_repetitions = 20 ):
211
+ """
212
+ A hypothesis decorator to return a probabilistic ending spatial tournament.
113
213
114
214
Parameters
115
215
----------
@@ -123,7 +223,7 @@ def prob_end_tournaments(draw, strategies=axelrod.strategies,
123
223
The maximum probability of a match ending
124
224
min_noise : float
125
225
The minimum noise value
126
- min_noise : float
226
+ max_noise : float
127
227
The maximum noise value
128
228
min_repetitions : integer
129
229
The minimum number of repetitions
@@ -134,13 +234,29 @@ def prob_end_tournaments(draw, strategies=axelrod.strategies,
134
234
min_size = min_size ,
135
235
max_size = max_size ))
136
236
players = [s () for s in strategies ]
237
+ player_indices = list (range (len (players )))
238
+
239
+ all_potential_edges = list (itertools .combinations (player_indices , 2 ))
240
+ all_potential_edges .extend ([(i , i ) for i in player_indices ]) # Loops
241
+ edges = draw (lists (sampled_from (all_potential_edges ), unique = True ,
242
+ average_size = 2 * len (players )))
243
+
244
+ # Ensure all players/nodes are connected:
245
+ node_indices = sorted (set ([node for edge in edges for node in edge ]))
246
+ missing_nodes = [index
247
+ for index in player_indices if index not in node_indices ]
248
+ for index in missing_nodes :
249
+ opponent = draw (sampled_from (player_indices ))
250
+ edges .append ((index , opponent ))
251
+
137
252
prob_end = draw (floats (min_value = min_prob_end , max_value = max_prob_end ))
138
253
repetitions = draw (integers (min_value = min_repetitions ,
139
254
max_value = max_repetitions ))
140
255
noise = draw (floats (min_value = min_noise , max_value = max_noise ))
141
256
142
- tournament = axelrod .ProbEndTournament (players , prob_end = prob_end ,
143
- repetitions = repetitions , noise = noise )
257
+ tournament = ProbEndSpatialTournament (players , prob_end = prob_end ,
258
+ repetitions = repetitions ,
259
+ noise = noise , edges = edges )
144
260
return tournament
145
261
146
262
@@ -178,5 +294,5 @@ def games(draw, prisoners_dilemma=True, max_value=100):
178
294
r = draw (integers (max_value = max_value ))
179
295
p = draw (integers (max_value = max_value ))
180
296
181
- game = axelrod . Game (r = r , s = s , t = t , p = p )
297
+ game = Game (r = r , s = s , t = t , p = p )
182
298
return game
0 commit comments