Beispiel #1
0
    def test_move_handmaid(self):
        """Deploy the handmaid and survive attack"""
        game = Game.new(4, 2)
        action = PlayerAction(Card.handmaid, 0, Card.noCard, Card.noCard)
        game, _ = game.move(action)

        players = game.players()
        player = players[0]
        self.assertTrue(PlayerTools.is_playing(player))
        self.assertFalse(PlayerActionTools.is_blank(player.actions[0]))
        self.assertEqual(player.actions[0], action)
        for action in player.actions[1:]:
            self.assertTrue(PlayerActionTools.is_blank(action))

        action_attack = PlayerAction(Card.guard, 0, Card.prince, Card.noCard)
        game, _ = game.move(action_attack)

        players = game.players()
        target = players[0]
        player = players[1]
        self.assertTrue(PlayerTools.is_playing(player))
        self.assertTrue(PlayerTools.is_playing(target))

        self.assertFalse(PlayerActionTools.is_blank(player.actions[0]))
        self.assertEqual(player.actions[0], action_attack)
        for action in player.actions[1:]:
            self.assertTrue(PlayerActionTools.is_blank(action))

        for action in target.actions[1:]:
            self.assertTrue(PlayerActionTools.is_blank(action))
Beispiel #2
0
    def test_move_guard_success(self):
        """Getting a guard move, with a right guess"""
        game = Game.new()
        action = PlayerAction(Card.guard, 3, Card.handmaid, 0)
        self.assertEqual(len(game.opponents()), 3)
        self.assertListEqual(game.opponent_turn(), [1, 2, 3])
        game, _ = game.move(action)

        self.assertEqual(game.round(), 0)
        self.assertEqual(game.player_turn(), 1)
        self.assertEqual(game.cards_left(), 10)
        self.assertTrue(game.active())
        self.assertFalse(game.over())

        players = game.players()
        player = players[0]
        target = players[3]
        recent_action = player.actions[0]
        self.assertListEqual(game.opponent_turn(), [0, 2])
        self.assertEqual(len(game.opponents()), 2)

        self.assertFalse(PlayerTools.is_playing(target))
        self.assertEqual(recent_action, action)
        self.assertEqual(player.hand_card, Card.handmaid)
        self.assertFalse(PlayerActionTools.is_blank(recent_action))
        for action in player.actions[1:]:
            self.assertTrue(PlayerActionTools.is_blank(action))
Beispiel #3
0
 def test_blank(self):
     """Create an action"""
     # play guard, on player 3, guessing Prince, no revealed card
     action_normal = PlayerAction(1, 3, 5, 0)
     self.assertEqual(PlayerActionTools.is_blank(action_normal), False)
     # no action - either hasn't been taken or player was eliminated
     action_blank = PlayerAction(0, 0, 0, 0)
     self.assertEqual(PlayerActionTools.is_blank(action_blank), True)
Beispiel #4
0
def play(seed, previous_actions):
    """Play a game"""
    game = Game.new(4, seed)
    previous_actions = np.array([], dtype=np.uint8) if len(previous_actions) < 1 else \
        np.array([int(i) for i in previous_actions.split(",")], dtype=np.uint8)
    previous_actions = PlayerActionTools.from_np_many(previous_actions)[::-1]
    actions = []
    while game.active():
        if not game.is_current_player_playing():
            game = game.skip_eliminated_player()
            continue

        display(game, actions)

        try:
            if len(previous_actions) > 0:
                action = previous_actions.pop()
            else:
                print("  What card to play?")
                action = get_action()
            actions.append(action)
            game, _ = game.move(action)
        except ValueError:
            print("Invalid move - Exit with Ctrl-C")

    display(game, actions)
    print("Game Over : Player {} Wins!".format(game.winner()))
Beispiel #5
0
    def test_move_prince_self(self):
        """Use prince to force self discard"""
        game = Game.new(4, 2)
        action = PlayerAction(Card.prince, 0, Card.noCard, Card.noCard)
        action_other = PlayerAction(Card.handmaid, 0, Card.noCard, Card.noCard)
        game, _ = game.move(action)

        players = game.players()
        player = players[0]
        self.assertTrue(PlayerTools.is_playing(player))
        self.assertFalse(PlayerActionTools.is_blank(player.actions[0]))
        self.assertFalse(PlayerActionTools.is_blank(player.actions[1]))
        self.assertEqual(player.actions[0], action)
        self.assertEqual(player.actions[1], action_other)
        for action in player.actions[2:]:
            self.assertTrue(PlayerActionTools.is_blank(action))
Beispiel #6
0
 def test_init(self):
     """Create a Player"""
     player = PlayerTools.blank(1)
     self.assertEqual(player.hand_card, 1)
     self.assertEqual(len(player.actions), 8)
     for action in player.actions:
         self.assertTrue(PlayerActionTools.is_blank(action))
Beispiel #7
0
 def test_from_np(self):
     """Action from a numpy array"""
     arr = np.array([1, 3, 5, 0], dtype=np.uint8)
     action = PlayerActionTools.from_np(arr)
     self.assertEqual(action.discard, 1)
     self.assertEqual(action.player_target, 3)
     self.assertEqual(action.guess, 5)
     self.assertEqual(action.revealed_card, 0)
Beispiel #8
0
    def test_move_princess(self):
        """Commit suicide by discarding the princess"""
        game = Game.new(4, 11)
        action = PlayerAction(Card.princess, 0, Card.noCard, Card.noCard)
        game, _ = game.move(action)

        players = game.players()
        player = players[0]

        self.assertFalse(PlayerTools.is_playing(player))
        self.assertFalse(PlayerActionTools.is_blank(player.actions[0]))
        self.assertFalse(PlayerActionTools.is_blank(player.actions[1]))
        self.assertEqual(player.actions[0],
                         PlayerAction(Card.baron, 0, Card.noCard, Card.noCard))
        self.assertEqual(player.actions[1], action)

        for action in player.actions[2:]:
            self.assertTrue(PlayerActionTools.is_blank(action))
Beispiel #9
0
 def test_init(self):
     """Create an action"""
     # play guard, on player 3, guessing Prince, no revealed card
     action = PlayerAction(1, 3, 5, 0)
     self.assertEqual(action.discard, 1)
     self.assertEqual(action.player_target, 3)
     self.assertEqual(action.guess, 5)
     self.assertEqual(action.revealed_card, 0)
     self.assertEqual(PlayerActionTools.is_blank(action), False)
Beispiel #10
0
 def test_from_np_many(self):
     """Action from a numpy array"""
     actions = [
         PlayerAction(1, 3, 5, 1),
         PlayerAction(4, 0, 5, 1),
         PlayerAction(8, 0, 0, 1),
         PlayerAction(5, 0, 0, 1)
     ]
     arr = np.array([1, 3, 5, 1, 4, 0, 5, 1, 8, 0, 0, 1, 5, 0, 0, 1],
                    dtype=np.uint8)
     self.assertListEqual(PlayerActionTools.from_np_many(arr), actions)
Beispiel #11
0
    def test_move_baron_failure(self):
        """Getting a baron move, with a failure"""
        game = Game.new(4, 48)
        action = PlayerAction(Card.baron, 1, Card.noCard, Card.noCard)
        game, _ = game.move(action)

        players = game.players()
        player = players[0]
        target = players[1]

        self.assertFalse(PlayerTools.is_playing(player))
        self.assertTrue(PlayerTools.is_playing(target))

        self.assertFalse(PlayerActionTools.is_blank(player.actions[0]))
        self.assertFalse(PlayerActionTools.is_blank(player.actions[1]))
        for action in player.actions[2:]:
            self.assertTrue(PlayerActionTools.is_blank(action))

        for action in target.actions:
            self.assertTrue(PlayerActionTools.is_blank(action))
Beispiel #12
0
 def test_to_np_many(self):
     """Actions to a numpy array"""
     actions = [
         PlayerAction(1, 3, 5, 0),
         PlayerAction(4, 0, 5, 0),
         PlayerAction(8, 0, 0, 0),
         PlayerAction(5, 0, 0, 0)
     ]
     arr = np.array([1, 3, 5, 0, 4, 0, 5, 0, 8, 0, 0, 0, 5, 0, 0, 0],
                    dtype=np.uint8)
     self.assertTrue((PlayerActionTools.to_np_many(actions) == arr).all())
Beispiel #13
0
    def test_move_king(self):
        """Use king to swap hands with the target"""
        game = Game.new(4, 0)
        action = PlayerAction(Card.king, 1, Card.noCard, Card.noCard)
        game, _ = game.move(action)

        players = game.players()
        player = players[0]
        target = players[1]

        self.assertTrue(PlayerTools.is_playing(player))
        self.assertFalse(PlayerActionTools.is_blank(player.actions[0]))
        self.assertEqual(player.actions[0], action)
        self.assertEqual(player.hand_card, Card.priest)
        for action in player.actions[1:]:
            self.assertTrue(PlayerActionTools.is_blank(action))

        self.assertTrue(PlayerTools.is_playing(target))
        self.assertEqual(target.hand_card, Card.guard)
        for action in target.actions:
            self.assertTrue(PlayerActionTools.is_blank(action))
Beispiel #14
0
    def is_action_valid(self, action):
        """Tests if an action is valid given the current game state"""
        player = self.player()

        # if player is out, only valid action is no action
        if player.hand_card == Card.noCard:
            return PlayerActionTools.is_blank(action)

        target_player = self._players[action.player_target]
        player_hand = [player.hand_card, self._deck[0]]

        # cannot discard a card not in the hand
        if action.discard not in player_hand:
            return False

        new_hand_card = Game.new_hand_card(action.discard, player_hand)

        # countess must be discarded if the other card is king/prince
        if new_hand_card == Card.countess and \
                (action.discard == Card.prince or action.discard == Card.king):
            return False

        # cannot target an invalid player
        if not self._is_valid_player_target(action.player_target):
            return False

        # cannot mis-target a card
        if self.player_turn() == action.player_target and action.discard in Card.only_other:
            # Check if self is the only valid target due to everybody else protected (or dead)
            other_players_invalid = [not PlayerTools.is_playing(p) or PlayerTools.is_defended(p)
                                     for p in self._players if p is not self.player()]

            if all(other_players_invalid):
                return True
            else:
                return False

        if self.player_turn() != action.player_target and action.discard in Card.only_self:
            return False

        if not PlayerTools.is_playing(target_player):
            return False

        # Check if target is defender (and not the current player)
        if PlayerTools.is_defended(target_player) and player != target_player:
            return False

        # Cannot guess guard or no card
        if action.discard == Card.guard and (
                action.guess == Card.guard or action.guess == Card.noCard):
            return False

        return True
Beispiel #15
0
    def test_move_prince_other(self):
        """Use prince to force another to discard"""
        game = Game.new(4, 2)
        action = PlayerAction(Card.prince, 1, Card.noCard, Card.noCard)
        action_target = PlayerAction(Card.guard, 0, Card.noCard, Card.noCard)
        game, _ = game.move(action)

        players = game.players()
        player = players[0]
        target = players[1]

        self.assertTrue(PlayerTools.is_playing(player))
        self.assertFalse(PlayerActionTools.is_blank(player.actions[0]))
        self.assertEqual(player.actions[0], action)
        for action in player.actions[1:]:
            self.assertTrue(PlayerActionTools.is_blank(action))

        self.assertTrue(PlayerTools.is_playing(target))
        self.assertFalse(PlayerActionTools.is_blank(target.actions[0]))
        self.assertEqual(target.actions[0], action_target)
        for action in target.actions[1:]:
            self.assertTrue(PlayerActionTools.is_blank(action))
Beispiel #16
0
    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))
Beispiel #17
0
    def test_move_baron_success(self):
        """Getting a baron move, with a success"""
        game = Game.new(4, 48)
        action = PlayerAction(Card.baron, 3, Card.noCard, Card.noCard)
        game, _ = game.move(action)

        players = game.players()
        player = players[0]
        target = players[3]
        recent_action = player.actions[0]

        self.assertTrue(PlayerTools.is_playing(player))
        self.assertFalse(PlayerTools.is_playing(target))
        self.assertEqual(recent_action, action)

        self.assertFalse(PlayerActionTools.is_blank(recent_action))
        for action in player.actions[1:]:
            self.assertTrue(PlayerActionTools.is_blank(action))

        self.assertFalse(PlayerActionTools.is_blank(target.actions[0]))
        for action in target.actions[1:]:
            self.assertTrue(PlayerActionTools.is_blank(action))
Beispiel #18
0
    def test_move_priest(self):
        """Getting a priest move"""
        game = Game.new(4, 5)
        action = PlayerAction(Card.priest, 1, Card.noCard, Card.noCard)
        action_expected = PlayerAction(Card.priest, 1, Card.noCard, Card.guard)
        game, _ = game.move(action)

        self.assertEqual(game.round(), 0)
        self.assertEqual(game.player_turn(), 1)
        self.assertEqual(game.cards_left(), 10)
        self.assertTrue(game.active())
        self.assertFalse(game.over())

        players = game.players()
        player = players[0]
        target = players[1]
        recent_action = player.actions[0]

        self.assertTrue(PlayerTools.is_playing(target))
        self.assertEqual(recent_action, action_expected)
        self.assertFalse(PlayerActionTools.is_blank(recent_action))
        for action in player.actions[1:]:
            self.assertTrue(PlayerActionTools.is_blank(action))
Beispiel #19
0
    def test_move_guard_failure(self):
        """Getting a guard move, with a wrong guess"""
        game = Game.new()
        action = PlayerAction(Card.guard, 1, Card.handmaid, 0)
        game, _ = game.move(action)

        self.assertEqual(game.round(), 0)
        self.assertEqual(game.player_turn(), 1)
        self.assertEqual(game.cards_left(), 10)
        self.assertTrue(game.active())
        self.assertFalse(game.over())

        players = game.players()
        player = players[0]
        target = players[1]
        recent_action = player.actions[0]

        self.assertTrue(PlayerTools.is_playing(target))
        self.assertEqual(recent_action, action)
        self.assertEqual(player.hand_card, Card.handmaid)
        self.assertFalse(PlayerActionTools.is_blank(recent_action))
        for action in player.actions[1:]:
            self.assertTrue(PlayerActionTools.is_blank(action))
Beispiel #20
0
    def test_move_guard_guess_guard(self):
        """Getting a guard move and guessing guard"""
        game = Game.new()
        action = PlayerAction(Card.guard, 1, Card.guard, 0)
        game, _ = game.move(action)

        self.assertEqual(game.round(), 0)
        self.assertEqual(game.player_turn(), 0)
        self.assertEqual(game.cards_left(), 11)
        self.assertTrue(game.active())
        self.assertFalse(game.over())

        players = game.players()
        player = players[0]
        target = players[1]
        recent_action = player.actions[0]

        self.assertTrue(PlayerTools.is_playing(player))
        self.assertEqual(player.hand_card, Card.handmaid)
        self.assertEqual(game.deck()[0], Card.guard)
        self.assertTrue(PlayerActionTools.is_blank(recent_action))
        for action in player.actions:
            self.assertTrue(PlayerActionTools.is_blank(action))
Beispiel #21
0
    def replay(seed, action_sequence=None):
        """Generate a game from a recorded set of actions"""
        action_sequence = action_sequence if action_sequence is not None else []
        action_sequence = np.array(action_sequence, dtype=np.uint8)
        action_sequence = PlayerActionTools.from_np_many(action_sequence)[::-1]
        game = Game.new(4, seed)

        while len(action_sequence) > 0:
            if not game.is_current_player_playing():
                game = game.skip_eliminated_player()
            else:
                action = action_sequence.pop()
                game = game._move(action)

        return game
Beispiel #22
0
    def is_action_valid(self, action):
        """Tests if an action is valid given the current game state"""
        player = self.player()

        # if player is out, only valid action is no action
        if player.hand_card == Card.noCard:
            return PlayerActionTools.is_blank(action)

        target_player = self._players[action.player_target]
        player_hand = [player.hand_card, self._deck[0]]

        # cannot discard a card not in the hand
        if action.discard not in player_hand:
            return False

        new_hand_card = Game.new_hand_card(action.discard, player_hand)

        # countess must be discarded if the other card is king/prince
        if new_hand_card == Card.countess and \
                (action.discard == Card.prince or action.discard == Card.king):
            return False

        # cannot target an invalid player
        if not self._is_valid_player_target(action.player_target):
            return False

        # cannot mis-target a card
        if self.player_turn() == action.player_target and action.discard in Card.only_other:
            return False
        if self.player_turn() != action.player_target and action.discard in Card.only_self:
            return False

        if not PlayerTools.is_playing(target_player):
            return False

        # Cannot guess guard or no card
        if action.discard == Card.guard and (
                action.guess == Card.guard or action.guess == Card.noCard):
            return False

        return True
Beispiel #23
0
def display(game, actions):
    """Print a game to the console"""
    lst = [str(i) for i in PlayerActionTools.to_np_many(actions)]
    print(",".join(lst))
    for line in game.to_str():
        print(line)
Beispiel #24
0
 def skip_eliminated_player(self, throw=False):
     """If the current player is eliminated, skip to next"""
     if self.is_current_player_playing():
         return self
     return self._move(PlayerActionTools.blank(), throw)
Beispiel #25
0
 def test_to_np(self):
     """Action to a numpy array"""
     action = PlayerAction(1, 3, 5, 0)
     arr = np.array([1, 3, 5, 0], dtype=np.uint8)
     self.assertTrue((PlayerActionTools.to_np(action) == arr).all())