33import axelrod
44import unittest
55from .test_player import TestPlayer
6+ from axelrod import dbs
67
78C , D = axelrod .Actions .C , axelrod .Actions .D
89
@@ -11,7 +12,7 @@ class TestNode(unittest.TestCase):
1112 """
1213 Test for the base class
1314 """
14- node = axelrod . dbs .Node ()
15+ node = dbs .Node ()
1516
1617 def test_get_siblings (self ):
1718 with self .assertRaises (NotImplementedError ) as context :
@@ -22,6 +23,189 @@ def test_is_stochastic(self):
2223 self .node .is_stochastic ()
2324
2425
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+
25209class TestDBS (TestPlayer ):
26210 name = "DBS: 0.75, 3, 4, 3, 5"
27211 player = axelrod .DBS
0 commit comments