def render(self, mode='human', close=False): print("-------PLAYER------") for i in range(self._number_of_players): print("player {}".format(i)) Card.print_pretty_cards(self._players[i].get_hand_cards()) print("score: {}".format(self._players[i].get_score())) print("--------BOARD-------") Card.print_pretty_cards(self._playing_cards) print("--------------------")
def filter_score_cards(hand_cards, keep_spade_queen=False): valid_hand_cards = [] for card in hand_cards: if Card.get_suit_int(card) == Card.CHAR_SUIT_TO_INT_SUIT['h']: pass elif keep_spade_queen is False and Card.get_suit_int( card) == Evaluator.SPADES_QUEEN: pass else: valid_hand_cards.append(card) return valid_hand_cards
def _identify_looser(self, cards, ids): suits = [Card.get_suit_int(c) for c in cards] if suits[1:].count(suits[0]) == 0: return ids[0] first_rank = Card.get_rank_int(cards[0]) max_rank = first_rank max_index = 0 number_of_cards = len(cards) for i in range(1, number_of_cards): if suits[i] == suits[0]: tmp_rank = Card.get_rank_int(cards[i]) if tmp_rank > max_rank: max_index = i tmp_rank = max_rank return ids[max_index]
class Evaluator(object): SPADES_QUEEN = Card.new('Qs') def __init__(self): pass def _calculate_score(self, cards): suits = [Card.get_suit_int(c) for c in cards] score = suits.count(Card.CHAR_SUIT_TO_INT_SUIT['h']) if Evaluator.SPADES_QUEEN in cards: score += 13 return score def _identify_looser(self, cards, ids): suits = [Card.get_suit_int(c) for c in cards] if suits[1:].count(suits[0]) == 0: return ids[0] first_rank = Card.get_rank_int(cards[0]) max_rank = first_rank max_index = 0 number_of_cards = len(cards) for i in range(1, number_of_cards): if suits[i] == suits[0]: tmp_rank = Card.get_rank_int(cards[i]) if tmp_rank > max_rank: max_index = i tmp_rank = max_rank return ids[max_index] def evaluate(self, cards, ids): return self._calculate_score(cards), self._identify_looser(cards, ids)
def get_observation(self): ob = {} ob['scores'] = [player.get_score() for player in self._players] ob['playing_cards'] = self._playing_cards.copy() ob['playing_ids'] = self._playing_ids.copy() ob['hand_cards'] = self._players[ self._current_player_id].get_hand_cards() if len(self._playing_cards) == 0: ob['valid_hand_cards'] = ob['hand_cards'] else: trick_suit = Card.get_suit_int(self._playing_cards[0]) ob['valid_hand_cards'] = [ card for card in ob['hand_cards'] if Card.get_suit_int(card) == trick_suit ] if len(ob['valid_hand_cards']) == 0: ob['valid_hand_cards'] = ob['hand_cards'] return ob
def render(self): print("--------GAME-------") print("round: {}".format(self._round)) print("trick: {}".format(self._trick)) print("heart broken: {}".format(self._is_heart_broken)) print("-------PLAYER------") for i in range(self._number_of_players): print("player {}".format(i)) playing_cards = [Card.int_to_pretty_str(c) for c in self._players[i].get_hand_cards(is_sorted=True)] print(' '.join(playing_cards)) print("score: {}".format(self._players[i].get_score())) print("--------BOARD-------") playing_card_strs = ["[]"] * self._number_of_players for playing_id, playing_card in zip(self._playing_ids, self._playing_cards): playing_card_strs[playing_id] = Card.int_to_pretty_str(playing_card) print(' '.join(playing_card_strs)) print("--------------------") print("")
class Evaluator(object): SPADES_QUEEN = Card.new('Qs') def __init__(self): pass def calculate_score(self, cards): suits = [Card.get_suit_int(c) for c in cards] score = suits.count(Card.CHAR_SUIT_TO_INT_SUIT['h']) if Evaluator.SPADES_QUEEN in cards: score += 13 return score def identify_looser(self, cards, ids): suits = [Card.get_suit_int(c) for c in cards] if suits[1:].count(suits[0]) == 0: return ids[0] first_rank = Card.get_rank_int(cards[0]) max_rank = first_rank max_index = 0 number_of_cards = len(cards) for i in range(1, number_of_cards): if suits[i] == suits[0]: tmp_rank = Card.get_rank_int(cards[i]) if tmp_rank > max_rank: max_index = i max_rank = tmp_rank return ids[max_index] def shooting_the_moon(self, players): round_scores = [p.get_uncommited_score() for p in players] max_score = max(round_scores) max_score_player_id = round_scores.index(max_score) if max_score == 26: for player_id, p in enumerate(players): p.rollback_to_last_commited_score() if player_id != max_score_player_id: p.add_score(26) def filter_score_cards(hand_cards, keep_spade_queen=False): valid_hand_cards = [] for card in hand_cards: if Card.get_suit_int(card) == Card.CHAR_SUIT_TO_INT_SUIT['h']: pass elif keep_spade_queen is False and Card.get_suit_int( card) == Evaluator.SPADES_QUEEN: pass else: valid_hand_cards.append(card) return valid_hand_cards def evaluate(self, cards, ids): return self.calculate_score(cards), self.identify_looser(cards, ids)
def _filter_valid_hand_cards(self, hand_cards): if len(self._playing_cards) == 0: if self._trick == 0: if HeartsEnv.CLUB_TWO not in hand_cards: raise Exception("oops, first player does not have club two") valid_hand_cards = [HeartsEnv.CLUB_TWO] elif self._is_heart_broken is True: valid_hand_cards = hand_cards else: valid_hand_cards = [card for card in hand_cards if Card.get_suit_int(card) != Card.CHAR_SUIT_TO_INT_SUIT['h']] else: trick_suit = Card.get_suit_int(self._playing_cards[0]) valid_hand_cards = [card for card in hand_cards if Card.get_suit_int(card) == trick_suit] if len(valid_hand_cards) == 0: valid_hand_cards = hand_cards if self._trick == 0: valid_hand_cards = [card for card in valid_hand_cards if Card.get_suit_int(card) != Card.CHAR_SUIT_TO_INT_SUIT['h']] if (self._trick == 0) and (Evaluator.SPADES_QUEEN in valid_hand_cards): valid_hand_cards.remove(Evaluator.SPADES_QUEEN) return valid_hand_cards
def step(self, action_card): info = {} info['current_player_id'] = self._current_player_id info['action'] = action_card if len(self._playing_cards) == self._number_of_players: self._playing_cards.clear() self._playing_ids.clear() self._players[self._current_player_id].remove_hand_card(action_card) self._playing_cards.append(action_card) self._playing_ids.append(self._current_player_id) if len(self._playing_cards) == self._number_of_players: self._trick += 1 punish_score, punish_player_id = self._evaluator.evaluate(self._playing_cards, self._playing_ids) self._players[punish_player_id].add_score(punish_score) info['punish_score'] = punish_score info['punish_player_id'] = punish_player_id rewards = [0] * self._number_of_players if len(self._playing_cards) == self._number_of_players: self._current_player_id = punish_player_id rewards[punish_player_id] = punish_score else: self._current_player_id += 1 self._current_player_id = self._current_player_id % 4 done = False is_new_round = False if self._trick == self._number_of_hand_card_per_player: scores = [player.get_score() for player in self._players] for score in scores: if score >= 100: done = True break if done is False: self._start_new_round() is_new_round = True info['is_new_round'] = is_new_round info['done'] = done if is_new_round or done: if self._shooting_the_moon_enabled is True: self._evaluator.shooting_the_moon(self._players) for player in self._players: player.commit_new_round_score() observation = self.get_observation() self._current_observation = observation if self._is_heart_broken is False and Card.get_suit_int(action_card) == Card.CHAR_SUIT_TO_INT_SUIT['h']: self._is_heart_broken = True info['is_heart_broken'] = self._is_heart_broken self._players_watch(info) return observation, rewards, done, info
def _calculate_score(self, cards): suits = [Card.get_suit_int(c) for c in cards] score = suits.count(Card.CHAR_SUIT_TO_INT_SUIT['h']) if Evaluator.SPADES_QUEEN in cards: score += 13 return score
class HeartsEnv(gym.Env): CLUB_TWO = Card.new('2c') def __init__(self, endgame_score=100): self._evaluator = Evaluator() self._number_of_players = 0 self._number_of_hand_card_per_player = 0 self._players = [] self._trick = 0 self._round = 0 # each round has 13 trick when we have 4 players self._playing_cards = [] self._playing_ids = [] self._current_player_id = 0 self._endgame_score = endgame_score self._current_observation = {} self._shooting_the_moon_enabled = False self._is_heart_broken = False def enable_shooting_the_moon(self): self._shooting_the_moon_enabled = True def _filter_valid_hand_cards(self, hand_cards): if len(self._playing_cards) == 0: if self._trick == 0: if HeartsEnv.CLUB_TWO not in hand_cards: raise Exception("oops, first player does not have club two") valid_hand_cards = [HeartsEnv.CLUB_TWO] elif self._is_heart_broken is True: valid_hand_cards = hand_cards else: valid_hand_cards = [card for card in hand_cards if Card.get_suit_int(card) != Card.CHAR_SUIT_TO_INT_SUIT['h']] else: trick_suit = Card.get_suit_int(self._playing_cards[0]) valid_hand_cards = [card for card in hand_cards if Card.get_suit_int(card) == trick_suit] if len(valid_hand_cards) == 0: valid_hand_cards = hand_cards if self._trick == 0: valid_hand_cards = [card for card in valid_hand_cards if Card.get_suit_int(card) != Card.CHAR_SUIT_TO_INT_SUIT['h']] if (self._trick == 0) and (Evaluator.SPADES_QUEEN in valid_hand_cards): valid_hand_cards.remove(Evaluator.SPADES_QUEEN) return valid_hand_cards def get_observation(self): ob = {} ob['trick'] = self._trick ob['round'] = self._round ob['number_of_players'] = self._number_of_players ob['scores'] = [player.get_score() for player in self._players] ob['playing_cards'] = self._playing_cards.copy() ob['playing_ids'] = self._playing_ids.copy() ob['hand_cards'] = self._players[self._current_player_id].get_hand_cards() ob['current_player_id'] = self._current_player_id ob['valid_hand_cards'] = self._filter_valid_hand_cards(ob['hand_cards']) ob['number_of_hand_cards_for_all_players'] = [len(player.get_hand_cards()) for player in self._players] return ob def add_player(self, strategy, hand_cards=None): player_id = len(self._players) player = Player(player_id, strategy) if hand_cards is not None: player.reset_hand_cards(hand_cards) self._players.append(player) def copy_observation(self, observation): ob = observation self._number_of_players = ob['number_of_players'] self._number_of_hand_card_per_player = 52 // self._number_of_players self._trick = ob['trick'] self._round = ob['round'] self._playing_cards = ob['playing_cards'].copy() self._playing_ids = ob['playing_ids'].copy() self._current_player_id = ob['current_player_id'] self._current_observation = self.get_observation() def start(self): if self._trick == 0 and self._round == 0: self._number_of_players = len(self._players) self._number_of_hand_card_per_player = 52 // self._number_of_players self._start_new_round() def step(self, action_card): info = {} info['current_player_id'] = self._current_player_id info['action'] = action_card if len(self._playing_cards) == self._number_of_players: self._playing_cards.clear() self._playing_ids.clear() self._players[self._current_player_id].remove_hand_card(action_card) self._playing_cards.append(action_card) self._playing_ids.append(self._current_player_id) if len(self._playing_cards) == self._number_of_players: self._trick += 1 punish_score, punish_player_id = self._evaluator.evaluate(self._playing_cards, self._playing_ids) self._players[punish_player_id].add_score(punish_score) info['punish_score'] = punish_score info['punish_player_id'] = punish_player_id rewards = [0] * self._number_of_players if len(self._playing_cards) == self._number_of_players: self._current_player_id = punish_player_id rewards[punish_player_id] = punish_score else: self._current_player_id += 1 self._current_player_id = self._current_player_id % 4 done = False is_new_round = False if self._trick == self._number_of_hand_card_per_player: scores = [player.get_score() for player in self._players] for score in scores: if score >= 100: done = True break if done is False: self._start_new_round() is_new_round = True info['is_new_round'] = is_new_round info['done'] = done if is_new_round or done: if self._shooting_the_moon_enabled is True: self._evaluator.shooting_the_moon(self._players) for player in self._players: player.commit_new_round_score() observation = self.get_observation() self._current_observation = observation if self._is_heart_broken is False and Card.get_suit_int(action_card) == Card.CHAR_SUIT_TO_INT_SUIT['h']: self._is_heart_broken = True info['is_heart_broken'] = self._is_heart_broken self._players_watch(info) return observation, rewards, done, info def _players_watch(self, info): for player in self._players: player._watch(self._current_observation, info) def move(self): if len(self._current_observation['playing_cards']) == 4: self._current_observation['playing_cards'].clear() self._current_observation['playing_ids'].clear() return self._players[self._current_player_id].move(self._current_observation) def _start_new_round(self): deck = Deck() deck.shuffle() club_two_player_id = -1 for player_id, player in enumerate(self._players): hand_cards = deck.draw(self._number_of_hand_card_per_player) player.reset_hand_cards(hand_cards) if HeartsEnv.CLUB_TWO in hand_cards: club_two_player_id = player_id if club_two_player_id == -1: raise Exception("oops, it cannot find a player has club two") self._trick = 0 self._playing_cards = [] self._playing_ids = [] self._current_player_id = club_two_player_id self._round += 1 self._is_heart_broken = False self._current_observation = self.get_observation() def reset(self): deck = Deck() deck.shuffle() for player in self._players: player.reset(deck.draw(self._number_of_hand_card_per_player)) self._trick = 0 self._playing_cards = [] self._playing_ids = [] self._current_player_id = 0 self._round = 0 self._is_heart_broken = False def render(self): print("--------GAME-------") print("round: {}".format(self._round)) print("trick: {}".format(self._trick)) print("heart broken: {}".format(self._is_heart_broken)) print("-------PLAYER------") for i in range(self._number_of_players): print("player {}".format(i)) playing_cards = [Card.int_to_pretty_str(c) for c in self._players[i].get_hand_cards(is_sorted=True)] print(' '.join(playing_cards)) print("score: {}".format(self._players[i].get_score())) print("--------BOARD-------") playing_card_strs = ["[]"] * self._number_of_players for playing_id, playing_card in zip(self._playing_ids, self._playing_cards): playing_card_strs[playing_id] = Card.int_to_pretty_str(playing_card) print(' '.join(playing_card_strs)) print("--------------------") print("")
from treys.card import Card from treys.evaluator import Evaluator from treys.deck import Deck # create a card card = Card.new('Qh') # create a board and hole cards board = [Card.new('2h'), Card.new('2s'), Card.new('Jc')] hand = [Card.new('Qs'), Card.new('Th')] # pretty print cards to console Card.print_pretty_cards(board + hand) # create an evaluator evaluator = Evaluator() # and rank your hand rank = evaluator.evaluate(board, hand) class_ = evaluator.get_rank_class(rank) print("{} {}".format(rank, evaluator.class_to_string(class_))) print() # or for random cards or games, create a deck print("Dealing a new hand...") deck = Deck() board = deck.draw(5) player1_hand = deck.draw(2) player2_hand = deck.draw(2) print("The board:")