def test_get_legal_actions(self):
        self.env.game.get_legal_actions = MagicMock(return_value=[
            Card(Spades, Queen),
            Card(Clubs, Ten),
            Card(Diamonds, Ace),
            Card(Hearts, Jack)
        ])
        expected = [2, 10, 17, 19]

        self.assertEqual(expected, self.env._get_legal_actions())
Example #2
0
    def test_judge_round_when_no_active_marriage(self):
        np_random = np.random.RandomState()
        judger = Judger(np_random)
        active_marriage = None
        stock = [(0, Card(Clubs, Ten)), (1, Card(Hearts, Nine)),
                 (2, Card(Clubs, Ace))]
        expected = (2, 21)

        result = judger.judge_round(stock, active_marriage)

        self.assertEqual(expected, result)
    def test_encode_cards_set(self):
        cards = [
            Card(Spades, Queen),
            Card(Clubs, Ten),
            Card(Diamonds, Ace),
            Card(Hearts, Jack)
        ]
        expected = [2, 10, 17, 19]

        result = self.env._encode_cards_set(cards)

        self.assertSetEqual(set(expected), set(result))
Example #4
0
 def _check_marriage(player: ThousandSchnapsenPlayer, card: Card) -> bool:
     """ Check if new marriage is activated 
     
     Args:
         player (ThousandSchnapsenPlayer): Current player
         card (Card): Card to put on the stock
         
     Return:
         (bool): True if new marriage activated, otherwise False
     """
     if card.rank == King and (Card(card.suit, Queen) in player.hand):
         return True
     if card.rank == Queen and (Card(card.suit, King) in player.hand):
         return True
     return False
Example #5
0
    def test_get_legal_actions_when_cannot_put_same_suit_nor_beat(self):
        num_players = 3
        np_random = np.random.RandomState()
        cur_round = Round(num_players, np_random)
        player = Player(0, np_random)
        cards = {
            Card(Spades, Ten),
            Card(Diamonds, Nine),
            Card(Spades, Queen),
        }
        player.hand = cards
        stock = [(2, Card(Clubs, Ace))]
        active_marriage = Hearts
        expected = cards

        result = cur_round.get_legal_actions(stock, active_marriage, player)

        self.assertSetEqual(expected, result)
Example #6
0
    def _reason_about_cards(self, action: Card, trump: bool):
        current_player = self.get_player_id()
        for i in range(self.player_num):
            self.possible_cards[i] -= {action}
            self.certain_cards[i] -= {action}

        self.possible_cards[current_player] -= self._get_impossible_cards(
            action)

        if trump:
            second_marriage_part = Card(action.suit,
                                        King if action.rank == Queen else King)
            self.certain_cards[current_player] |= {second_marriage_part}
        if len(self.state['stock']) == 0 and not trump and action.rank in {
                Queen, King
        }:
            second_marriage_part = Card(action.suit,
                                        King if action.rank == Queen else King)
            self.possible_cards[current_player] -= {second_marriage_part}
Example #7
0
    def test_proceed_round(self):
        num_players = 3
        np_random = np.random.RandomState()
        cur_round = Round(num_players, np_random)
        game_pointer = 0
        players = [
            Player(player_id, np_random) for player_id in range(num_players)
        ]
        stock = [(2, Card(Diamonds, Ten))]
        used_marriages = set()
        card = Card(Diamonds, Queen)
        players[game_pointer].hand = [card]
        expected = (1, None)

        result = cur_round.proceed_round(game_pointer, players, stock,
                                         used_marriages, card)

        self.assertEqual(expected, result)
        self.assertEqual((game_pointer, card), stock[1])
        self.assertEqual(0, len(players[game_pointer].hand))
Example #8
0
    def test_get_legal_actions_when_stock_empty(self):
        num_players = 3
        np_random = np.random.RandomState()
        cur_round = Round(num_players, np_random)
        player = Player(0, np_random)
        cards = {
            Card(Spades, Ten),
            Card(Diamonds, Nine),
            Card(Hearts, Queen),
            Card(Spades, King),
            Card(Clubs, Ace),
        }
        player.hand = cards
        stock = []
        active_marriage = None
        expected = cards

        result = cur_round.get_legal_actions(stock, active_marriage, player)

        self.assertSetEqual(expected, result)
    def test_extract_state_when_round_in_progress(self):
        state = {
            'stock': [(1, Card(Diamonds, Jack))],
            'active_marriage': Hearts,
            'used_marriages': {Hearts, Diamonds},
            'hand': frozenset([Card(Diamonds, Queen),
                               Card(Spades, Nine)]),
            'players_used': [[], [Card(Diamonds, Jack)], []],
            'current_player': 2
        }
        expected = np.zeros(152, dtype=int)
        expected[[0, 14]] = 1  # hand
        expected[24:48] = 1  # common possible
        expected[[24 + 0, 24 + 14]] = 0  # remove hand from possible
        expected[109] = 1  # stock
        expected[147] = 1  # active marriage
        expected[[150, 151]] = 1  # used marriages

        result = self.env._extract_state(state)['obs']

        self.assertTrue(np.allclose(expected, result))
Example #10
0
    def _decode_action(self, action_id):
        """ Decode Action id to the action in the game.

        Arg:
            action_id (int): The id of the action

        Return:
            (Card): The action that will be passed to the game engine.
        """
        suit = Card.valid_suit[action_id // CARDS_PER_SUIT_COUNT]
        rank = Card.valid_rank[action_id % CARDS_PER_SUIT_COUNT]
        return Card(suit, rank)
Example #11
0
    def test_proceed_round_when_marriage_activated(self):
        num_players = 3
        np_random = np.random.RandomState()
        cur_round = Round(num_players, np_random)
        game_pointer = 0
        players = [
            Player(player_id, np_random) for player_id in range(num_players)
        ]
        stock = []
        used_marriages = set()
        card = Card(Diamonds, Queen)
        players[game_pointer].hand = [card, Card(Diamonds, King)]
        players[game_pointer].points = 0
        expected = (1, Diamonds)

        result = cur_round.proceed_round(game_pointer, players, stock,
                                         used_marriages, card)

        self.assertEqual(expected, result)
        self.assertEqual((game_pointer, card), stock[0])
        self.assertEqual(80, players[game_pointer].points)
        self.assertEqual(1, len(players[game_pointer].hand))
    def test_encode_card_when_card_is_defined(self):
        expected = 10

        result = self.env._encode_card(Card(Clubs, Ten))

        self.assertEqual(expected, result)
class TestThousandSchnapsenEnv(unittest.TestCase):
    def __init__(self, *args):
        super().__init__(*args)
        self.env = make('thousand-schnapsen', config={'seed': 0})
        self.env.reset()

    @data((2, Card(Spades, Queen)), (19, Card(Hearts, Jack)),
          (10, Card(Clubs, Ten)), (17, Card(Diamonds, Ace)))
    @unpack
    def test_decode_action(self, action_id: int, card: Card):
        decoded_action = self.env._decode_action(action_id)
        self.assertEqual(card, decoded_action)

    def test_get_legal_actions(self):
        self.env.game.get_legal_actions = MagicMock(return_value=[
            Card(Spades, Queen),
            Card(Clubs, Ten),
            Card(Diamonds, Ace),
            Card(Hearts, Jack)
        ])
        expected = [2, 10, 17, 19]

        self.assertEqual(expected, self.env._get_legal_actions())

    def test_encode_cards_set(self):
        cards = [
            Card(Spades, Queen),
            Card(Clubs, Ten),
            Card(Diamonds, Ace),
            Card(Hearts, Jack)
        ]
        expected = [2, 10, 17, 19]

        result = self.env._encode_cards_set(cards)

        self.assertSetEqual(set(expected), set(result))

    def test_encode_card_when_card_is_none(self):
        expected = []

        result = self.env._encode_card(None)

        self.assertSetEqual(set(expected), set(result))

    def test_encode_card_when_card_is_defined(self):
        expected = 10

        result = self.env._encode_card(Card(Clubs, Ten))

        self.assertEqual(expected, result)

    def test_encode_marriage_when_suit_is_none(self):
        expected = []

        result = self.env._encode_marriage(None)

        self.assertSetEqual(set(expected), set(result))

    def test_encode_marriage_when_suit_is_defined(self):
        expected = 2

        result = self.env._encode_marriage(Diamonds)

        self.assertEqual(expected, result)

    def test_encode_marriages(self):
        expected = [1, 3]

        result = self.env._encode_marriages({Clubs, Hearts})

        self.assertSetEqual(set(expected), set(result))

    def test_encode(self):
        code = np.zeros(10, dtype=int)
        chunk = [1, 2]
        start_index = 2
        length = 4
        expected = np.zeros(10, dtype=int)
        expected[[3, 4]] = 1

        end_index = self.env._encode(code, chunk, start_index, length)

        self.assertTrue(np.allclose(expected, code))
        self.assertEqual(6, end_index)

    def test_extract_state_when_round_in_progress(self):
        state = {
            'stock': [(1, Card(Diamonds, Jack))],
            'active_marriage': Hearts,
            'used_marriages': {Hearts, Diamonds},
            'hand': frozenset([Card(Diamonds, Queen),
                               Card(Spades, Nine)]),
            'players_used': [[], [Card(Diamonds, Jack)], []],
            'current_player': 2
        }
        expected = np.zeros(152, dtype=int)
        expected[[0, 14]] = 1  # hand
        expected[24:48] = 1  # common possible
        expected[[24 + 0, 24 + 14]] = 0  # remove hand from possible
        expected[109] = 1  # stock
        expected[147] = 1  # active marriage
        expected[[150, 151]] = 1  # used marriages

        result = self.env._extract_state(state)['obs']

        self.assertTrue(np.allclose(expected, result))

    def test_extract_state_when_new_round(self):
        state = {
            'stock': [(1, Card(Diamonds, Jack)), (1, Card(Diamonds, King)),
                      (1, Card(Diamonds, Ace))],
            'active_marriage':
            Hearts,
            'used_marriages': {Hearts, Diamonds},
            'hand':
            frozenset([Card(Diamonds, Queen),
                       Card(Spades, Nine)]),
            'players_used': [[], [Card(Diamonds, Jack)], []],
            'current_player':
            2
        }
        expected = np.zeros(152, dtype=int)
        expected[[0, 14]] = 1  # hand
        expected[24:48] = 1  # common possible
        expected[[24 + 0, 24 + 14]] = 0  # remove hand from possible
        expected[147] = 1  # active marriage
        expected[[150, 151]] = 1  # used marriages

        result = self.env._extract_state(state)['obs']

        self.assertTrue(np.allclose(expected, result))
def get_color(suit: str) -> Set[Card]:
    ranks = ['9', 'J', 'Q', 'K', 'T', 'A']
    return {Card(suit, rank) for rank in ranks}
Example #15
0
def action_dto_to_env_action(action: Action) -> int:
    card = Card(rank=action.card.rank, suit=action.card.suit)
    return card.__hash__()