def test_get_legal_actions(self): game = BidGame(players, num_players, starting_player, num_cards_per_player, num_cards_dog, dog) game.init_game() actions = game.get_legal_actions() for action in actions: self.assertIn(action.get_str(), TarotBid.order.keys())
def test_get_payoffs_main(self): bid_game = BidGame(players, num_players, starting_player, num_cards_per_player, num_cards_dog, dog) bid_game.init_game() game = MainGame(num_players, num_cards_per_player, starting_player, players, taking_player_id, new_dog) game.init_game() while not game.is_over: actions = game.get_legal_actions() action = np.random.choice(actions) state, _ = game.step(action) print(len(state['hand'])) print(len(state['others_hand'])) print(len(state['played_cards'])) total_cards = len(state['hand']) + len(state['others_hand']) + len( state['played_cards']) if game.taking_bid <= 3: self.assertEqual(total_cards, 72) # Not counting the dog in it else: self.assertEqual( total_cards, 78) # Adding the dog in the others hand as not known cards payoffs = game.get_payoffs() total = 0 for _, payoff in payoffs.items(): total += payoff self.assertEqual(total, 0)
def init_game(self, number_of_deals: int = 0) -> (dict, int): """ Initialize players and state for bid game in a globalgame object :return: (tuple): containing : (dict): the current state (int): next player id """ self.current_game_part = 'BID' self.bid_over = False self.dog_over = False self.main_over = False self.number_of_deals = number_of_deals self.is_game_over = False self.players = [Player(i) for i in range(self.num_players)] self.dog = TarotDog() # Initialize bid Round self.bid_game = BidGame(self.players, self.num_players, self.starting_player, self.num_cards_per_player, self.num_cards_dog, self.dog) self.bid_game.init_game() player_id = self.bid_game.bid_round.current_player_id state = self.bid_game.get_state(player_id) return state, player_id
def test_init_cards_main(self): bid_game = BidGame(players, num_players, starting_player, num_cards_per_player, num_cards_dog, dog) bid_game.init_game() game = MainGame(num_players, num_cards_per_player, starting_player, players, taking_player_id, new_dog) state, _ = game.init_game() self.assertEqual(len(list(state['hand'])), game.num_cards_per_player)
def test_init_game(self): game = BidGame(players, num_players, starting_player, num_cards_per_player, num_cards_dog, dog) state, _ = game.init_game() self.assertIsInstance(state['max_bid'], int) self.assertEqual(len(state['hand']), game.num_cards_per_player) actions = state['legal_actions'] for action in actions: self.assertIn(action.get_str(), TarotBid.order.keys())
def test_step(self): bid_game = BidGame(players, num_players, starting_player, num_cards_per_player, num_cards_dog, dog) bid_game.init_game() game = MainGame(num_players, num_cards_per_player, starting_player, players, taking_player_id, new_dog) game.init_game() action = np.random.choice(game.get_legal_actions()) state, next_player_id = game.step(action) current = game.main_round.current_player_id self.assertLessEqual(len(state['played_cards']), 2) self.assertEqual(next_player_id, current)
def test_init_game(self): bid_game = BidGame(players, num_players, starting_player, num_cards_per_player, num_cards_dog, dog) bid_game.init_game() game = MainGame(num_players, num_cards_per_player, starting_player, players, taking_player_id, new_dog) state, _ = game.init_game() total_cards = list(state['hand'] + state['others_hand']) self.assertIn(len(total_cards), [ game.num_players * game.num_cards_per_player, game.num_players * game.num_cards_per_player + num_cards_dog ])
def test_step_back(self): bid_game = BidGame(players, num_players, starting_player, num_cards_per_player, num_cards_dog, dog) bid_game.init_game() game = MainGame(num_players, num_cards_per_player, starting_player, players, taking_player_id, new_dog) _, player_id = game.init_game() action = np.random.choice(game.get_legal_actions()) self.assertEqual(game.main_round.current_player_id, player_id) game.step(action) self.assertEqual(game.main_round.current_player_id, (player_id + 1) % game.num_players)
def get_action_num(self) -> int: """ Return the number of applicable actions :return: (int): The number of actions. There are 6 or 78 actions """ if self.current_game_part == 'BID': return BidGame.get_action_num() elif self.current_game_part == 'DOG': return DogGame.get_action_num() else: return MainGame.get_action_num()
def test_step(self): game = BidGame(players, num_players, starting_player, num_cards_per_player, num_cards_dog, dog) game.init_game() action = np.random.choice(game.get_legal_actions()) current = game.bid_round.current_player_id state, next_player_id = game.step(action) self.assertLessEqual(len(state['other_bids']), num_players) self.assertEqual(next_player_id, (current + 1) % num_players)
def test_get_final_bid(self): game = BidGame(players, num_players, starting_player, num_cards_per_player, num_cards_dog, dog) game.init_game() while not game.bid_over: actions = game.get_legal_actions() action = np.random.choice(actions) state, _ = game.step(action) total_cards = len(state['hand']) self.assertEqual(total_cards, 18) taking_player_id = game.bid_round.taking_player_id self.assertIsInstance(taking_player_id, int) self.assertLessEqual(-game.bid_round.max_bid_order, -1)
def test_get_player_id(self): game = BidGame(players, num_players, starting_player, num_cards_per_player, num_cards_dog, dog) _, player_id = game.init_game() current = game.get_player_id() self.assertEqual(player_id, current)
def test_get_action_num(self): game = BidGame(players, num_players, starting_player, num_cards_per_player, num_cards_dog, dog) action_num = game.get_action_num() self.assertEqual(action_num, 6)
def test_get_player_num(self): game = BidGame(players, num_players, starting_player, num_cards_per_player, num_cards_dog, dog) num_player = game.get_player_num() self.assertEqual(num_player, 4)
class GlobalGame(object): def __init__(self): """ Initialize a global game object """ self.current_game_part = 'BID' self.num_players = 4 self.num_cards_per_player = 18 self.num_cards_dog = 6 self.starting_player = random.randint(0, self.num_players - 1) self.payoffs = [0 for _ in range(self.num_players)] # Initialize a dealer that can deal cards self.dealer = None # Initialize four players to play the game self.players = None self.taking_player_id = None self.taking_bid_order = None self.number_of_deals = 0 # Initialize a Bid instance self.bid_game = None self.bid_round = None self.bid_over = False # Initialize the dog self.dog_game = None self.dog = None self.dog_over = False # Depending on the bid and dog, the known cards differ: self.known_cards = [] # Initialize a Round instance self.main_game = None self.main_round = None self.main_over = False self.is_game_over = False def init_game(self, number_of_deals: int = 0) -> (dict, int): """ Initialize players and state for bid game in a globalgame object :return: (tuple): containing : (dict): the current state (int): next player id """ self.current_game_part = 'BID' self.bid_over = False self.dog_over = False self.main_over = False self.number_of_deals = number_of_deals self.is_game_over = False self.players = [Player(i) for i in range(self.num_players)] self.dog = TarotDog() # Initialize bid Round self.bid_game = BidGame(self.players, self.num_players, self.starting_player, self.num_cards_per_player, self.num_cards_dog, self.dog) self.bid_game.init_game() player_id = self.bid_game.bid_round.current_player_id state = self.bid_game.get_state(player_id) return state, player_id def step(self, played_action: Union[TarotCard, TarotBid, None]) -> (dict, int): """ Get the next state :param played_action: chosen action to be played (TarotCard or TarotBid): A specific TarotCard or TarotBid :return: Tuple containing: (dict): next player's state (int): next plater's id """ if self.current_game_part == 'BID': state, player_id = self.bid_game.step(played_action) if state is None: self.number_of_deals += 1 return self.init_game(self.number_of_deals) state = self.bid_game.get_state(player_id) self.bid_game.bid_round.current_player_id = player_id if self.bid_game.bid_over: self.bid_over = True self.taking_player_id = self.bid_game.taking_player_id self.taking_bid_order = self.bid_game.taking_bid_order if self.taking_bid_order < 4: self.current_game_part = 'DOG' player_id = self.taking_player_id self.dog_game = DogGame(self.players, self.taking_player_id, self.num_cards_per_player, self.num_cards_dog, self.dog, self.taking_bid_order) self.dog_game.init_game() state = self.dog_game.get_state(player_id) else: self.dog_over = True self.current_game_part = 'MAIN' player_id = self.starting_player self.dog_game = DogGame(self.players, self.taking_player_id, self.num_cards_per_player, self.num_cards_dog, self.dog, self.taking_bid_order) self.main_game = MainGame(self.num_players, self.num_cards_per_player, self.starting_player, self.players, self.bid_game.taking_player_id, self.dog_game.dog_round.new_dog) self.main_game.init_game() state = self.main_game.get_state(player_id) elif self.current_game_part == 'DOG': state, player_id = self.dog_game.step(played_action) state = self.dog_game.get_state(player_id) if self.dog_game.is_over: self.dog_over = True self.current_game_part = 'MAIN' player_id = self.starting_player self.main_game = MainGame(self.num_players, self.num_cards_per_player, self.starting_player, self.players, self.bid_game.taking_player_id, self.dog_game.dog_round.new_dog) self.main_game.init_game() state = self.main_game.get_state(player_id) elif self.current_game_part == 'MAIN': state, player_id = self.main_game.step(played_action) if self.main_game.is_over: self.main_over = True self.is_game_over = True else: raise AttributeError return state, player_id def get_state(self, player_id: int) -> dict: """ Return player's state :param player_id: (int): player id :return: The state of the player """ if self.current_game_part == 'BID': state = self.bid_game.get_state(player_id) elif self.current_game_part == 'DOG': state = self.dog_game.get_state(player_id) else: state = self.main_game.get_state(player_id) return state def get_payoffs(self) -> dict: # TODO REMOVE PENALISATION WHEN NO PLAYER IS TAKING - 1 POINT BY NEW DEAL """ Return the payoffs of the game :return: (dict): Each entry corresponds to the payoff of one player """ payoffs = self.main_game.get_payoffs() return { i: payoffs[i] - self.number_of_deals for i in range(self.num_players) } def get_legal_actions(self) -> Union[List[TarotCard], List[TarotDog]]: """ Return the legal actions for current player :return: (list): A list of legal actions """ if self.current_game_part == 'BID': return self.bid_game.get_legal_actions() elif self.current_game_part == 'DOG': return self.dog_game.get_legal_actions() else: return self.main_game.get_legal_actions() def get_player_num(self) -> int: """ Return the number of players in Tarot :return: (int): The number of players in the game """ return self.num_players def get_action_num(self) -> int: """ Return the number of applicable actions :return: (int): The number of actions. There are 6 or 78 actions """ if self.current_game_part == 'BID': return BidGame.get_action_num() elif self.current_game_part == 'DOG': return DogGame.get_action_num() else: return MainGame.get_action_num() def get_player_id(self) -> int: """ Return the current player's id :return: (int): current player's id """ if self.current_game_part == 'BID': return self.bid_game.get_player_id() elif self.current_game_part == 'DOG': return self.dog_game.get_player_id() else: return self.main_game.get_player_id() def is_over(self) -> bool: """ :return: (bool) is the game over """ return self.is_game_over def step_back(self): pass
from rlcard.games.tarot.bid.bid import TarotBid from rlcard.games.tarot.utils import ACTION_LIST from rlcard.games.tarot.utils import encode_hand, encode_target num_players = 4 num_cards_per_player = 18 taking_player_id = random.randint(0, 3) starting_player = random.randint(0, 3) players = [Player(i) for i in range(num_players)] num_cards_dog = 6 dog = TarotDog() taking_bid = [TarotBid('POUSSE'), TarotBid('GARDE_CONTRE')][random.randint(0, 1)].get_bid_order() taking_bid = TarotBid('POUSSE').get_bid_order() bid_game = BidGame(players, num_players, starting_player, num_cards_per_player, num_cards_dog, dog) bid_game.init_game() players = bid_game.players dog = bid_game.dog class TestTarotBidGameMethods(unittest.TestCase): def test_get_action_num(self): game = DogGame(players, taking_player_id, num_cards_per_player, num_cards_dog, dog, taking_bid) action_num = game.get_action_num() self.assertEqual(action_num, 78) def test_init_game(self): game = DogGame(players, taking_player_id, num_cards_per_player, num_cards_dog, dog, taking_bid)