3
3
import axelrod
4
4
import unittest
5
5
from .test_player import TestPlayer
6
+ from axelrod import dbs
6
7
7
8
C , D = axelrod .Actions .C , axelrod .Actions .D
8
9
@@ -11,7 +12,7 @@ class TestNode(unittest.TestCase):
11
12
"""
12
13
Test for the base class
13
14
"""
14
- node = axelrod . dbs .Node ()
15
+ node = dbs .Node ()
15
16
16
17
def test_get_siblings (self ):
17
18
with self .assertRaises (NotImplementedError ) as context :
@@ -22,6 +23,189 @@ def test_is_stochastic(self):
22
23
self .node .is_stochastic ()
23
24
24
25
26
+ class TestTreeSearch (unittest .TestCase ):
27
+ """
28
+ A set of tests for the tree-search functions.
29
+ We test the answers of both minimax_tree_search and MoveGen
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
34
+ """
35
+ def setUp (self ):
36
+ """
37
+ Initialization for tests.
38
+ """
39
+ # For each test, we check the answer againt each possible
40
+ # inputs, that are in self.input_pos
41
+ self .input_pos = [(C , C ), (C , D ), (D , C ), (D , D )]
42
+ # We define the policies against which we are going to test
43
+ self .cooperator_policy = dbs .create_policy (1 , 1 , 1 , 1 )
44
+ self .defector_policy = dbs .create_policy (0 , 0 , 0 , 0 )
45
+ self .titForTat_policy = dbs .create_policy (1 , 1 , 0 , 0 )
46
+ self .alternator_policy = dbs .create_policy (0 , 1 , 0 , 1 )
47
+ self .grudger_policy = dbs .create_policy (1 , 0 , 0 , 0 )
48
+ self .random_policy = dbs .create_policy (.5 , .5 , .5 , .5 )
49
+
50
+ def test_minimaxTreeSearch_cooperator (self ):
51
+ """
52
+ Tests the minimax_tree_search function when playing against a
53
+ Cooperator player.
54
+ Output == 0 means Cooperate, 1 means Defect.
55
+ The best (hence expected) answer to Cooperator is to defect
56
+ whatever the input position is.
57
+ """
58
+ expected_output = [1 , 1 , 1 , 1 ]
59
+ for inp , out in zip (self .input_pos , expected_output ):
60
+ 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 )
64
+
65
+ def test_MoveGen_cooperator (self ):
66
+ """
67
+ Tests the MoveGen function when playing against a
68
+ Cooperator player.
69
+ """
70
+ expected_output = [D , D , D , D ]
71
+ for inp , out in zip (self .input_pos , expected_output ):
72
+ out_move = dbs .MoveGen (inp , self .cooperator_policy ,
73
+ depth_search_tree = 5 )
74
+ self .assertEqual (out_move , out )
75
+
76
+ def test_minimaxTreeSearch_defector (self ):
77
+ """
78
+ Tests the minimax_tree_search function when playing against a
79
+ Defector player.
80
+ The best answer to Defector is to always defect
81
+ """
82
+ expected_output = [1 , 1 , 1 , 1 ]
83
+ for inp , out in zip (self .input_pos , expected_output ):
84
+ 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 )
87
+ self .assertEqual (values .index (max (values )),out )
88
+
89
+ def test_MoveGen_defector (self ):
90
+ """
91
+ Tests the MoveGen function when playing against a
92
+ Defector player.
93
+ """
94
+ expected_output = [D , D , D , D ]
95
+ for inp , out in zip (self .input_pos , expected_output ):
96
+ out_move = dbs .MoveGen (inp , self .defector_policy ,
97
+ depth_search_tree = 5 )
98
+ self .assertEqual (out_move , out )
99
+
100
+ def test_minimaxTreeSearch_titForTat (self ):
101
+ """
102
+ 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.
106
+ """
107
+ expected_output = [0 , 0 , 0 , 0 ]
108
+ for inp , out in zip (self .input_pos , expected_output ):
109
+ 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 )
112
+ self .assertEqual (values .index (max (values )),out )
113
+
114
+ def test_last_node_titForTat (self ):
115
+ """
116
+ Test that against TitForTat, for the last move, i.e. if tree
117
+ depth is 1, the algorithms defects for all input
118
+ """
119
+ expected_output = [1 , 1 , 1 , 1 ]
120
+ for inp , out in zip (self .input_pos , expected_output ):
121
+ 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 )
124
+ self .assertEqual (values .index (max (values )),out )
125
+
126
+ def test_MoveGen_titForTat (self ):
127
+ """
128
+ Tests the MoveGen function when playing against a
129
+ TitForTat player.
130
+ """
131
+ expected_output = [C , C , C , C ]
132
+ for inp , out in zip (self .input_pos , expected_output ):
133
+ out_move = dbs .MoveGen (inp , self .titForTat_policy ,
134
+ depth_search_tree = 5 )
135
+ self .assertEqual (out_move , out )
136
+
137
+ def test_minimaxTreeSearch_alternator (self ):
138
+ """
139
+ Tests the minimax_tree_search function when playing against an
140
+ Alternator player.
141
+ The best answer to Alternator is to always defect
142
+ """
143
+ expected_output = [1 , 1 , 1 , 1 ]
144
+ for inp , out in zip (self .input_pos , expected_output ):
145
+ 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 )
148
+ self .assertEqual (values .index (max (values )),out )
149
+
150
+ def test_MoveGen_alternator (self ):
151
+ """
152
+ Tests the MoveGen function when playing against an
153
+ Alternator player.
154
+ """
155
+ expected_output = [D , D , D , D ]
156
+ for inp , out in zip (self .input_pos , expected_output ):
157
+ out_move = dbs .MoveGen (inp , self .random_policy , depth_search_tree = 5 )
158
+ self .assertEqual (out_move , out )
159
+
160
+ def test_minimaxTreeSearch_random (self ):
161
+ """
162
+ Tests the minimax_tree_search function when playing against a
163
+ Random player.
164
+ The best answer to Random is to always defect
165
+ """
166
+ expected_output = [1 , 1 , 1 , 1 ]
167
+ for inp , out in zip (self .input_pos , expected_output ):
168
+ 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 )
171
+ self .assertEqual (values .index (max (values )),out )
172
+
173
+ def test_MoveGen_random (self ):
174
+ """
175
+ Tests the MoveGen function when playing against a
176
+ Random player.
177
+ """
178
+ expected_output = [D , D , D , D ]
179
+ for inp , out in zip (self .input_pos , expected_output ):
180
+ out_move = dbs .MoveGen (inp , self .random_policy , depth_search_tree = 5 )
181
+ self .assertEqual (out_move , out )
182
+
183
+ def test_minimaxTreeSearch_grudger (self ):
184
+ """
185
+ 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
189
+ """
190
+ expected_output = [0 , 1 , 1 , 1 ]
191
+ for inp , out in zip (self .input_pos , expected_output ):
192
+ 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 )
195
+ self .assertEqual (values .index (max (values )),out )
196
+
197
+ def test_MoveGen_grudger (self ):
198
+ """
199
+ Tests the MoveGen function when playing against a
200
+ Grudger player.
201
+ """
202
+ expected_output = [C , D , D , D ]
203
+ for inp , out in zip (self .input_pos , expected_output ):
204
+ out_move = dbs .MoveGen (inp ,
205
+ self .grudger_policy , depth_search_tree = 5 )
206
+ self .assertEqual (out_move , out )
207
+
208
+
25
209
class TestDBS (TestPlayer ):
26
210
name = "DBS: 0.75, 3, 4, 3, 5"
27
211
player = axelrod .DBS
0 commit comments