def test_first_legal_bids(self): game = Game() _, current_player_id = game.init_game() for _ in range(3): legal_actions = game.judger.get_legal_actions() self.assertEqual(len(legal_actions), 36) action = PassAction() self.assertTrue(action in legal_actions) _, next_player_id = game.step(action) legal_actions = game.judger.get_legal_actions() self.assertEqual(len(legal_actions), 36) self.assertTrue(PassAction() in legal_actions)
def test_step(self): game = Game() _, current_player_id = game.init_game() legal_actions = game.judger.get_legal_actions() action = np.random.choice(legal_actions) print( f'test_step current_player_id={current_player_id} action={action} legal_actions={[str(action) for action in legal_actions]}' ) _, next_player_id = game.step(action) next_legal_actions = game.judger.get_legal_actions() print( f'test_step next_player_id={next_player_id} next_legal_actions={[str(action) for action in next_legal_actions]}' )
def test_init_game(self): player_ids = list(range(4)) game = Game() state, current_player = game.init_game() self.assertEqual(len(game.round.move_sheet), 1) self.assertIn(current_player, player_ids) self.assertEqual(len(game.actions), 0) self.assertEqual(len(game.round.players[current_player].hand), 13) # current_player has 13 cards self.assertEqual(len(game.round.dealer.shuffled_deck), 52) self.assertEqual(len(game.round.dealer.stock_pile), 0) self.assertEqual(state['player_id'], current_player) self.assertEqual(len(state['hand']), 13)
def test_pass_out_hand(self): game = Game() _, current_player_id = game.init_game() for _ in range(4): legal_actions = game.judger.get_legal_actions() action = PassAction() self.assertTrue(action in legal_actions) _, next_player_id = game.step(action) self.assertTrue(not game.round.contract_bid_move) self.assertTrue(game.round.is_bidding_over()) self.assertTrue(game.is_over()) self.assertTrue(not game.round.get_declarer()) self.assertTrue(not game.round.get_dummy()) self.assertTrue(not game.round.get_left_defender()) self.assertTrue(not game.round.get_right_defender())
def test_print_scene(self): game = Game() next_state, next_player_id = game.init_game() deal_hand_move = game.round.move_sheet[0] self.assertTrue(isinstance(deal_hand_move, DealHandMove)) while not game.is_over(): current_player_id = game.round.current_player_id self.assertEqual(current_player_id, next_player_id) legal_actions = game.judger.get_legal_actions() action = np.random.choice(legal_actions) game.round.print_scene() next_state, next_player_id = game.step(action) game.round.print_scene() for player_id in range(4): player = game.round.players[player_id] hand = player.hand self.assertTrue(not hand)
def extract_state(self, game: BridgeGame): ''' Extract useful information from state for RL. Args: game (BridgeGame): The game Returns: (numpy.array): The extracted state ''' extracted_state = {} legal_actions: OrderedDict = self.get_legal_actions(game=game) raw_legal_actions = list(legal_actions.keys()) current_player = game.round.get_current_player() current_player_id = current_player.player_id # construct hands_rep of hands of players hands_rep = [np.zeros(52, dtype=int) for _ in range(4)] if not game.is_over(): for card in game.round.players[current_player_id].hand: hands_rep[current_player_id][card.card_id] = 1 if game.round.is_bidding_over(): dummy = game.round.get_dummy() other_known_player = dummy if dummy.player_id != current_player_id else game.round.get_declarer( ) for card in other_known_player.hand: hands_rep[other_known_player.player_id][card.card_id] = 1 # construct trick_pile_rep trick_pile_rep = [np.zeros(52, dtype=int) for _ in range(4)] if game.round.is_bidding_over() and not game.is_over(): trick_moves = game.round.get_trick_moves() for move in trick_moves: player = move.player card = move.card trick_pile_rep[player.player_id][card.card_id] = 1 # construct hidden_card_rep (during trick taking phase) hidden_cards_rep = np.zeros(52, dtype=int) if not game.is_over(): if game.round.is_bidding_over(): declarer = game.round.get_declarer() if current_player_id % 2 == declarer.player_id % 2: hidden_player_ids = [(current_player_id + 1) % 2, (current_player_id + 3) % 2] else: hidden_player_ids = [ declarer.player_id, (current_player_id + 2) % 2 ] for hidden_player_id in hidden_player_ids: for card in game.round.players[hidden_player_id].hand: hidden_cards_rep[card.card_id] = 1 else: for player in game.round.players: if player.player_id != current_player_id: for card in player.hand: hidden_cards_rep[card.card_id] = 1 # construct vul_rep vul_rep = np.array(game.round.tray.vul, dtype=int) # construct dealer_rep dealer_rep = np.zeros(4, dtype=int) dealer_rep[game.round.tray.dealer_id] = 1 # construct current_player_rep current_player_rep = np.zeros(4, dtype=int) current_player_rep[current_player_id] = 1 # construct is_bidding_rep is_bidding_rep = np.array([1] if game.round.is_bidding_over() else [0]) # construct bidding_rep bidding_rep = np.zeros(self.max_bidding_rep_index, dtype=int) bidding_rep_index = game.round.dealer_id # no_bid_action_ids allocated at start so that north always 'starts' the bidding for move in game.round.move_sheet: if bidding_rep_index >= self.max_bidding_rep_index: break elif isinstance(move, PlayCardMove): break elif isinstance(move, CallMove): bidding_rep[bidding_rep_index] = move.action.action_id bidding_rep_index += 1 # last_bid_rep last_bid_rep = np.zeros(self.last_bid_rep_size, dtype=int) last_move = game.round.move_sheet[-1] if isinstance(last_move, CallMove): last_bid_rep[last_move.action.action_id - ActionEvent.no_bid_action_id] = 1 # bid_amount_rep and trump_suit_rep bid_amount_rep = np.zeros(8, dtype=int) trump_suit_rep = np.zeros(5, dtype=int) if game.round.is_bidding_over( ) and not game.is_over() and game.round.play_card_count == 0: contract_bid_move = game.round.contract_bid_move if contract_bid_move: bid_amount_rep[contract_bid_move.action.bid_amount] = 1 bid_suit = contract_bid_move.action.bid_suit bid_suit_index = 4 if not bid_suit else BridgeCard.suits.index( bid_suit) trump_suit_rep[bid_suit_index] = 1 rep = [] rep += hands_rep rep += trick_pile_rep rep.append(hidden_cards_rep) rep.append(vul_rep) rep.append(dealer_rep) rep.append(current_player_rep) rep.append(is_bidding_rep) rep.append(bidding_rep) rep.append(last_bid_rep) rep.append(bid_amount_rep) rep.append(trump_suit_rep) obs = np.concatenate(rep) extracted_state['obs'] = obs extracted_state['legal_actions'] = legal_actions extracted_state['raw_legal_actions'] = raw_legal_actions extracted_state['raw_obs'] = obs return extracted_state
def test_get_num_actions(self): game = Game() num_actions = game.get_num_actions() self.assertEqual(num_actions, 91)
def test_get_num_players(self): game = Game() num_players = game.get_num_players() self.assertEqual(num_players, 4)