1 from unittest import TestCase
3 from naja.constants import BITS, MOVES
4 from naja.gameboard import GameBoard, LocationCard
5 from naja.options import parse_args
6 from naja.player import Player
7 from naja import actions
10 class TestActions(TestCase):
14 def make_player(self, *bits):
17 player_bits |= (1 << bit)
18 return Player(player_bits, None)
20 def make_board(self, player_bits=None, locations=None):
22 locations = [{'card_name': 'card', 'actions': []}]
23 board = GameBoard.new_game({'cards': locations})
24 if player_bits is not None:
25 board.player.bits.bits = 0
26 board.player.bits.set_bits(player_bits)
29 def make_location_card(self, bits=(), name='card', actions=()):
30 return LocationCard(name, set(bits), list(actions), None)
32 def assert_player_bits(self, board, *bits):
33 self.assertEqual(sum(1 << bit for bit in bits), board.player.bits.bits)
35 def assert_state(self, state1, state2, exclude=(), player_exclude=()):
36 def filter_dict(source, exclude_keys):
37 return dict((k, v) for k, v in source.items()
38 if k not in exclude_keys)
40 state1 = filter_dict(state1, exclude)
41 if 'player' in state1:
42 state1['player'] = filter_dict(state1['player'], player_exclude)
43 state2 = filter_dict(state2, exclude)
44 if 'player' in state2:
45 state2['player'] = filter_dict(state2['player'], player_exclude)
47 self.assertEqual(state1, state2)
49 def test_check_available(self):
50 def check_available(action_bits, player_bits, expected_result):
51 action = actions.LocationAction(action_bits)
52 player = self.make_player(*player_bits)
53 self.assertEqual(action.check_available(player), expected_result)
55 check_available(set(), [], True)
56 check_available(set(), [BITS.MSB], True)
57 check_available(set([BITS.MSB]), [], False)
58 check_available(set([BITS.MSB]), [BITS.MSB], True)
60 def test_get_text(self):
61 class LocationAction1(actions.LocationAction):
63 action1 = LocationAction1([])
64 self.assertEqual(action1.get_text(), "foo")
66 class LocationAction2(actions.LocationAction):
68 action2 = LocationAction2([], bar="baz")
69 self.assertEqual(action2.get_text(), "foo baz")
71 def test_get_text_row_column(self):
72 class DirectionAction(actions.LocationAction):
73 TEXT = "foo %(direction)s %(rowcol)s"
75 action_north = DirectionAction([], direction='NORTH')
76 self.assertEqual(action_north.get_text(), "foo {NORTH} column")
78 action_south = DirectionAction([], direction='SOUTH')
79 self.assertEqual(action_south.get_text(), "foo {SOUTH} column")
81 action_east = DirectionAction([], direction='EAST')
82 self.assertEqual(action_east.get_text(), "foo {EAST} row")
84 action_west = DirectionAction([], direction='WEST')
85 self.assertEqual(action_west.get_text(), "foo {WEST} row")
87 def test_DoNothing(self):
88 board = self.make_board()
89 state_before = board.export()
90 actions.DoNothing(set()).perform_action(board, None)
91 state_after = board.export()
92 self.assert_state(state_before, state_after)
94 def test_LoseHealthOrMSB_MSB_clear(self):
95 board = self.make_board()
96 state_before = board.export()
97 actions.LoseHealthOrMSB(set()).perform_action(board, None)
98 state_after = board.export()
99 self.assertEqual(state_after['health'], state_before['health'] - 1)
100 self.assert_state(state_before, state_after, exclude=['health'])
102 def test_LoseHealthOrMSB_MSB_set(self):
103 board = self.make_board(player_bits=[BITS.MSB])
104 state_before = board.export()
105 actions.LoseHealthOrMSB(set()).perform_action(board, None)
106 state_after = board.export()
107 self.assertEqual(board.player.bits.check_bit(BITS.MSB), False)
108 self.assert_state(state_before, state_after, player_exclude=['bits'])
110 def test_SetBits(self):
111 board = self.make_board()
112 state_before = board.export()
113 card = self.make_location_card([BITS.MSB, BITS.NORTH])
114 actions.SetBits(set()).perform_action(board, card)
115 state_after = board.export()
117 board.player.bits.check_bits([BITS.MSB, BITS.NORTH]), True)
118 self.assert_state(state_before, state_after, player_exclude=['bits'])
120 def test_ToggleBits(self):
121 board = self.make_board(player_bits=[BITS.NORTH])
122 state_before = board.export()
123 card = self.make_location_card([BITS.MSB, BITS.NORTH])
124 actions.ToggleBits(set()).perform_action(board, card)
125 state_after = board.export()
126 self.assertEqual(board.player.bits.check_bit(BITS.MSB), True)
127 self.assertEqual(board.player.bits.check_bit(BITS.NORTH), False)
128 self.assert_state(state_before, state_after, player_exclude=['bits'])
130 def test_LoseHealthOrMSBAndSetBits_MSB_clear(self):
131 board = self.make_board(player_bits=[])
132 state_before = board.export()
133 card = self.make_location_card([BITS.BLUE, BITS.NORTH])
134 actions.LoseHealthOrMSBAndSetBits(set()).perform_action(board, card)
135 state_after = board.export()
136 self.assertEqual(state_after['health'], state_before['health'] - 1)
137 self.assert_player_bits(board, BITS.BLUE, BITS.NORTH)
139 state_before, state_after, exclude=['health'],
140 player_exclude=['bits'])
142 def test_LoseHealthOrMSBAndSetBits_MSB_set(self):
143 board = self.make_board(player_bits=[BITS.MSB])
144 state_before = board.export()
145 card = self.make_location_card([BITS.BLUE, BITS.NORTH])
146 actions.LoseHealthOrMSBAndSetBits(set()).perform_action(board, card)
147 state_after = board.export()
148 self.assert_player_bits(board, BITS.BLUE, BITS.NORTH)
149 self.assert_state(state_before, state_after, player_exclude=['bits'])
151 def test_LoseHealthOrMSBAndSetBits_MSB_set_and_on_card(self):
152 board = self.make_board(player_bits=[BITS.MSB])
153 state_before = board.export()
154 card = self.make_location_card([BITS.MSB, BITS.NORTH])
155 actions.LoseHealthOrMSBAndSetBits(set()).perform_action(board, card)
156 state_after = board.export()
157 self.assert_player_bits(board, BITS.MSB, BITS.NORTH)
158 self.assert_state(state_before, state_after, player_exclude=['bits'])
160 def test_AcquireWinToken(self):
161 board = self.make_board(
162 player_bits=[BITS.RED, BITS.GREEN, BITS.BLUE])
163 state_before = board.export()
164 actions.AcquireWinToken(set()).perform_action(board, None)
165 state_after = board.export()
166 self.assertEqual(state_after['wins'], state_before['wins'] + 1)
167 self.assertEqual(board.player.bits.bits, 0)
169 state_before, state_after, exclude=['wins'],
170 player_exclude=['bits'])
172 def test_GainHealthAndClearBitsOrMSB_MSB_clear(self):
173 board = self.make_board(player_bits=[BITS.NORTH])
175 state_before = board.export()
176 card = self.make_location_card([BITS.BLUE, BITS.NORTH])
177 actions.GainHealthAndClearBitsOrMSB(set()).perform_action(board, card)
178 state_after = board.export()
179 self.assertEqual(state_after['health'], state_before['health'] + 1)
180 self.assert_player_bits(board)
182 state_before, state_after, exclude=['health'],
183 player_exclude=['bits'])
185 def test_GainHealthAndClearBitsOrMSB_MSB_set(self):
186 board = self.make_board(player_bits=[BITS.MSB, BITS.NORTH])
188 state_before = board.export()
189 card = self.make_location_card([BITS.BLUE, BITS.NORTH])
190 actions.GainHealthAndClearBitsOrMSB(set()).perform_action(board, card)
191 state_after = board.export()
192 self.assertEqual(state_after['health'], state_before['health'] + 1)
193 self.assert_player_bits(board, BITS.NORTH)
195 state_before, state_after, exclude=['health'],
196 player_exclude=['bits'])
198 def test_AllowKnightMove(self):
199 board = self.make_board(player_bits=[BITS.RED, BITS.BLUE])
200 actions.AllowChessMove(
201 set([BITS.RED, BITS.BLUE]), chesspiece="KNIGHT"
202 ).perform_action(board, None)
203 self.assertEqual(board.player.movement_mode, MOVES.KNIGHT)
205 def test_AllowBishopMove(self):
206 board = self.make_board(player_bits=[BITS.RED, BITS.BLUE])
207 actions.AllowChessMove(
208 set([BITS.RED, BITS.BLUE]), chesspiece="BISHOP"
209 ).perform_action(board, None)
210 self.assertEqual(board.player.movement_mode, MOVES.BISHOP)
212 def test_AllowCastleMove(self):
213 board = self.make_board(player_bits=[BITS.RED, BITS.BLUE])
214 actions.AllowChessMove(
215 set([BITS.RED, BITS.BLUE]), chesspiece="CASTLE"
216 ).perform_action(board, None)
217 self.assertEqual(board.player.movement_mode, MOVES.CASTLE)