def _get_observation(self, player): keys = ['position', 'state', 'stack', 'money_in_pot', 'bet_this_street', 'all_in'] values = [ [other.position, other.state, other.stack, other.money_in_pot, other.bet_this_street, other.all_in] for other in self.players if other is not player ] return { 'self': { 'position': player.position, 'cards': [[Card.get_suit_int(card), Card.get_rank_int(card)] for card in player.cards], 'stack': player.stack, 'money_in_pot': player.money_in_pot, 'bet_this_street': player.bet_this_street, }, 'table': { 'street': int(self.street), 'cards': [[Card.get_suit_int(card), Card.get_rank_int(card)] for card in self.cards], 'pot': self.pot, 'bet_to_match': self.bet_to_match, 'minimum_raise': self.minimum_raise, }, 'others': [ { key: val for key, val in zip(keys, value) } for value in values ] }
def top_royalties(cards): ranked_cards = split_by_rank(cards) top_roy=0 if len(ranked_cards) == 1: top_roy += Card.get_rank_int(ranked_cards[0][0])+10 elif len(ranked_cards) == 2: top_roy += Card.get_rank_int(ranked_cards[0][0])-3 return top_roy
def is_full_house(cards): ranks = {} ranks[Card.get_rank_int(cards[0])] = 1 for c in range(1, len(cards)): if Card.get_rank_int(c) in ranks: ranks[Card.get_rank_int(c)] += 1 else: ranks[Card.get_rank_int(c)] = 1 count = list(ranks.values()) if len(count) == 2 and ((count[0] == 2 and count[1] == 3) or (count[0] == 3 and count[1] == 2)): return True else: return False
def has_suited_pockets(self, player_index): if Card.get_suit_int( self.pocket_cards[player_index][0]) == Card.get_rank_int( self.pocket_cards[player_index][1]): return True else: return False
def convert_card_to_treys(cards): convert_cards = [] hand_nb_spade = 0 hand_nb_heart = 0 hand_nb_diamond = 0 hand_nb_clover = 0 feats = [] for card in cards: color = card[0] num = card[1] if color == "C": hand_nb_clover += 1 elif color == "H": hand_nb_heart += 1 elif color == "D": hand_nb_diamond += 1 elif color == "S": hand_nb_spade += 1 convert_cards.append(Card.new(num.upper() + color.lower())) for i in [0, 1, 2, 3, 4]: feat = np.zeros(13) try: feat[Card.get_rank_int(convert_cards[i])] = 1 feats.append(feat) except Exception as e: feats.append(feat) return feats, hand_nb_spade, hand_nb_heart, hand_nb_diamond, hand_nb_clover
def get_community_cards_features(self): feat_flop = np.zeros(52) feat_turn = np.zeros(52) feat_river = np.zeros(52) if self.current_street.value >= Street.FLOP.value: for i in range(0, 3): feat_flop[Card.get_rank_int(self.community_cards[i]) * self.get_card_real_suit_int( self.community_cards[i])] = 1 if self.current_street.value >= Street.TURN.value: feat_turn[Card.get_rank_int(self.community_cards[3]) * self.get_card_real_suit_int(self.community_cards[3])] = 1 if self.current_street.value >= Street.RIVER.value: feat_turn[Card.get_rank_int(self.community_cards[4]) * self.get_card_real_suit_int(self.community_cards[4])] = 1 return np.concatenate([feat_flop, feat_turn, feat_river])
def do_swap(card, swap): char_one = swap[0] char_two = swap[1] if (Card.get_suit_int(card) == char_to_int[char_one]): return Card.new(rank_int_to_char[Card.get_rank_int(card)] + char_two) else: return card
def move(self, observation): # for Lookaheadplaystrategy if self._first_action_card is not None: first_action_card = self._first_action_card self._first_action_card = None return first_action_card number_of_playing_ids = len(observation['playing_ids']) valid_hand_cards = observation['valid_hand_cards'] playing_cards = observation['playing_cards'] valid_hand_ranks = [Card.get_rank_int(c) for c in valid_hand_cards] min_card_id = valid_hand_ranks.index(min(valid_hand_ranks)) max_card_id = valid_hand_ranks.index(max(valid_hand_ranks)) # if i am last player in this trick if number_of_playing_ids == observation['number_of_players'] - 1: first_suit = Card.get_suit_int(playing_cards[0]) competitor_ranks = [ Card.get_rank_int(c) for c in playing_cards if Card.get_suit_int(c) == first_suit ] max_suit = Card.get_suit_int(valid_hand_cards[max_card_id]) punish_score = self._evaluator.calculate_score(playing_cards) # we do not have same suit card, so just drop max card. it does not get punish score if (max_suit != first_suit) or (punish_score == 0): return valid_hand_cards[max_card_id] # we will be the looser in this round, so just drop max card. elif valid_hand_ranks[min_card_id] > max(competitor_ranks): return valid_hand_cards[max_card_id] # drop the card which is not larger then biggest playing card. else: max_safe_card_id = min_card_id max_safe_rank = valid_hand_ranks[min_card_id] max_competitor_ranks = max(competitor_ranks) for tmp_card_id, r in enumerate(valid_hand_ranks): if (r < max_competitor_ranks) and (r > max_safe_rank): max_safe_rank = r max_safe_card_id = tmp_card_id return valid_hand_cards[max_safe_card_id] # otherwise else: return valid_hand_cards[min_card_id]
def same_rank(cards): ranks = [] for card in cards: ranks.append(Card.get_rank_int(card)) same_rank = True for r in range(1, len(ranks)): if ranks[r] != ranks[r - 1]: same_rank = False break return same_rank
def card_to_total_index(c): suit = Card.get_suit_int(c) # keeping 1 as is if suit == 2: suit = 0 elif suit == 4: suit = 2 elif suit == 8: suit = 3 return Card.get_rank_int(c)*(suit+1)
def is_straight(cards): ranks = [] for card in cards: ranks.append(Card.get_rank_int(card)) ranks.sort() is_straight = True for r in range(1, len(ranks)): if ranks[r] != ranks[r - 1] + 1: is_straight = False break return is_straight
def move(self, observation): number_of_playing_ids = len(observation['playing_ids']) valid_hand_cards = observation['valid_hand_cards'] playing_cards = observation['playing_cards'] valid_hand_ranks = [Card.get_rank_int(c) for c in valid_hand_cards] min_card_id = valid_hand_ranks.index(min(valid_hand_ranks)) max_card_id = valid_hand_ranks.index(max(valid_hand_ranks)) # if i am last player in this trick if number_of_playing_ids == observation['number_of_players'] - 1: first_suit = Card.get_suit_int(playing_cards[0]) competitor_ranks = [ Card.get_rank_int(c) for c in playing_cards if Card.get_suit_int(c) == first_suit ] max_suit = Card.get_suit_int(valid_hand_cards[max_card_id]) punish_score = self._evaluator.calculate_score(playing_cards) # we do not have same suit card, so just drop max card. it does not get punish score if (max_suit != first_suit) or (punish_score == 0): return valid_hand_cards[max_card_id] # we will be the looser in this round, so just drop max card. elif valid_hand_ranks[min_card_id] > max(competitor_ranks): return valid_hand_cards[max_card_id] # drop the card which is not larger then biggest playing card. else: max_safe_card_id = min_card_id max_safe_rank = valid_hand_ranks[min_card_id] max_competitor_ranks = max(competitor_ranks) for tmp_card_id, r in enumerate(valid_hand_ranks): if (r < max_competitor_ranks) and (r > max_safe_rank): max_safe_rank = r max_safe_card_id = tmp_card_id return valid_hand_cards[max_safe_card_id] # apply monte carlo sampling to estimate win rate of valid hand cards else: simulated_scores = [ self._simulate(card, observation) for card in valid_hand_cards ] best_card_id = simulated_scores.index(min(simulated_scores)) return valid_hand_cards[best_card_id]
def convert_hand_to_treys(hand): num = [] color = [] for card in hand: color.append(card[0]) num.append(card[1]) card1 = Card.new(num[0].upper() + color[0].lower()) card2 = Card.new(num[1].upper() + color[1].lower()) feat = np.zeros(13) for c in [card1, card2]: feat[Card.get_rank_int(c)] = 1 return feat
def score_front_royalties(cards): if len(cards) != 3: raise ValueError("Incorrect number of cards!") ranks = [Card.get_rank_int(x) for x in cards] ctr = collections.Counter(ranks) rank, count = ctr.most_common()[0] if count < 2: return 0 if count == 2: return max(0, rank - 3) if count == 3: return 10 + rank
def transferCard(cards): try: result = [] for i in cards: rank = Card.get_rank_int(i) suit = Card.get_suit_int(i) suit = int(math.log2(suit)) result.append(suit * 13 + rank) print('cards = ', result) one_hot_encoding = np.zeros(52) one_hot_encoding[result] += 1 except Exception as e: print(cards) one_hot_encoding = np.zeros(52) return one_hot_encoding
def convertCardToString(card): intSuit = Card.get_suit_int( card) # Spade = 1, heart = 2, diamond = 4, club = 8 intRank = Card.get_rank_int( card ) # 2 = 0, 3 = 1, 4 = 2, 5 = 3, 6 = 4, 7 = 5, 8 = 6,... J = 9, ... A = 12 cardString = "" if (intRank < 8): cardString = str(intRank + 2) elif (intRank == 8): cardString = "T" elif (intRank == 9): cardString = "J" elif (intRank == 10): cardString = "Q" elif (intRank == 11): cardString = "K" elif (intRank == 12): cardString = "A" else: raise Exception( 'intRank should not exceed 12. The value of intRank was: {}'. format(intRank)) if (intSuit == 1): cardString = cardString + "s" elif (intSuit == 2): cardString = cardString + "h" elif (intSuit == 4): cardString = cardString + "d" elif (intSuit == 8): cardString = cardString + "c" else: raise Exception( 'intSuit bad. The value of intSuit was: {}'.format(intSuit)) return cardString
def highest_card(cards): rank = Card.get_rank_int(cards[0]) for card in cards: if rank > Card.get_rank_int(card): rank = Card.get_rank_int(card) return rank
def GetCardInt(self, card): card_suit = Card.get_suit_int(card) - 1 if card_suit == 7: #Treys Clubs suit == 8-> From line above, if clubs, card_suit == 7 (Club_Suit-1 --> 8 - 1 == 7) card_suit = 2 #Correct the fact clubs suit should == 3, from first line (clubs_int - 1 == 2) return str((13 * card_suit) + Card.get_rank_int(card))
def pretty_print_hand(hand_cards, hand_type, table_cards, kicker): combined = [] combined.extend(hand_cards) combined.extend(table_cards) values = [Card.get_rank_int(c) for c in combined] suits = [Card.get_suit_int(c) for c in combined] suit_ints = [1, 2, 4, 8] if hand_type == 'High Card': return 'High card %s' % singulars[max(values)] if hand_type == 'Pair': doubles = [] for k, v in Counter(values).items(): doubles.extend([k] * (v // 2)) return 'a pair of %s' % plurals[max(doubles)] if hand_type == 'Two Pair': doubles = [] for k, v in Counter(values).items(): doubles.extend([k] * (v // 2)) first = max(doubles) doubles.remove(first) second = max(doubles) return 'two pair, %s and %s' % (plurals[first], plurals[second]) if hand_type == 'Three of a Kind': triples = [] for k, v in Counter(values).items(): triples.extend([k] * (v // 3)) return 'three of a kind, %s' % plurals[max(triples)] if hand_type == 'Straight': # TODO: Fix this mess previous_value = None high = None low = None sequence = 1 for value in reversed(sorted(set(values))): if previous_value is None: previous_value = value high = value continue elif value == previous_value - 1: sequence += 1 if sequence == 4 and value == 0: if 12 in values: low = value break else: sequence = 1 high = value if sequence == 5: low = value break previous_value = value return 'a straight, %s to %s' % (singulars[low], singulars[high]) if hand_type == 'Flush': # TODO: Fix this mess counts = np.array( [len([suit for suit in suits if suit == i]) for i in suit_ints]) suit_i = int(np.argmax(counts)) high = max([ values[i] for i in range(len(values)) if suits[i] == suit_ints[suit_i] ]) return 'a flush, %s high' % singulars[high] if hand_type == 'Full House': triples = [] for k, v in Counter(values).items(): triples.extend([k] * (v // 3)) doubles = [] for k, v in Counter(values).items(): doubles.extend([k] * (v // 2)) return 'a full house, %s full of %s' % (plurals[max(triples)], plurals[max(doubles)]) if hand_type == 'Four of a Kind': quads = [] for k, v in Counter(values).items(): quads.extend([k] * (v // 4)) return 'four of a kind, %s' % plurals[max(quads)] if hand_type == 'Straight Flush': # TODO: Fix this mess counts = np.array( [len([suit for suit in suits if suit == i]) for i in suit_ints]) suit_i = int(np.argmax(counts)) correct_suit = [ values[i] for i in range(len(values)) if suits[i] == suit_ints[suit_i] ] previous_value = None high = None low = None sequence = 1 for value in reversed(sorted(set(correct_suit))): if previous_value is None: previous_value = value high = value continue elif value == previous_value - 1: sequence += 1 if sequence == 4 and value == 0: if 12 in correct_suit: low = value break else: sequence = 1 high = value if sequence == 5: low = value break previous_value = value return 'royal flush, %s to %s' % (singulars[low], singulars[high]) raise Exception("Incorrect hand/table passed to pretty_print_hand")
def flop(self): # check for pairs strength = 0 pairs = [] board_pairs = [] for c in itertools.combinations(self.hand + self.board, 2): if PokerProbabilities.same_rank(c): pairs.append(Card.get_rank_int(c[0])) for cb in itertools.combinations(self.hand + self.board, 2): if PokerProbabilities.same_rank(cb): board_pairs.append(Card.get_rank_int(cb[0])) board_three = -1 if PokerProbabilities.same_rank(self.board): board_three = Card.get_rank_int(self.board[0]) three_of_a_kind = -1 for ci in itertools.combinations(self.hand + self.board, 3): if PokerProbabilities.same_rank(ci): three_of_a_kind = Card.get_rank_int(ci[0]) four_of_a_kind = -1 if PokerProbabilities.same_rank(self.hand): for cf in itertools.combinations(self.board, 2): if PokerProbabilities.same_rank(cf): if Card.get_rank_int(cf[0]) == Card.get_rank_int( self.hand[0]): four_of_a_kind = Card.get_rank_int(cf[0]) if four_of_a_kind != -1: strength = 20 return strength if four_of_a_kind == -1 and three_of_a_kind != -1: strength = 8 return strength if PokerProbabilities.is_straight_flush(self.hand + self.board): strength = 25 return strength if PokerProbabilities.is_straight(self.hand + self.board): strength = 12 return strength if PokerProbabilities.is_flush(self.hand + self.board): strength = 15 return strength if PokerProbabilities.is_full_house(self.hand + self.board): strength = 18 return strength if board_three == -1 and three_of_a_kind == -1 and pairs: pairs.sort(reverse=True) # if pairs are in your hand for s in self.hand: for i, p in enumerate(pairs): if Card.get_rank_int(s) == p: if i == 0: if p >= PokerProbabilities.highest_card( self.board): strength += 5 # likely top pair else: strength += 4 # low pair if i == 1: strength += 2 # two pair return strength if not pairs: if PokerProbabilities.highest_card( self.hand) > PokerProbabilities.highest_card(self.board): strength = 2 else: strength = 1 return strength
def rank_str(self): rank_int = Card.get_rank_int(self._card) return Card.STR_RANKS[rank_int]
def score_hand(self, opponent): top_rank1 = evaluator.evaluate(self.top_hand, []) mid_rank1 = evaluator.evaluate(self.middle_hand, []) bot_rank1 = evaluator.evaluate(self.bottom_hand, []) top_rank2 = evaluator.evaluate(opponent.top_hand, []) mid_rank2 = evaluator.evaluate(opponent.middle_hand, []) bot_rank2 = evaluator.evaluate(opponent.bottom_hand, []) # if both players foul if (not bot_rank1 <= mid_rank1 < top_rank1) and ( not bot_rank2 <= mid_rank2 <= top_rank2): return (0, 0) # if player 1 only fouls elif not bot_rank1 <= mid_rank1 <= top_rank1: r = opponent.get_royalties() return (-6 - r, 6 + r) # if player 2 only fouls elif not bot_rank2 <= mid_rank2 <= top_rank2: r = self.get_royalties() return (6 + r, -6 - r) # if neither player fouls else: r1 = self.get_royalties() r2 = opponent.get_royalties() # bottom hand if bot_rank1 < bot_rank2: bs = 1 elif bot_rank1 == bot_rank2: bs = 0 else: bs = -1 # middle hand if mid_rank1 < mid_rank2: ms = 1 elif mid_rank1 == mid_rank2: ms = 0 else: ms = -1 # top hand if top_rank1 < top_rank2: ts = 1 elif top_rank1 > top_rank2: ts = -1 # the folowing should take care of the 3-to-5 card mapping being many-to-one else: dummy_top1 = [ self.top_hand[0], self.top_hand[1], self.top_hand[2] ] dummy_top2 = [ opponent.top_hand[0], opponent.top_hand[1], opponent.top_hand[2] ] ranked1 = methods.split_by_rank(dummy_top1) ranked2 = methods.split_by_rank(dummy_top2) if len(ranked1[0]) == 2: # for pairs if Card.get_rank_int(ranked1[1][0]) == Card.get_rank_int( ranked2[1][0]): ts = 0 elif Card.get_rank_int(ranked1[1][0]) > Card.get_rank_int( ranked2[1][0]): ts = 1 else: ts = -1 else: # for high cards if Card.get_rank_int(ranked1[0][0]) > Card.get_rank_int( ranked2[0][0]): ts = 1 elif Card.get_rank_int(ranked1[0][0]) < Card.get_rank_int( ranked2[0][0]): ts = -1 else: if Card.get_rank_int( ranked1[1][0]) > Card.get_rank_int( ranked2[1][0]): ts = 1 elif Card.get_rank_int( ranked1[1][0]) < Card.get_rank_int( ranked2[1][0]): ts = -1 else: if Card.get_rank_int( ranked1[2][0]) > Card.get_rank_int( ranked2[2][0]): ts = 1 elif Card.get_rank_int( ranked1[2][0]) < Card.get_rank_int( ranked2[2][0]): ts = -1 else: ts = 0 # calculate sum of individual score s = bs + ms + ts # double score if player wins all three hands (as per POFC scoring rules) if s % 3 == 0: s = 2 * s # calculate player1 score by adding difference of royalties s = s + r1 - r2 return s
def get_max_rank(cards): max_rank = 0 for c in cards: if Card.get_rank_int(c)>max_rank: max_rank=Card.get_rank_int(c) return max_rank
def get_min_rank(cards): min_rank = 0 for c in cards: if Card.get_rank_int(c)<min_rank: min_rank=Card.get_rank_int(c) return min_rank
def split_by_rank(cards): aces = [] kings = [] queens = [] jacks = [] tens = [] nines = [] eights = [] sevens = [] sixes = [] fives = [] fours = [] threes = [] twos = [] for card in cards: if Card.get_rank_int(card)==0: twos.append(card) elif Card.get_rank_int(card)==1: threes.append(card) elif Card.get_rank_int(card)==2: fours.append(card) elif Card.get_rank_int(card)==3: fives.append(card) elif Card.get_rank_int(card)==4: sixes.append(card) elif Card.get_rank_int(card)==5: sevens.append(card) elif Card.get_rank_int(card)==6: eights.append(card) elif Card.get_rank_int(card)==7: nines.append(card) elif Card.get_rank_int(card)==8: tens.append(card) elif Card.get_rank_int(card)==9: jacks.append(card) elif Card.get_rank_int(card)==10: queens.append(card) elif Card.get_rank_int(card)==11: kings.append(card) elif Card.get_rank_int(card)==12: aces.append(card) else: return 'Card rank ERROR' all_ranks = [aces,kings,queens,jacks,tens,nines,eights,sevens,sixes,fives,fours,threes,twos] rank_split = [] for rank in all_ranks: if len(rank)>0: rank_split.append(rank) rank_split.sort(key=len, reverse=True) return rank_split
def rank_int(self): rank_int = Card.get_rank_int(self._card) return rank_int
def preflop(self): score = 0 highest_card = max(Card.get_rank_int(self.hand[0]), Card.get_rank_int(self.hand[1])) if highest_card == 12: score += 10 elif highest_card == 11: score += 8 elif highest_card == 10: score += 7 elif highest_card == 9: score += 6 elif highest_card <= 8: score += highest_card / 2 + 1 if Card.get_rank_int(self.hand[0]) == Card.get_rank_int(self.hand[1]): score = score * 2 if score < 5: score = 5 if Card.get_suit_int(self.hand[0]) == Card.get_suit_int(self.hand[1]): score += 2 if abs( Card.get_rank_int(self.hand[0]) - Card.get_rank_int(self.hand[1])) == 2: score -= 1 elif abs( Card.get_rank_int(self.hand[0]) - Card.get_rank_int(self.hand[1])) == 3: score -= 2 elif abs( Card.get_rank_int(self.hand[0]) - Card.get_rank_int(self.hand[1])) == 4: score -= 4 elif abs( Card.get_rank_int(self.hand[0]) - Card.get_rank_int(self.hand[1])) >= 5: score -= 5 if abs(Card.get_rank_int(self.hand[0]) - Card.get_rank_int(self.hand[1])) <= 2 \ and highest_card < 10: score += 1 return math.ceil(score)
def move(self, observation): valid_hand_cards = observation['valid_hand_cards'] valid_hand_ranks = [Card.get_rank_int(c) for c in valid_hand_cards] min_card_id = valid_hand_ranks.index(min(valid_hand_ranks)) return valid_hand_cards[min_card_id]
def get_pocket_cards_features(self, player_index): feat = np.zeros(52) for c in self.pocket_cards[player_index]: feat[Card.get_rank_int(c) * self.get_card_real_suit_int(c)] = 1 return feat