def _move(self, action, throw=False): """Current player makes an action. Returns (NewGame and Reward)<Game,int>""" if self.over() or not self.is_action_valid(action): return self._invalid_input(throw) # player is out, increment turn index if action.discard == Card.noCard: return Game(self.deck(), self.players(), self.turn_index() + 1, self._action_log) player = self.player() player_hand = [player.hand_card, self._deck[0]] player_hand_new = Game.new_hand_card(action.discard, player_hand) deck_new = self._deck[1:] # choosing to discard the princess ... is valid if action.discard == Card.princess: return self._move_princess(self._deck[0], action, deck_new) # priest requires modification of action (knowledge) if action.discard == Card.priest: return self._move_priest(action, player_hand_new, deck_new) # updated players for the next turn player = PlayerTools.move(self.player(), player_hand_new, action) current_players = Game._set_player( self._players, player, self.player_turn()) if action.discard == Card.baron: return self._move_baron(action, current_players, player_hand_new, deck_new) # No other logic for handmaids or countess if action.discard == Card.handmaid or \ action.discard == Card.countess: action_updated = action._replace(player=self.player_turn()) return Game(deck_new, current_players, self._turn_index + 1, [*self._action_log, action_updated]) if action.discard == Card.guard: return self._move_guard(current_players, action, deck_new) if action.discard == Card.prince: return self._move_prince(current_players, action, deck_new) if action.discard == Card.king: return self._move_king(current_players, action, deck_new) raise NotImplementedError("Missing game logic")
def _move_priest(self, action, player_hand_new, deck_new): """ Handle a priest action into a new game state Action gains knowledge of other player's card """ player_targets_card = Card.noCard if \ PlayerTools.is_defended(self._players[action.player_target]) \ else self._players[action.player_target].hand_card action_updated = PlayerAction( action.discard, action.player_target, action.guess, player_targets_card) player = PlayerTools.move( self.player(), player_hand_new, action_updated) current_players = Game._set_player( self._players, player, self.player_turn()) return Game(deck_new, current_players, self._turn_index + 1)
def test_move(self): """Player performs a move""" player = PlayerTools.blank(1) player_next = PlayerTools.move(player, 4, PlayerAction(3, 2, 0, 0)) self.assertEqual(player.hand_card, 1) self.assertEqual(len(player.actions), 8) for action in player.actions: self.assertTrue(PlayerActionTools.is_blank(action)) self.assertEqual(player_next.hand_card, 4) self.assertEqual(len(player_next.actions), 8) action = player_next.actions[0] self.assertEqual(action.discard, 3) self.assertEqual(action.player_target, 2) self.assertEqual(action.guess, 0) self.assertEqual(action.revealed_card, 0) self.assertEqual(PlayerActionTools.is_blank(action), False) for action in player_next.actions[1:]: self.assertTrue(PlayerActionTools.is_blank(action))