1 from unittest import TestCase
3 from naja.constants import BITS, MOVES, EXAMINE
4 from naja.gameboard import GameBoard, LocationCard
5 from naja.options import parse_args
6 from naja import actions
9 class TestGameBoard(TestCase):
13 def make_deck(self, cards=None):
15 cards = [{'actions': []}]
16 return {'cards': cards}
18 def assert_state(self, state1, state2, exclude=(), player_exclude=()):
19 def filter_dict(source, exclude_keys):
20 return dict((k, v) for k, v in source.items()
21 if k not in exclude_keys)
23 state1 = filter_dict(state1, exclude)
24 if 'player' in state1:
25 state1['player'] = filter_dict(state1['player'], player_exclude)
26 state2 = filter_dict(state2, exclude)
27 if 'player' in state2:
28 state2['player'] = filter_dict(state2['player'], player_exclude)
30 self.assertEqual(state1, state2)
32 def test_export_new_board(self):
33 board = GameBoard.new_game({'cards': [{'actions': [
35 'action_class': 'LoseHealthOrMSB',
38 'action_class': 'GainHealth',
39 'required_bits': [BITS.RED],
42 exported_state = board.export()
43 board_locations = exported_state.pop('board_locations')
44 self.assertEqual(exported_state, {
49 'locations': [{'actions': [
51 'action_class': 'LoseHealthOrMSB',
54 'action_class': 'GainHealth',
55 'required_bits': [BITS.RED],
58 'player': board.player.export(),
60 'player_mode': EXAMINE,
63 for position, location_state in board_locations:
64 positions.append(position)
66 sorted(location_state.keys()), ['actions', 'bitwise_operand'])
67 self.assertEqual(location_state['actions'], [
69 'action_class': 'LoseHealthOrMSB',
73 'action_class': 'GainHealth',
74 'required_bits': [BITS.RED],
78 self.assertTrue(2 <= len(location_state['bitwise_operand']) <= 3)
80 positions, sorted((x, y) for x in range(5) for y in range(5)))
82 def test_lose_health(self):
83 board = GameBoard.new_game(self.make_deck())
84 self.assertEqual(board.health, 4)
85 state_1 = board.export()
88 self.assertEqual(board.health, 3)
89 state_2 = board.export()
91 self.assert_state(state_1, state_2, exclude=['health'])
93 def test_gain_health(self):
94 board = GameBoard.new_game(self.make_deck())
96 self.assertEqual(board.health, 2)
97 state_1 = board.export()
100 self.assertEqual(board.health, 3)
101 state_2 = board.export()
103 self.assert_state(state_1, state_2, exclude=['health'])
105 def test_gain_health_at_max(self):
106 board = GameBoard.new_game(self.make_deck())
107 self.assertEqual(board.health, 4)
108 state_1 = board.export()
111 self.assertEqual(board.health, 4)
112 state_2 = board.export()
114 self.assert_state(state_1, state_2)
116 def generate_locations(self, override_dict=None):
117 locations_dict = dict(((x, y), '%s%s' % (x, y))
118 for x in range(5) for y in range(5))
120 locations_dict.update(override_dict)
121 return locations_dict
123 def test_shift_locations_north(self):
124 board = GameBoard.new_game(self.make_deck())
125 board.board_locations = self.generate_locations()
126 board.shift_locations('NORTH')
127 self.assertEqual(board.board_locations, self.generate_locations({
128 (2, 0): '21', (2, 1): '23', (2, 3): '24', (2, 4): '20',
131 def test_shift_locations_south(self):
132 board = GameBoard.new_game(self.make_deck())
133 board.board_locations = self.generate_locations()
134 board.shift_locations('SOUTH')
135 self.assertEqual(board.board_locations, self.generate_locations({
136 (2, 0): '24', (2, 1): '20', (2, 3): '21', (2, 4): '23',
139 def test_shift_locations_east(self):
140 board = GameBoard.new_game(self.make_deck())
141 board.board_locations = self.generate_locations()
142 board.shift_locations('EAST')
143 self.assertEqual(board.board_locations, self.generate_locations({
144 (0, 2): '42', (1, 2): '02', (3, 2): '12', (4, 2): '32',
147 def test_shift_locations_west(self):
148 board = GameBoard.new_game(self.make_deck())
149 board.board_locations = self.generate_locations()
150 board.shift_locations('WEST')
151 self.assertEqual(board.board_locations, self.generate_locations({
152 (0, 2): '12', (1, 2): '32', (3, 2): '42', (4, 2): '02',
155 def test_rotate_locations_anticlockwise(self):
156 board = GameBoard.new_game(self.make_deck())
157 board.board_locations = self.generate_locations()
158 board.rotate_locations('ANTICLOCKWISE')
159 self.assertEqual(board.board_locations, self.generate_locations({
160 (1, 1): '21', (2, 1): '31', (3, 1): '32',
161 (1, 2): '11', (3, 2): '33',
162 (1, 3): '12', (2, 3): '13', (3, 3): '23',
165 def test_rotate_locations_anticlockwise_top(self):
166 board = GameBoard.new_game(self.make_deck(), initial_pos=(2, 0))
167 board.board_locations = self.generate_locations()
168 board.rotate_locations('ANTICLOCKWISE')
169 self.assertEqual(board.board_locations, self.generate_locations({
170 (1, 0): '30', (3, 0): '31',
171 (1, 1): '10', (2, 1): '11', (3, 1): '21',
174 def test_rotate_locations_anticlockwise_right(self):
175 board = GameBoard.new_game(self.make_deck(), initial_pos=(0, 2))
176 board.board_locations = self.generate_locations()
177 board.rotate_locations('ANTICLOCKWISE')
178 self.assertEqual(board.board_locations, self.generate_locations({
179 (0, 1): '11', (1, 1): '12',
181 (0, 3): '01', (1, 3): '03',
184 def test_rotate_locations_anticlockwise_corner(self):
185 board = GameBoard.new_game(self.make_deck(), initial_pos=(0, 4))
186 board.board_locations = self.generate_locations()
187 board.rotate_locations('ANTICLOCKWISE')
188 self.assertEqual(board.board_locations, self.generate_locations({
189 (0, 3): '13', (1, 3): '14',
193 def test_rotate_locations_clockwise(self):
194 board = GameBoard.new_game(self.make_deck())
195 board.board_locations = self.generate_locations()
196 board.rotate_locations('CLOCKWISE')
197 self.assertEqual(board.board_locations, self.generate_locations({
198 (1, 1): '12', (2, 1): '11', (3, 1): '21',
199 (1, 2): '13', (3, 2): '31',
200 (1, 3): '23', (2, 3): '33', (3, 3): '32',
203 def test_rotate_locations_clockwise_1_3(self):
204 board = GameBoard.new_game(self.make_deck(), initial_pos=(1, 3))
205 board.board_locations = self.generate_locations()
206 board.rotate_locations('CLOCKWISE')
207 self.assertEqual(board.board_locations, self.generate_locations({
208 (0, 2): '03', (1, 2): '02', (2, 2): '12',
209 (0, 3): '04', (2, 3): '22',
210 (0, 4): '14', (1, 4): '24', (2, 4): '23',
213 def test_allow_chess_move_knight(self):
214 board = GameBoard.new_game(self.make_deck())
215 board.allow_chess_move(MOVES.KNIGHT)
216 self.assertEqual(board.player.movement_mode, MOVES.KNIGHT)
218 def test_allow_chess_move_bishop(self):
219 board = GameBoard.new_game(self.make_deck())
220 board.allow_chess_move(MOVES.BISHOP)
221 self.assertEqual(board.player.movement_mode, MOVES.BISHOP)
223 def test_allow_chess_move_castle(self):
224 board = GameBoard.new_game(self.make_deck())
225 board.allow_chess_move(MOVES.CASTLE)
226 self.assertEqual(board.player.movement_mode, MOVES.CASTLE)
229 class TestLocationCard(TestCase):
230 def test_generate_bitwise_operand(self):
231 # This is testing a random process, so it may fail occasionally.
234 operand_sets.append(LocationCard.generate_bitwise_operand())
237 for operand_set in operand_sets:
238 sizes[len(operand_set)] += 1
239 bits.update(operand_set)
240 # TODO: Test that there's at least one condition and one direction.
241 self.assertTrue(sizes[2] > 0)
242 self.assertTrue(sizes[3] > 0)
243 self.assertTrue(sizes[2] > sizes[3])
244 self.assertEqual(bits, set(BITS.values()))
246 def test_new_location_no_actions(self):
247 location = LocationCard.new_location({'actions': []})
248 [action] = location.actions
249 self.assertEqual(type(action), actions.DoNothing)
250 self.assertEqual(action.required_bits, set())
252 def test_new_location_one_action(self):
253 location = LocationCard.new_location({'actions': [
254 {'required_bits': [], 'action_class': 'DoNothing'},
256 [action] = location.actions
257 self.assertEqual(type(action), actions.DoNothing)
258 self.assertEqual(action.required_bits, set())
260 def test_parse_bits(self):
262 LocationCard.parse_bits([]), frozenset([]))
264 LocationCard.parse_bits(['RED']), frozenset([BITS.RED]))
266 LocationCard.parse_bits([BITS.BLUE]), frozenset([BITS.BLUE]))
268 LocationCard.parse_bits([BITS.NORTH, 'MSB']),
269 frozenset([BITS.NORTH, BITS.MSB]))