def get_bucket_number(hole_cards, community_cards=None):
    """	
	Evaluate handstrength base on Chen's Formula if only hole cards are drawn,
    because it values both hand potential as well as relative value of card rank.
    Otherwise, evaluate handstrength using Deuces Monte-carlo Look-up table.
    Divide the bucket with equal probability based on the number of buckets.
    Using the handstrength value drawn earlier, find the right bucket.
    
    :param hole_cards: List(str) in format of 'CA' for hole cards belong to the current player
    :param community_cards: List(str) in format of 'S3' for community cards   
    """
    if not community_cards:
        points = starting_hand_evaluator(hole_cards)
        bucket_number = int(
            math.ceil((points + 1.5) / 21.5 * constants.BUCKET_NUM) - 1)
    else:
        hole_cards = list(
            map(lambda x: DeucesCard.new(x[1] + x[0].lower()), hole_cards))
        community_cards = list(
            map(lambda x: DeucesCard.new(x[1] + x[0].lower()),
                community_cards))

        evaluator = DeucesEvaluator()
        five_cards_ranking = evaluator.evaluate(hole_cards, community_cards)
        strength = 1.0 - evaluator.get_five_card_rank_percentage(
            five_cards_ranking)
        bucket_number = int(math.ceil(strength * constants.BUCKET_NUM) - 1)

    return 0 if bucket_number == -1 else bucket_number
Example #2
0
async def evaluateHand(whichServer):
    global table
    global hands
    global board
    global isRound
    global firstGame
    global players
    global pot
    finalBoard = []
    finalHands = []
    handWinner = []
    max = 100000
    eval = Evaluator()
    for card in board[whichServer]:
        temp1 = card[1].replace('10', 'T')
        temp2 = card[0].lower()
        temp3 = Card.new(temp1[0] + temp2[0])
        finalBoard.append(temp3)

    for p in table[whichServer]:
        for card in hands[whichServer][p]:
            temp1 = card[1].replace('10', 'T')
            temp2 = card[0].lower()
            temp3 = Card.new(temp1[0] + temp2[0])
            finalHands.append(temp3)

        valueOfHand = eval.evaluate(finalBoard, finalHands)

        if valueOfHand < max:
            max = valueOfHand
            handWinner = []
            handWinner.append(p)
        elif valueOfHand == max:
            handWinner.append(p)

        print(eval.evaluate(finalBoard, finalHands))
        finalHands = []

    pot[whichServer] /= len(handWinner)
    for winners in handWinner:
        players[whichServer][winners] += pot[whichServer]
        await bot.send_message(
            pokerChannel[whichServer], winners.display_name +
            " won the round! They won " + str(pot[whichServer]) +
            "$. Use command startPoker to start another one!")
    firstGame[whichServer] = 0
    pot[whichServer] = 0
    isRound[whichServer] = 0
Example #3
0
    def _get_deuces_card(self, card):
        card_str = ""
        val = card % 13 + 1
        if val < 10 and val > 1:
            card_str = str(val)
        else:
            if val == 1:
                card_str = "A"
            if val == 10:
                card_str = "T"
            if val == 11:
                card_str = "J"
            if val == 12:
                card_str = "Q"
            if val == 13:
                card_str = "K"

        if card < 13:
            card_str += "h"
        elif card < 26:
            card_str += "d"
        elif card < 39:
            card_str += "s"
        else:
            card_str += "c"
        return Card.new(card_str)
Example #4
0
def create_cards(cards):

    # we want to return a list of Card objects, given the string label
    ret_cards = []
    for card in cards:
        ret_cards.append(Card.new(card))

    return ret_cards
Example #5
0
    def calculateHand(self, hole_card, round_state):
        """ 
        Passes what's on table and in your hand to deuces,
        to calculate hand strength,
        if the flop hasnt been played yet, return -1
        """
        if (round_state["community_card"] == []):
            return -1

        board = list(
            map(lambda x: Card.new(x[-1] + x[0].lower()),
                round_state["community_card"]))

        hand = list(map(lambda x: Card.new(x[-1] + x[0].lower()), hole_card))
        evaluator = Evaluator()
        #Return as a fraction, lower is better
        return (evaluator.evaluate(board, hand) / 7462)
Example #6
0
    def GetFullDeck():
        if Deck._FULL_DECK:
            return list(Deck._FULL_DECK)

        # create the standard 52 card deck
        for rank in Card.STR_RANKS:
            for suit, val in Card.CHAR_SUIT_TO_INT_SUIT.items():
                Deck._FULL_DECK.append(Card.new(rank + suit))

        return list(Deck._FULL_DECK)
Example #7
0
    def GetFullDeck():
        if Deck._FULL_DECK:
            return list(Deck._FULL_DECK)

        # create the standard 52 card deck
        for rank in Card.STR_RANKS:
            for suit,val in Card.CHAR_SUIT_TO_INT_SUIT.iteritems():
                Deck._FULL_DECK.append(Card.new(rank + suit))

        return list(Deck._FULL_DECK)
Example #8
0
    def evaluate_hand(board, hand):
        if board is None or len(board) < 3:
            raise ValueError("Missing board cards")
        if hand is None or len(hand) < 2:
            raise ValueError("Missing hole cards")

        deuces_board = [Card.new(board[0]), Card.new(board[1]), Card.new(board[2]),
                        Card.new(board[3]), Card.new(board[4])]
        deuces_hand = [Card.new(hand[0]), Card.new(hand[1])]

        evaluator = Evaluator()
        score = evaluator.evaluate(deuces_board, deuces_hand)
        hand_rank = evaluator.get_rank_class(score)
        hand_rank_str = evaluator.class_to_string(hand_rank)

        return hand_rank_str, score
Example #9
0
        st = PokerState()
        st.playerJustMoved = self.playerJustMoved
        st.deck = self.deck
        st.board = self.board
        st.player1 = self.player1
        st.player2 = self.player2
        return st

    def DoMove(self, move):
        """ Update a state by carrying out the given move.
            Must update playerJustMoved.
        """

        self.playerJustMoved = 3 - self.playerJustMoved

    def GetMoves(self):
        return ["aposta", "sai"]

    def GetResult(self, player1):
        p1 = self.evaluator.evaluate(self.player1, self.board)
        p2 = self.evaluator.evaluate(self.player2, self.board)
        if p1 < p2:
            return 1.0


board = [Card.new('Th'), Card.new('Kh'), Card.new('Qh'), Card.new('Jh')]
Card.print_pretty_cards(board)
p1 = [Card.new('8c'), Card.new('9c')]
e = Evaluator()

print e.evaluate(board, p1)
Example #10
0
from deuces.card import Card
from deuces.evaluator import Evaluator
from deuces.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)
print("Rank for your hand is: %d" % rank)

# 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:")
Card.print_pretty_cards(board)
    for card in hole_card + board:
        deck.remove_card(card)
    board_full = board + deck.draw(5 - len(board))
    opponents_hole = [deck.draw(2) for i in range(nb_player - 1)
                      ]  #[unused_cards[2 * i:2 * i + 2]
    opponents_score = [
        evaluator.evaluate(board_full, hole) for hole in opponents_hole
    ]  #[HandEvaluator.eval_hand(hole, community_card) for hole in opponents_hole]
    my_score = evaluator.evaluate(
        board_full,
        hole_card)  #HandEvaluator.eval_hand(hole_card, community_card)
    return 1 if my_score < min(opponents_score) else 0


evaluator = Evaluator()
hole_card = [Card.new('9s'), Card.new('Ks')]
board = [Card.new('8d'), Card.new('Ah'), Card.new('Kh')]
nb_players = 6
nb_simulations = 10000

time_1 = time.time()
hand_equity = deuces_estimate_win_rate(nb_simulations, nb_players, hole_card,
                                       board)
print("The equity is: " + str(hand_equity * 100) + "%")
time_2 = time.time()
print("The total time taken is: " + str((time_2 - time_1) * 1000) + " [ms]")

### Getting evals/s
evaluator = Evaluator()
hole_card = [Card.new('9s'), Card.new('Ks')]
board_full = [
Example #12
0
def to_deuces_intlist(L):
    return [Card.new(z) for z in pypoker_to_deuces_strlist(L)]
    def GenerateMultipliers(self,
                            hands,
                            hand_values,
                            num_players=4,
                            data_dir=None):
        """
        Generates an array full of multipliers used to calculate the results of gameplay
        
        hands =         Array of hands (rounds*all_hands_per_round, 3) with format:
                        [[dealer_Cards], [player1_cards], [player2_cards], [player3_cards], ...]
            
        hand_values =   Array of the associated hand ranks returned from evaluate_hands
        
        num_players =   Number of players per round (excluding the player/dealer)
        
        
        Returns array of multipliers (num_rounds,num_players,4) specifying the following for each hand:

            multipliers[round,hand,0]:    Play multiplier -- determines whether hand should be played
                                                             and whether it wins, loses, or pushes
                                                             (1 = win, -1 = loss, 0 = no play or push)
                                                            
            multipliers[round,hand,1]:    Ante multiplier -- 0 = ante pushes, 1 = ante wins, -1 = ante loses
            
            multipliers[round,hand,2]:    Pair Plus multiplier -- -1 if Pair Plus loses, otherwise the bonus multiple
            
            multipliers[round,hand,3]:    6-Card Multiplier -- -1 if 6-Card bonus loses, otherwise the bonus multiple
        """

        if data_dir is None:
            data_dir = self.tmp_dir

        all_hands = num_players + 1
        num_rounds = len(hands) / all_hands

        multipliers = np.memmap(path.join(data_dir, 'multipliers'),
                                dtype='int32',
                                mode='w+',
                                shape=(num_rounds, num_players, 4))

        play_multipliers = multipliers[:, :, 0]
        ante_multipliers = multipliers[:, :, 1]
        pair_plus_multipliers = multipliers[:, :, 2]
        six_card_multipliers = multipliers[:, :, 3]

        #group hand values into sets of 1 dealer hand + related player hands
        #Split the dealer values into one group and player values into another
        splittable_values = hand_values.reshape(-1, all_hands)
        dealer_values = splittable_values.T[0].reshape(-1, 1)
        player_values = splittable_values.T[1:].T

        #Lower valued hands beat higher valued hands
        #Win_lose = -1 for player hands that lose, 1 for wins, and 0 for ties
        win_lose = np.memmap(path.join(data_dir, 'win_lose'),
                             dtype='int32',
                             mode='w+',
                             shape=(num_rounds, num_players))
        win_lose[:] = np.copysign(1, dealer_values - player_values)

        #Hand and card ranks needed to determine when play bet should be made for each hand
        #The suits are arbitrary as long as these are unsuited hands
        ACE_HIGH = self.evaluate_hand(Card.hand_to_binary(['Ac', '2d', '4d']))
        KING_HIGH = self.evaluate_hand(Card.hand_to_binary(['Kc', '2d', '3d']))
        QUEEN_HIGH = self.evaluate_hand(Card.hand_to_binary(['Qc', '2d',
                                                             '3d']))
        ACE = Card.get_rank_int(Card.new('Ac'))
        KING = Card.get_rank_int(Card.new('Kc'))
        QUEEN = Card.get_rank_int(Card.new('Qc'))

        #In each round, one dealer card is dealt face up
        #Here we build an array view containing the first dealer card for each round as our face up card
        #hands.reshape(1,-1)[0] is equivalent to hands.flatten() without copying into a new array

        dealer_face_up = hands.reshape(1,
                                       -1)[0][0::all_hands * 3].reshape(-1, 1)

        #Face up dealer cards are converted to int ranks
        #face_up_rank = (dealer_face_up>>8)&0xFF

        #Hand plays based on House Way:
        #    Always play A high or better
        #    Play K high if dealer face up card is K or worse
        #    Play Q high if dealer face up card is Q or worse
        #    Never play hands less than Q high

        #Play the hand = 1, don't play = 0

        play_multipliers[:] = np.where(
            player_values <= ACE_HIGH, 1,
            np.where(
                player_values <= KING_HIGH,
                np.where((dealer_face_up >> 8) & 0xF < ACE, 1, 0),
                np.where(player_values <= QUEEN_HIGH,
                         np.where((dealer_face_up >> 8) & 0xF < KING, 1, 0),
                         0)))

        #Pair Plus bonus loses (-1) when a player's hand is less than a pair
        #Otherwise it pays a multiple of the bet depending on the hand strength for pairs and better
        #The bet plays independently of the hand winning or losing,
        #but if the player does not make a play bet, the Pair Plus bonus is forfeit (-1)

        #Pay chart
        #    Worse than one pair:  -1
        #    Pair: 1x
        #    Flush: 3x
        #    Straight: 6x
        #    Straight flush: 30x
        #    Royal flush: 50x

        pair_plus_multipliers[:] = np.where(
            play_multipliers == 0, -1,
            np.where(
                player_values > self.tc_lookup.MAX_PAIR, -1,
                np.where(
                    player_values > self.tc_lookup.MAX_FLUSH, 1,
                    np.where(
                        player_values > self.tc_lookup.MAX_STRAIGHT, 3,
                        np.where(
                            player_values > self.tc_lookup.MAX_TRIPS, 6,
                            np.where(
                                player_values >
                                self.tc_lookup.MAX_STRAIGHT_FLUSH, 30,
                                np.where(player_values > 1, 40, 50)))))))

        #Calculate Ante wins/losses
        #If a play bet is not made, ante loses (-1) automatically
        #If a play bet is made:
        #    Hand wins:  ante wins (+1)
        #    Hand loses: ante loses (-1) if dealer has Q high or better, otherwise pushes (0)

        ante_multipliers[:] = np.where(
            play_multipliers == 0, -1,
            np.where(win_lose > -1, win_lose,
                     np.where(dealer_values <= QUEEN_HIGH, -1, 0)))

        #Calculate Play wins/losses
        #We need to do this after calculating the Pair Plus bonus
        #so we don't confuse ties with forfeit hands
        #If the dealer hand is worse than Q high, the Play bet pushes (0)

        play_multipliers[:] = np.where(dealer_values <= QUEEN_HIGH,
                                       play_multipliers * win_lose, 0)

        del win_lose

        #Now we need to compute the 6-card bonuses
        #These are based on the best 5-card hand that can be made from the player's 3 card and the dealer's 3

        #The first out of each group of hands is the dealer hand for that group
        #The rest are the player hands
        #we want groups like: [dcard1, dcard2, dcard3, pcard1, pcard2, pcard3]
        #to pass to deuces' hand evaluator
        #This requires some slicing arobatics to avoid building new arrays

        #Hands are arranged by round such as dealer_cards, player1_cards, player2_cards, etc.
        #Then stepped slices are taken and truncated to form slices for each combo of dealer and player cards

        #eg. If hands = [D01, D02, D03, Pa1, Pa2, Pa3, Pb1, Pb2, Pb3,
        #                D11, D12, D13, Pc1, Pc2, Pc3, Pd1, Pd2, Pd3]
        #
        #Then eval_hands[0] = [[D01, D02, D03, Pa1, Pa2, Pa3],
        #                      [D11, D12, D13, Pc1, Pc2, Pc3]]
        #
        #     eval_hands[1] = [[D01, D02, D03, Pb1, Pb2, Pb3],
        #                      [D11, D12, D13, Pd1, Pd2, Pd3]]

        eval_hands = [
            hands.reshape(-1, all_hands, 3)[:, ::i + 1][:, :2].reshape(-1, 6)
            for i in xrange(num_players)
        ]

        #calculate 6card bonuses
        evaluator = Evaluator()

        #This is the main bottleneck in the simulator
        #The only real way to resolve it is to rebuild the deuces library's
        #hand evaluator to process arrays of hands rather than one at a time,
        #which is currently beyond the scope of this project

        for i in xrange(num_players):
            six_card_multipliers[:, i] = np.apply_along_axis(
                evaluator._six, 1, eval_hands[i])

        #Map hand values to bonus payouts

        SC_MAX_STRAIGHT_FLUSH = evaluator.table.MAX_STRAIGHT_FLUSH
        SC_MAX_QUADS = evaluator.table.MAX_FOUR_OF_A_KIND
        SC_MAX_FULL_HOUSE = evaluator.table.MAX_FULL_HOUSE
        SC_MAX_FLUSH = evaluator.table.MAX_FLUSH
        SC_MAX_STRAIGHT = evaluator.table.MAX_STRAIGHT
        SC_MAX_TRIPS = evaluator.table.MAX_THREE_OF_A_KIND

        #6-Card Bonus Payout table
        #Worse than trips  -1
        #Trips              5
        #Straight           10
        #Flush              15
        #Full House         25
        #Quads              50
        #Straight Flush     200
        #Royal Flush        1000

        six_card_multipliers[:] = np.where(
            six_card_multipliers > SC_MAX_TRIPS, -1,
            np.where(
                six_card_multipliers > SC_MAX_STRAIGHT, 5,
                np.where(
                    six_card_multipliers > SC_MAX_FLUSH, 10,
                    np.where(
                        six_card_multipliers > SC_MAX_FULL_HOUSE, 15,
                        np.where(
                            six_card_multipliers > SC_MAX_QUADS, 25,
                            np.where(
                                six_card_multipliers > SC_MAX_STRAIGHT_FLUSH,
                                50,
                                np.where(six_card_multipliers > 1, 200,
                                         1000)))))))

        return multipliers
Example #14
0
def all_evaluation(full_board, evaluator):
    """
    Efficient evaluation of all possible hands on a board.
    Args:
        full_board: list of int (deuces cards). Despite its name, does not actually have to be a 5-card board (can be 3, 4, or 5 cards)
        evaluator: deuces Evaluator object 
    Returns: 
        dict of deuces cards with evaluations
    """

    all_hands = {}
    fp = flush_possible(full_board)
    ranks = ['A', 'K', 'Q', 'J', 'T', '9', '8', '7', '6', '5', '4', '3', '2']
    suits = ['s', 'c', 'd', 'h']
    equivalent_lists = []

    if fp[0] == 'n' or fp[1] == 2:
        for rank in ranks:
            this_rank = []
            for suit in suits:
                card = Card.new(rank + suit)
                if card not in full_board:
                    this_rank.append(card)
            equivalent_lists.append(this_rank)
    elif fp[1] <= 1:  #where all cards with the same rank not of the flush suit are indistinct
        altered_suits = deepcopy(suits)
        altered_suits.remove(fp[0])
        for rank in ranks:
            this_rank = []
            for suit in altered_suits:
                card = Card.new(rank + suit)
                if card not in full_board:
                    this_rank.append(card)
            equivalent_lists.append(this_rank)

            card_of_suit = Card.new(rank + fp[0])
            if card_of_suit not in full_board:
                equivalent_lists.append([card_of_suit])

    combos = combinations_with_replacement(equivalent_lists, 2)

    if fp[1] == 2:
        for combo in combos:
            for equivalent_x in combo[0]:
                for equivalent_y in combo[1]:
                    if equivalent_x != equivalent_y and (
                            Card.int_to_str(equivalent_x)[1] !=
                            Card.int_to_str(equivalent_y)[1]):
                        evaluation_most = evaluator.evaluate(
                            full_board, [equivalent_x, equivalent_y])
                        break

            for equivalent_x in combo[0]:
                for equivalent_y in combo[1]:
                    if equivalent_x != equivalent_y and (
                            Card.int_to_str(equivalent_x)[1] !=
                            Card.int_to_str(equivalent_y)[1]):
                        all_hands[tuple(sorted([equivalent_x, equivalent_y
                                                ]))] = evaluation_most
                    elif equivalent_x != equivalent_y and (
                            Card.int_to_str(equivalent_x)[1]
                            == Card.int_to_str(equivalent_y)[1]):
                        special_evaluation = evaluator.evaluate(
                            full_board, [equivalent_x, equivalent_y])
                        all_hands[tuple(sorted([equivalent_x, equivalent_y
                                                ]))] = special_evaluation

    else:
        for combo in combos:
            for equivalent_x in combo[0]:
                for equivalent_y in combo[1]:
                    if equivalent_x != equivalent_y:
                        evaluation = evaluator.evaluate(
                            full_board, [equivalent_x, equivalent_y])
                        break
            for equivalent_x in combo[0]:
                for equivalent_y in combo[1]:
                    if equivalent_x != equivalent_y:
                        all_hands[tuple(sorted([equivalent_x,
                                                equivalent_y]))] = evaluation

    return all_hands