def __init__(self): self.ALL_CARDS = np.array([i for i in range(52)]) self.hands = [] self.flop = (-1, -1, -1) self.turn = -1 self.river = -1 self.eval = Evaluator()
def __init__(self): self.playerJustMoved = 2 self.deck = Deck() self.board = self.deck.draw(3) self.player1 = self.deck.draw(2) self.player2 = self.deck.draw(2) self.evaluator = Evaluator()
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
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)
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)
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)
def __init__(self, smallBlind=1): self.deck = Deck() self.players = [] self.smallBlind = smallBlind self.bigBlind = self.smallBlind * 2 self.evaluator = Evaluator()
def create_alsm(self): # the table containing all ranks where the Ace could be in a straight, depending on the lowest card # we'll call it, ace-low-straight-map # this will be the mapping: # A3456 -> 23456 # A4567 -> 34567 # A5678 -> 45678 # A6789 -> 56789 # A789T -> 6789T # A89TJ -> 789TJ # A9TJQ -> 89TJQ # However, we should obtain the rank of the hands through calculation, # rather than store their values evaluator = Evaluator() offsuit_A3456_rank = evaluator.evaluate(create_cards(["Ah","3h","4h","5h","6h"]),[]) offsuit_A4567_rank = evaluator.evaluate(create_cards(["Ah","4h","5h","6h","7h"]),[]) offsuit_A5678_rank = evaluator.evaluate(create_cards(["Ah","5h","6h","7h","8h"]),[]) offsuit_A6789_rank = evaluator.evaluate(create_cards(["Ah","6h","7h","8h","9h"]),[]) offsuit_A789T_rank = evaluator.evaluate(create_cards(["Ah","7h","8h","9h","Th"]),[]) offsuit_A89TJ_rank = evaluator.evaluate(create_cards(["Ah","8h","9h","Th","Jh"]),[]) offsuit_A9TJQ_rank = evaluator.evaluate(create_cards(["Ah","9h","Th","Jh","Qh"]),[]) offsuit_23456_rank = evaluator.evaluate(create_cards(["2h","3h","4h","5h","6h"]),[]) offsuit_34567_rank = evaluator.evaluate(create_cards(["3h","4h","5h","6h","7h"]),[]) offsuit_45678_rank = evaluator.evaluate(create_cards(["4h","5h","6h","7h","8h"]),[]) offsuit_56789_rank = evaluator.evaluate(create_cards(["5h","6h","7h","8h","9h"]),[]) offsuit_6789T_rank = evaluator.evaluate(create_cards(["6h","7h","8h","9h","Th"]),[]) offsuit_789TJ_rank = evaluator.evaluate(create_cards(["7h","8h","9h","Th","Jh"]),[]) offsuit_89TJQ_rank = evaluator.evaluate(create_cards(["8h","9h","Th","Jh","Qh"]),[]) onsuit_A3456_rank = evaluator.evaluate(create_cards(["Ah","3h","4h","5h","6c"]),[]) onsuit_A4567_rank = evaluator.evaluate(create_cards(["Ah","4h","5h","6h","7c"]),[]) onsuit_A5678_rank = evaluator.evaluate(create_cards(["Ah","5h","6h","7h","8c"]),[]) onsuit_A6789_rank = evaluator.evaluate(create_cards(["Ah","6h","7h","8h","9c"]),[]) onsuit_A789T_rank = evaluator.evaluate(create_cards(["Ah","7h","8h","9h","Tc"]),[]) onsuit_A89TJ_rank = evaluator.evaluate(create_cards(["Ah","8h","9h","Th","Jc"]),[]) onsuit_A9TJQ_rank = evaluator.evaluate(create_cards(["Ah","9h","Th","Jh","Qc"]),[]) onsuit_23456_rank = evaluator.evaluate(create_cards(["2h","3h","4h","5h","6c"]),[]) onsuit_34567_rank = evaluator.evaluate(create_cards(["3h","4h","5h","6h","7c"]),[]) onsuit_45678_rank = evaluator.evaluate(create_cards(["4h","5h","6h","7h","8c"]),[]) onsuit_56789_rank = evaluator.evaluate(create_cards(["5h","6h","7h","8h","9c"]),[]) onsuit_6789T_rank = evaluator.evaluate(create_cards(["6h","7h","8h","9h","Tc"]),[]) onsuit_789TJ_rank = evaluator.evaluate(create_cards(["7h","8h","9h","Th","Jc"]),[]) onsuit_89TJQ_rank = evaluator.evaluate(create_cards(["8h","9h","Th","Jh","Qc"]),[]) # the dictionary defining the necessary mappings, # ace-low-straight-map alsm = { (offsuit_A3456_rank,3) : offsuit_23456_rank, (offsuit_A4567_rank,4) : offsuit_34567_rank, (offsuit_A5678_rank,5) : offsuit_45678_rank, (offsuit_A6789_rank,6) : offsuit_56789_rank, (offsuit_A789T_rank,7) : offsuit_6789T_rank, (offsuit_A89TJ_rank,8) : offsuit_789TJ_rank, (offsuit_A9TJQ_rank,9) : offsuit_89TJQ_rank, (onsuit_A3456_rank,3) : onsuit_23456_rank, (onsuit_A4567_rank,4) : onsuit_34567_rank, (onsuit_A5678_rank,5) : onsuit_45678_rank, (onsuit_A6789_rank,6) : onsuit_56789_rank, (onsuit_A789T_rank,7) : onsuit_6789T_rank, (onsuit_A89TJ_rank,8) : onsuit_789TJ_rank, (onsuit_A9TJQ_rank,9) : onsuit_89TJQ_rank } return alsm
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