1
1
"""Tests DBS strategy."""
2
2
3
- import axelrod
4
3
import unittest
5
- from . test_player import TestPlayer
4
+ import axelrod
6
5
from axelrod .strategies import dbs
6
+ from .test_player import TestPlayer
7
7
8
8
C , D = axelrod .Actions .C , axelrod .Actions .D
9
9
10
10
11
11
class TestNode (unittest .TestCase ):
12
- """
13
- Test for the base class
14
- """
12
+ """Test for the base Node class."""
15
13
node = dbs .Node ()
16
14
17
15
def test_get_siblings (self ):
@@ -25,21 +23,18 @@ def test_is_stochastic(self):
25
23
26
24
class TestTreeSearch (unittest .TestCase ):
27
25
"""
28
- A set of tests for the tree-search functions.
29
- We test the answers of both minimax_tree_search and move_gen
30
- functions, against a set of classic policies (the answer being the
31
- best move to play for the next turn, considering an income
32
- position (C, C), (C, D), (D, C) or (D, D))
33
- For each policy, we test the answer for all income position
26
+ A set of tests for the tree-search functions. We test the answers of both
27
+ minimax_tree_search and move_gen functions, against a set of classic
28
+ policies (the answer being the best move to play for the next turn,
29
+ considering an incoming position (C, C), (C, D), (D, C) or (D, D)).
30
+ For each policy, we test the answer for all incoming position.
34
31
"""
35
32
def setUp (self ):
36
- """
37
- Initialization for tests.
38
- """
33
+ """Initialization for tests."""
39
34
# For each test, we check the answer against each possible
40
- # inputs, that are in self.input_pos
35
+ # inputs, that are in self.input_pos.
41
36
self .input_pos = [(C , C ), (C , D ), (D , C ), (D , D )]
42
- # We define the policies against which we are going to test
37
+ # We define the policies against which we are going to test.
43
38
self .cooperator_policy = dbs .create_policy (1 , 1 , 1 , 1 )
44
39
self .defector_policy = dbs .create_policy (0 , 0 , 0 , 0 )
45
40
self .titForTat_policy = dbs .create_policy (1 , 1 , 0 , 0 )
@@ -50,159 +45,149 @@ def setUp(self):
50
45
def test_minimaxTreeSearch_cooperator (self ):
51
46
"""
52
47
Tests the minimax_tree_search function when playing against a
53
- Cooperator player.
54
- Output == 0 means Cooperate, 1 means Defect.
48
+ Cooperator player. Output == 0 means Cooperate, 1 means Defect.
55
49
The best (hence expected) answer to Cooperator is to defect
56
50
whatever the input position is.
57
51
"""
58
52
expected_output = [1 , 1 , 1 , 1 ]
59
53
for inp , out in zip (self .input_pos , expected_output ):
60
54
begin_node = dbs .DeterministicNode (inp [0 ], inp [1 ], depth = 0 )
61
- values = dbs .minimax_tree_search (begin_node ,
62
- self .cooperator_policy , max_depth = 5 )
63
- self .assertEqual (values .index (max (values )),out )
55
+ values = dbs .minimax_tree_search (
56
+ begin_node , self .cooperator_policy , max_depth = 5 )
57
+ self .assertEqual (values .index (max (values )), out )
64
58
65
59
def test_move_gen_cooperator (self ):
66
60
"""
67
- Tests the move_gen function when playing against a
68
- Cooperator player.
61
+ Tests the move_gen function when playing against a Cooperator player.
69
62
"""
70
63
expected_output = [D , D , D , D ]
71
64
for inp , out in zip (self .input_pos , expected_output ):
72
- out_move = dbs .move_gen (inp , self . cooperator_policy ,
73
- depth_search_tree = 5 )
65
+ out_move = dbs .move_gen (
66
+ inp , self . cooperator_policy , depth_search_tree = 5 )
74
67
self .assertEqual (out_move , out )
75
68
76
69
def test_minimaxTreeSearch_defector (self ):
77
70
"""
78
71
Tests the minimax_tree_search function when playing against a
79
- Defector player.
80
- The best answer to Defector is to always defect
72
+ Defector player. The best answer to Defector is to always defect
81
73
"""
82
74
expected_output = [1 , 1 , 1 , 1 ]
83
75
for inp , out in zip (self .input_pos , expected_output ):
84
76
begin_node = dbs .DeterministicNode (inp [0 ], inp [1 ], depth = 0 )
85
- values = dbs .minimax_tree_search (begin_node ,
86
- self .defector_policy , max_depth = 5 )
77
+ values = dbs .minimax_tree_search (
78
+ begin_node , self .defector_policy , max_depth = 5 )
87
79
self .assertEqual (values .index (max (values )),out )
88
80
89
81
def test_move_gen_defector (self ):
90
82
"""
91
- Tests the move_gen function when playing against a
92
- Defector player.
83
+ Tests the move_gen function when playing against a Defector player.
93
84
"""
94
85
expected_output = [D , D , D , D ]
95
86
for inp , out in zip (self .input_pos , expected_output ):
96
- out_move = dbs .move_gen (inp , self . defector_policy ,
97
- depth_search_tree = 5 )
87
+ out_move = dbs .move_gen (
88
+ inp , self . defector_policy , depth_search_tree = 5 )
98
89
self .assertEqual (out_move , out )
99
90
100
91
def test_minimaxTreeSearch_titForTat (self ):
101
92
"""
102
93
Tests the minimax_tree_search function when playing against a
103
- TitForTat player.
104
- The best (hence expected) answer to TitFOrTat is to cooperate
105
- whatever the input position is.
94
+ TitForTat player. The best (hence expected) answer to TitFOrTat is to
95
+ cooperate whatever the input position is.
106
96
"""
107
97
expected_output = [0 , 0 , 0 , 0 ]
108
98
for inp , out in zip (self .input_pos , expected_output ):
109
99
begin_node = dbs .DeterministicNode (inp [0 ], inp [1 ], depth = 0 )
110
- values = dbs .minimax_tree_search (begin_node ,
111
- self .titForTat_policy , max_depth = 5 )
100
+ values = dbs .minimax_tree_search (
101
+ begin_node , self .titForTat_policy , max_depth = 5 )
112
102
self .assertEqual (values .index (max (values )),out )
113
103
114
104
def test_last_node_titForTat (self ):
115
105
"""
116
- Test that against TitForTat, for the last move, i.e. if tree
117
- depth is 1, the algorithms defects for all input
106
+ Test that against TitForTat, for the last move, i.e. if tree depth is 1,
107
+ the algorithms defects for all input.
118
108
"""
119
109
expected_output = [1 , 1 , 1 , 1 ]
120
110
for inp , out in zip (self .input_pos , expected_output ):
121
111
begin_node = dbs .DeterministicNode (inp [0 ], inp [1 ], depth = 0 )
122
- values = dbs .minimax_tree_search (begin_node ,
123
- self .titForTat_policy , max_depth = 1 )
112
+ values = dbs .minimax_tree_search (
113
+ begin_node , self .titForTat_policy , max_depth = 1 )
124
114
self .assertEqual (values .index (max (values )),out )
125
115
126
116
def test_move_gen_titForTat (self ):
127
117
"""
128
- Tests the move_gen function when playing against a
129
- TitForTat player.
118
+ Tests the move_gen function when playing against a TitForTat player.
130
119
"""
131
120
expected_output = [C , C , C , C ]
132
121
for inp , out in zip (self .input_pos , expected_output ):
133
- out_move = dbs .move_gen (inp , self . titForTat_policy ,
134
- depth_search_tree = 5 )
122
+ out_move = dbs .move_gen (
123
+ inp , self . titForTat_policy , depth_search_tree = 5 )
135
124
self .assertEqual (out_move , out )
136
125
137
126
def test_minimaxTreeSearch_alternator (self ):
138
127
"""
139
128
Tests the minimax_tree_search function when playing against an
140
- Alternator player.
141
- The best answer to Alternator is to always defect
129
+ Alternator player. The best answer to Alternator is to always defect.
142
130
"""
143
131
expected_output = [1 , 1 , 1 , 1 ]
144
132
for inp , out in zip (self .input_pos , expected_output ):
145
133
begin_node = dbs .DeterministicNode (inp [0 ], inp [1 ], depth = 0 )
146
- values = dbs .minimax_tree_search (begin_node ,
147
- self .alternator_policy , max_depth = 5 )
134
+ values = dbs .minimax_tree_search (
135
+ begin_node , self .alternator_policy , max_depth = 5 )
148
136
self .assertEqual (values .index (max (values )),out )
149
137
150
138
def test_move_gen_alternator (self ):
151
139
"""
152
- Tests the move_gen function when playing against an
153
- Alternator player.
140
+ Tests the move_gen function when playing against an Alternator player.
154
141
"""
155
142
expected_output = [D , D , D , D ]
156
143
for inp , out in zip (self .input_pos , expected_output ):
157
- out_move = dbs .move_gen (inp , self .random_policy , depth_search_tree = 5 )
144
+ out_move = dbs .move_gen (inp , self .random_policy ,
145
+ depth_search_tree = 5 )
158
146
self .assertEqual (out_move , out )
159
147
160
148
def test_minimaxTreeSearch_random (self ):
161
149
"""
162
- Tests the minimax_tree_search function when playing against a
163
- Random player.
164
- The best answer to Random is to always defect
150
+ Tests the minimax_tree_search function when playing against a Random
151
+ player. The best answer to Random is to always defect.
165
152
"""
166
153
expected_output = [1 , 1 , 1 , 1 ]
167
154
for inp , out in zip (self .input_pos , expected_output ):
168
155
begin_node = dbs .DeterministicNode (inp [0 ], inp [1 ], depth = 0 )
169
- values = dbs .minimax_tree_search (begin_node ,
170
- self .random_policy , max_depth = 5 )
156
+ values = dbs .minimax_tree_search (
157
+ begin_node , self .random_policy , max_depth = 5 )
171
158
self .assertEqual (values .index (max (values )),out )
172
159
173
160
def test_move_gen_random (self ):
174
161
"""
175
- Tests the move_gen function when playing against a
176
- Random player.
162
+ Tests the move_gen function when playing against a Random player.
177
163
"""
178
164
expected_output = [D , D , D , D ]
179
165
for inp , out in zip (self .input_pos , expected_output ):
180
- out_move = dbs .move_gen (inp , self .random_policy , depth_search_tree = 5 )
166
+ out_move = dbs .move_gen (inp , self .random_policy ,
167
+ depth_search_tree = 5 )
181
168
self .assertEqual (out_move , out )
182
169
183
170
def test_minimaxTreeSearch_grudger (self ):
184
171
"""
185
172
Tests the minimax_tree_search function when playing against a
186
- Grudger player.
187
- The best answer to Grudger is to cooperate if both cooperated
188
- at last round, else it's to defect
173
+ Grudger player. The best answer to Grudger is to cooperate if both
174
+ cooperated at last round, else it's to defect.
189
175
"""
190
176
expected_output = [0 , 1 , 1 , 1 ]
191
177
for inp , out in zip (self .input_pos , expected_output ):
192
178
begin_node = dbs .DeterministicNode (inp [0 ], inp [1 ], depth = 0 )
193
- values = dbs .minimax_tree_search (begin_node ,
194
- self .grudger_policy , max_depth = 5 )
179
+ values = dbs .minimax_tree_search (
180
+ begin_node , self .grudger_policy , max_depth = 5 )
195
181
self .assertEqual (values .index (max (values )),out )
196
182
197
183
def test_move_gen_grudger (self ):
198
184
"""
199
- Tests the move_gen function when playing against a
200
- Grudger player.
185
+ Tests the move_gen function when playing against a Grudger player.
201
186
"""
202
187
expected_output = [C , D , D , D ]
203
188
for inp , out in zip (self .input_pos , expected_output ):
204
- out_move = dbs .move_gen (inp ,
205
- self .grudger_policy , depth_search_tree = 5 )
189
+ out_move = dbs .move_gen (
190
+ inp , self .grudger_policy , depth_search_tree = 5 )
206
191
self .assertEqual (out_move , out )
207
192
208
193
@@ -222,68 +207,66 @@ class TestDBS(TestPlayer):
222
207
223
208
def test_strategy (self ):
224
209
default_init_kwargs = {
225
- 'discount_factor' :.75 , 'promotion_threshold' :3 ,
226
- 'violation_threshold' :4 , 'reject_threshold' :4 ,
227
- 'tree_depth' :5
228
- }
210
+ 'discount_factor' : .75 , 'promotion_threshold' : 3 ,
211
+ 'violation_threshold' : 4 , 'reject_threshold' : 4 ,
212
+ 'tree_depth' : 5
213
+ }
229
214
230
- # test that DBS always cooperate against Cooperator
215
+ # Test that DBS always cooperate against Cooperator.
231
216
actions = [(C , C )] * 7
232
217
self .versus_test (
233
- opponent = axelrod .Cooperator (),
234
- expected_actions = actions ,
235
- init_kwargs = default_init_kwargs
236
- )
218
+ opponent = axelrod .Cooperator (),
219
+ expected_actions = actions ,
220
+ init_kwargs = default_init_kwargs
221
+ )
237
222
238
- # test if it correctly learns Alternator strategy
223
+ # Test if it correctly learns Alternator strategy.
239
224
actions = [(C , C ), (C , D )] * 3 + [(D , C ), (C , D )] * 3
240
225
self .versus_test (
241
- opponent = axelrod .Alternator (),
242
- expected_actions = actions ,
243
- init_kwargs = default_init_kwargs
244
- )
226
+ opponent = axelrod .Alternator (),
227
+ expected_actions = actions ,
228
+ init_kwargs = default_init_kwargs
229
+ )
245
230
246
- # check that algorithms take into account a change in
247
- # opponent's strategy
231
+ # Check that algorithms take into account a change in opponent's
232
+ # strategy.
248
233
mock_actions = [C , C , C , D , D , D , D , D , D , D ]
249
234
exp_actions = [(C , C )] * 3 + [(C , D )] * 4 + [(D , D )] * 3
250
235
self .versus_test (
251
- opponent = axelrod .MockPlayer (actions = mock_actions ),
252
- expected_actions = exp_actions ,
253
- init_kwargs = default_init_kwargs
254
- )
236
+ opponent = axelrod .MockPlayer (actions = mock_actions ),
237
+ expected_actions = exp_actions ,
238
+ init_kwargs = default_init_kwargs
239
+ )
255
240
256
- # check that adaptation is faster if diminishing promotion_threshold
241
+ # Check that adaptation is faster if diminishing promotion_threshold.
257
242
init_kwargs_2 = {
258
- 'discount_factor' :.75 , 'promotion_threshold' :2 ,
259
- 'violation_threshold' :4 , 'reject_threshold' :4 ,
260
- 'tree_depth' :5
261
- }
243
+ 'discount_factor' : .75 , 'promotion_threshold' : 2 ,
244
+ 'violation_threshold' : 4 , 'reject_threshold' : 4 ,
245
+ 'tree_depth' : 5
246
+ }
262
247
mock_actions = [C , C , C , D , D , D , D , D , D , D ]
263
248
exp_actions = [(C , C )] * 3 + [(C , D )] * 3 + [(D , D )] * 4
264
249
self .versus_test (
265
- opponent = axelrod .MockPlayer (actions = mock_actions ),
266
- expected_actions = exp_actions ,
267
- init_kwargs = init_kwargs_2
268
- )
250
+ opponent = axelrod .MockPlayer (actions = mock_actions ),
251
+ expected_actions = exp_actions ,
252
+ init_kwargs = init_kwargs_2
253
+ )
269
254
270
- # check that ShouldDemote mecanism works.
271
- # We play against Alternator during 12 turns to make the
255
+ # Check that ShouldDemote mechanism works.
256
+ # We play against Alternator for 12 turns to make the
272
257
# algorithm learn Alternator's strategy, then at turn 13 we
273
- # change opponent to Defector, hence trigging ShouldDemote
274
- # mecanism
275
- # For this test we use violation_threshold=3
258
+ # change opponent to Defector, hence triggering ShouldDemote
259
+ # mechanism. For this test we use violation_threshold=3
276
260
init_kwargs_3 = {
277
- 'discount_factor' :.75 , 'promotion_threshold' :3 ,
278
- 'violation_threshold' :3 , 'reject_threshold' :3 ,
279
- 'tree_depth' :5
280
- }
261
+ 'discount_factor' : .75 , 'promotion_threshold' : 3 ,
262
+ 'violation_threshold' : 3 , 'reject_threshold' : 3 ,
263
+ 'tree_depth' : 5
264
+ }
281
265
exp_actions = [(C , C ), (C , D )] * 3 + [(D , C ), (C , D )] * 3
282
266
exp_actions += [(D , D ), (C , D )] * 3 + [(D , D )]
283
267
mock_actions = [C , D , C , D , C , D , C , D , C , D , C , D , D , D , D , D , D , D , D ]
284
268
self .versus_test (
285
- opponent = axelrod .MockPlayer (actions = mock_actions ),
286
- expected_actions = exp_actions ,
287
- init_kwargs = init_kwargs_3
288
- )
289
-
269
+ opponent = axelrod .MockPlayer (actions = mock_actions ),
270
+ expected_actions = exp_actions ,
271
+ init_kwargs = init_kwargs_3
272
+ )
0 commit comments