Example #1
0
 def test_proceed_game(self):
     game = Game()
     game.init_game()
     while not game.is_over():
         legal_actions = game.judge.get_legal_actions()
         action = np.random.choice(legal_actions)
         _, _ = game.step(action)
     self.assertEqual(game.actions[-1].action_id, score_player_1_action_id)
Example #2
0
def can_gin(game: GinRummyGame) -> bool:
    result = False
    last_action = game.get_last_action()
    last_action_type = type(last_action)
    if last_action_type is DrawCardAction or last_action_type is PickUpDiscardAction:
        current_player = game.get_current_player()
        hand = current_player.hand
        going_out_deadwood_count = game.settings.going_out_deadwood_count
        meld_clusters = melding.get_meld_clusters(hand=hand,
                                                  going_out_deadwood_count=going_out_deadwood_count,
                                                  is_going_out=True)
        if meld_clusters:
            deadwood_counts = [utils.get_deadwood_count(hand, meld_cluster) for meld_cluster in meld_clusters]
            result = min(deadwood_counts) == 0
    return result
Example #3
0
 def test_init_game(self):
     game = Game()
     state, current_player = game.init_game()
     opponent_player = (current_player + 1) % 2
     self.assertEqual(len(game.round.move_sheet), 1)
     self.assertIn(current_player, [0, 1])
     self.assertIn(game.round.dealer_id, [0, 1])
     self.assertEqual(len(game.actions), 0)
     self.assertEqual(opponent_player,
                      game.round.dealer_id)  # opponent_player is dealer
     self.assertEqual(len(game.round.players[opponent_player].hand),
                      10)  # dealer has 10 cards
     self.assertEqual(len(game.round.players[current_player].hand),
                      11)  # current_player has 11 cards
     self.assertEqual(len(game.round.dealer.shuffled_deck), 52)
     self.assertEqual(len(game.round.dealer.stock_pile), 31)
     self.assertEqual(state['player_id'], current_player)
     self.assertEqual(len(state['hand']), 11)
Example #4
0
def get_knock_cards(game: GinRummyGame) -> List[Card]:
    """
    :param game: GinRummyGame
    :return: list[Card] of cards that player can knock with
    """
    knock_cards = set()
    last_action = game.get_last_action()
    last_action_type = type(last_action)
    if last_action_type is DrawCardAction or last_action_type is PickUpDiscardAction:
        current_player = game.get_current_player()
        hand = current_player.hand
        going_out_deadwood_count = game.settings.going_out_deadwood_count
        meld_clusters = melding.get_meld_clusters(hand=hand,
                                                  going_out_deadwood_count=going_out_deadwood_count,
                                                  is_going_out=True)
        deadwood_cluster = [utils.get_deadwood(hand, meld_cluster) for meld_cluster in meld_clusters]
        for deadwood in deadwood_cluster:
            for card in deadwood:
                knock_cards.add(card)
    return list(knock_cards)
Example #5
0
 def test_step(self):
     game = Game()
     _, current_player = game.init_game()
     opponent_player = (current_player + 1) % 2
     action = np.random.choice(game.judge.get_legal_actions())
     self.assertIn(action.action_id,
                   put_action_ids)  # should be a put action
     _, next_player = game.step(action)
     if not game.is_over():
         self.assertEqual(next_player, opponent_player)
     if not game.is_over():
         action = np.random.choice(game.judge.get_legal_actions())
         self.assertIn(action.action_id,
                       get_action_ids)  # should be a get action
         _, next_player = game.step(action)
         self.assertEqual(next_player,
                          opponent_player)  # keep turn to put card
Example #6
0
 def __init__(self, config):
     self.game = Game()
     super().__init__(config=config)
     self.state_shape = [5, 52]
     self.judge = GinRummyJudge(game=self.game)
     self.scorer = scorers.GinRummyScorer()
Example #7
0
class GinRummyEnv(Env):
    ''' GinRummy Environment
    '''

    def __init__(self, config):
        self.game = Game()
        super().__init__(config=config)
        self.state_shape = [5, 52]
        self.judge = GinRummyJudge(game=self.game)
        self.scorer = scorers.GinRummyScorer()

    def _extract_state(self, state):  # 200213 don't use state ???
        ''' Encode state

        Args:
            state (dict): dict of original state

        Returns:
            numpy array: 5 * 52 array
                         5 : current hand (1 if card in hand else 0)
                             top_discard (1 if card is top discard else 0)
                             dead_cards (1 for discards except for top_discard else 0)
                             opponent known cards (likewise)
                             unknown cards (likewise)  # is this needed ??? 200213
        '''
        if self.game.is_over():
            obs = np.array([utils.encode_cards([]) for _ in range(5)])
            extracted_state = {'obs': obs, 'legal_actions': self._get_legal_actions()}
        else:
            discard_pile = self.game.round.dealer.discard_pile
            stock_pile = self.game.round.dealer.stock_pile
            top_discard = [] if not discard_pile else [discard_pile[-1]]
            dead_cards = discard_pile[:-1]
            current_player = self.game.get_current_player()
            opponent = self.game.round.players[(current_player.player_id + 1) % 2]
            known_cards = opponent.known_cards
            unknown_cards = stock_pile + [card for card in opponent.hand if card not in known_cards]
            hand_rep = utils.encode_cards(current_player.hand)
            top_discard_rep = utils.encode_cards(top_discard)
            dead_cards_rep = utils.encode_cards(dead_cards)
            known_cards_rep = utils.encode_cards(known_cards)
            unknown_cards_rep = utils.encode_cards(unknown_cards)
            rep = [hand_rep, top_discard_rep, dead_cards_rep, known_cards_rep, unknown_cards_rep]
            obs = np.array(rep)
            extracted_state = {'obs': obs, 'legal_actions': self._get_legal_actions()}
        return extracted_state

    def get_payoffs(self):
        ''' Get the payoffs of players. Must be implemented in the child class.

        Returns:
            payoffs (list): a list of payoffs for each player
        '''
        payoffs = self.scorer.get_payoffs(game=self.game)
        return payoffs

    def _decode_action(self, action_id) -> ActionEvent:  # FIXME 200213 should return str
        ''' Action id -> the action in the game. Must be implemented in the child class.

        Args:
            action_id (int): the id of the action

        Returns:
            action (ActionEvent): the action that will be passed to the game engine.
        '''
        return self.game.decode_action(action_id=action_id)

    def _get_legal_actions(self):
        ''' Get all legal actions for current state

        Returns:
            legal_actions (list): a list of legal actions' id
        '''
        legal_actions = self.judge.get_legal_actions()
        legal_actions_ids = [action_event.action_id for action_event in legal_actions]
        return legal_actions_ids

    def _load_model(self):
        ''' Load pretrained/rule model

        Returns:
            model (Model): A Model object
        '''
        assert False  # FIXME: stub
        return models.load('uno-rule-v1')  # FIXME: stub

    def set_scorer(self, printing_configuration: bool = False,
                   get_payoff: Callable[[GinRummyPlayer, Game], int or float] = None):
        if self.game.settings.scorer_name == "GinRummyScorer":
            self.scorer = scorers.GinRummyScorer(get_payoff=get_payoff)
        elif self.game.settings.scorer_name == "HighLowScorer":
            self.scorer = scorers.HighLowScorer(get_payoff=get_payoff)
        else:
            raise Exception("GinRummyEnv: cannot determine scorer.")
        if printing_configuration:
            print("")
            print("========== Scorer ==========")
            print("Scorer is", self.scorer.name)
Example #8
0
 def test_get_state(self):
     game = Game()
     state, _ = game.init_game()
     self.assertEqual(len(state), 6)
Example #9
0
 def test_get_action_num(self):
     game = Game()
     action_num = game.get_action_num()
     self.assertEqual(action_num, 110)
Example #10
0
 def test_get_player_num(self):
     game = Game()
     player_num = game.get_player_num()
     self.assertEqual(player_num, 2)
Example #11
0
 def test_get_state(self):
     game = Game()
     state, current_player = game.init_game()
     self.assertEqual(len(state), 6)
Example #12
0
 def test_get_num_actions(self):
     game = Game()
     num_actions = game.get_num_actions()
     self.assertEqual(num_actions, 110)
Example #13
0
 def test_get_num_players(self):
     game = Game()
     num_players = game.get_num_players()
     self.assertEqual(num_players, 2)
Example #14
0
 def __init__(self, config):
     self.game = Game()
     super().__init__(config=config)
     self.state_shape = [5, 52]
Example #15
0
class GinRummyEnv(Env):
    ''' GinRummy Environment
    '''
    def __init__(self, config):
        self.game = Game()
        super().__init__(config=config)
        self.state_shape = [5, 52]

    def _extract_state(self, state):  # 200213 don't use state ???
        ''' Encode state

        Args:
            state (dict): dict of original state

        Returns:
            numpy array: 5 * 52 array
                         5 : current hand (1 if card in hand else 0)
                             top_discard (1 if card is top discard else 0)
                             dead_cards (1 for discards except for top_discard else 0)
                             opponent known cards (likewise)
                             unknown cards (likewise)  # is this needed ??? 200213
        '''
        if self.game.is_over():
            obs = np.array([utils.encode_cards([]) for _ in range(5)])
            extracted_state = {
                'obs': obs,
                'legal_actions': self._get_legal_actions()
            }
        else:
            discard_pile = self.game.round.dealer.discard_pile
            stock_pile = self.game.round.dealer.stock_pile
            top_discard = [] if not discard_pile else [discard_pile[-1]]
            dead_cards = discard_pile[:-1]
            current_player = self.game.get_current_player()
            opponent = self.game.round.players[(current_player.player_id + 1) %
                                               2]
            known_cards = opponent.known_cards
            unknown_cards = stock_pile + [
                card for card in opponent.hand if card not in known_cards
            ]
            hand_rep = utils.encode_cards(current_player.hand)
            top_discard_rep = utils.encode_cards(top_discard)
            dead_cards_rep = utils.encode_cards(dead_cards)
            known_cards_rep = utils.encode_cards(known_cards)
            unknown_cards_rep = utils.encode_cards(unknown_cards)
            rep = [
                hand_rep, top_discard_rep, dead_cards_rep, known_cards_rep,
                unknown_cards_rep
            ]
            obs = np.array(rep)
            extracted_state = {
                'obs': obs,
                'legal_actions': self._get_legal_actions()
            }
        return extracted_state

    def get_payoffs(self):
        ''' Get the payoffs of players. Must be implemented in the child class.

        Returns:
            payoffs (list): a list of payoffs for each player
        '''
        payoffs = self.game.judge.scorer.get_payoffs(game=self.game)
        return payoffs

    def _decode_action(
            self, action_id) -> ActionEvent:  # FIXME 200213 should return str
        ''' Action id -> the action in the game. Must be implemented in the child class.

        Args:
            action_id (int): the id of the action

        Returns:
            action (ActionEvent): the action that will be passed to the game engine.
        '''
        return self.game.decode_action(action_id=action_id)

    def _get_legal_actions(self):
        ''' Get all legal actions for current state

        Returns:
            legal_actions (list): a list of legal actions' id
        '''
        legal_actions = self.game.judge.get_legal_actions()
        legal_actions_ids = [
            action_event.action_id for action_event in legal_actions
        ]
        return legal_actions_ids

    def _load_model(self):
        ''' Load pre-trained/rule model

        Returns:
            model (Model): A Model object
        '''
        raise NotImplementedError