def test_valid_actions(self): """Test if the random agent acts correctly.""" game = TestGames.replay(1, [ 1, 1, 3, 0, 4, 1, 0, 0, 1, 1, 3, 0, 1, 2, 6, 0, 7, 0, 0, 0, 1, 2, 2, 0, 8, 2, 0, 0, 1, 1, 5, 0 ]) actions = Agent.valid_actions(game, 782) self.assertEqual(len(actions), 2) # player can use baron or priest, at 1 or 3 self.assertListEqual(actions, [ PlayerAction( discard=Card.priest, player_target=3, guess=0, revealed_card=0), PlayerAction( discard=Card.baron, player_target=3, guess=0, revealed_card=0) ]) agent = AgentRandom(4) action = agent.move(game) self.assertEqual( action, PlayerAction(discard=Card.baron, player_target=1, guess=0, revealed_card=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))
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)
def test_from_np(self): """Player from a numpy array""" player = Player(1, [PlayerAction(1, 3, 5, 0), PlayerAction(3, 0, 0, 2)]) arr = np.array([1, 1, 3, 5, 0, 3, 0, 0, 2], dtype=np.uint8) player_res = PlayerTools.from_np(arr) self.assertEqual(player_res, player)
def test_to_np(self): """Player to a numpy array""" player = Player(1, [PlayerAction(1, 3, 5, 0), PlayerAction(3, 0, 0, 0)]) arr = np.array([1, 1, 3, 5, 0, 3, 0, 0, 0], dtype=np.uint8) arr_res = PlayerTools.to_np(player) self.assertEqual(len(arr_res), len(arr)) self.assertTrue((arr_res == arr).all())
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())
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)
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))
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))
def test_end_elimination(self): """Reach the end of a game by elimination""" game = Game.new(4, 0) game, _ = game.move( PlayerAction(Card.guard, 1, Card.priest, Card.noCard)) game = game.skip_eliminated_player() game, _ = game.move( PlayerAction(Card.guard, 3, Card.countess, Card.noCard)) game, _ = game.move( PlayerAction(Card.handmaid, 3, Card.noCard, Card.noCard)) game, _ = game.move( PlayerAction(Card.countess, 0, Card.noCard, Card.noCard)) game = game.skip_eliminated_player() game, _ = game.move( PlayerAction(Card.baron, 3, Card.noCard, Card.noCard)) game, _ = game.move( PlayerAction(Card.guard, 2, Card.handmaid, Card.noCard)) self.assertFalse(game.over()) game, _ = game.move( PlayerAction(Card.princess, 0, Card.noCard, Card.noCard)) self.assertEqual(game.cards_left(), 4) self.assertTrue(game.over())
def test_valid_actions(self): """Test if the actions generated for a player at a game state is valid.""" game = TestGames.replay(1, [ 1, 1, 3, 0, 4, 1, 0, 0, 1, 1, 3, 0, 1, 2, 6, 0, 7, 0, 0, 0, 1, 2, 2, 0, 8, 2, 0, 0, 1, 1, 5, 0 ]) actions = Agent.valid_actions(game, 782) self.assertEqual(len(actions), 2) # player can use baron or priest, at 1 or 3 self.assertListEqual(actions, [ PlayerAction( discard=Card.priest, player_target=3, guess=0, revealed_card=0), PlayerAction( discard=Card.baron, player_target=3, guess=0, revealed_card=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))
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)
def test_last_player_win(self): """Win the game by knocking out the opposing player""" game = Game.new(2, 3) action = PlayerAction(Card.guard, 1, Card.king, 0) game, _ = game.move(action) self.assertEqual(game.round(), 0) self.assertEqual(game.cards_left(), 12) self.assertFalse(game.active()) self.assertTrue(game.over()) self.assertEqual(0, game.winner())
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))
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))
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_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))
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))
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))
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))
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))
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))
def get_action(): """Get a player action from the console""" discard = get_int("Discard Card") player_target = get_int("Player Target") guess = get_int("Guessed Card") if discard == Card.guard else 0 return PlayerAction(discard, player_target, guess, 0)
def valid_actions(game, seed=451): """Returns valid moves based on a current game""" player_self = game.player_turn() opponents = game.opponent_turn() possible_actions = [ # Actions always targeting the current player PlayerAction(Card.king, player_self, Card.noCard, Card.noCard, Card.noCard, player_self, 0), PlayerAction(Card.guard, player_self, Card.noCard, Card.noCard, Card.noCard, player_self, 0), PlayerAction(Card.priest, player_self, Card.noCard, Card.noCard, Card.noCard, player_self, 0), PlayerAction(Card.baron, player_self, Card.noCard, Card.noCard, Card.noCard, player_self, 0), PlayerAction(Card.prince, player_self, Card.noCard, Card.noCard, Card.noCard, player_self, 0), PlayerAction(Card.handmaid, player_self, Card.noCard, Card.noCard, Card.noCard, player_self, 0), PlayerAction(Card.countess, player_self, Card.noCard, Card.noCard, Card.noCard, player_self, 0), PlayerAction(Card.princess, player_self, Card.noCard, Card.noCard, Card.noCard, player_self, 0) ] for rel_idx in range(len(game._players)): target_idx = game.absolute_player_idx(rel_idx, player_self) possible_actions.extend([ PlayerAction(Card.guard, target_idx, Card.priest, Card.noCard, Card.noCard, player_self, 0), PlayerAction(Card.guard, target_idx, Card.baron, Card.noCard, Card.noCard, player_self, 0), PlayerAction(Card.guard, target_idx, Card.handmaid, Card.noCard, Card.noCard, player_self, 0), PlayerAction(Card.guard, target_idx, Card.prince, Card.noCard, Card.noCard, player_self, 0), PlayerAction(Card.guard, target_idx, Card.king, Card.noCard, Card.noCard, player_self, 0), PlayerAction(Card.guard, target_idx, Card.countess, Card.noCard, Card.noCard, player_self, 0), PlayerAction(Card.guard, target_idx, Card.princess, Card.noCard, Card.noCard, player_self, 0), PlayerAction(Card.priest, target_idx, Card.noCard, Card.noCard, Card.noCard, player_self, 0), PlayerAction(Card.baron, target_idx, Card.noCard, Card.noCard, Card.noCard, player_self, 0), PlayerAction(Card.king, target_idx, Card.noCard, Card.noCard, Card.noCard, player_self, 0), PlayerAction(Card.prince, target_idx, Card.noCard, Card.noCard, Card.noCard, player_self, 0) ]) actions = [ action for action in possible_actions if game.is_action_valid(action) ] return actions
def valid_actions(game, seed=451): """Returns valid moves based on a current game""" random.seed(seed + game.round()) player_self = game.player_turn() opponents = game.opponent_turn() actions_possible = [ PlayerAction(Card.guard, random.choice(opponents), Card.priest, Card.noCard), PlayerAction(Card.guard, random.choice(opponents), Card.baron, Card.noCard), PlayerAction(Card.guard, random.choice(opponents), Card.handmaid, Card.noCard), PlayerAction(Card.guard, random.choice(opponents), Card.prince, Card.noCard), PlayerAction(Card.guard, random.choice(opponents), Card.king, Card.noCard), PlayerAction(Card.guard, random.choice(opponents), Card.countess, Card.noCard), PlayerAction(Card.guard, random.choice(opponents), Card.princess, Card.noCard), PlayerAction(Card.priest, random.choice(opponents), Card.noCard, Card.noCard), PlayerAction(Card.baron, random.choice(opponents), Card.noCard, Card.noCard), PlayerAction(Card.king, random.choice(opponents), Card.noCard, Card.noCard), PlayerAction(Card.prince, random.choice(opponents), Card.noCard, Card.noCard), PlayerAction(Card.prince, player_self, Card.noCard, Card.noCard), PlayerAction(Card.handmaid, player_self, Card.noCard, Card.noCard), PlayerAction(Card.countess, player_self, Card.noCard, Card.noCard), PlayerAction(Card.princess, player_self, Card.noCard, Card.noCard) ] actions = [action for action in actions_possible if game.is_action_valid(action)] return actions
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())