def straight_and_highcards(self, straights, highcards): """ Unique five card sets. Straights and highcards. Reuses bit sequences from flush calculations. """ rank = LookupTable.MAX_FLUSH + 1 for s in straights: prime_product = Card.prime_product_from_rankbits(s) self.unsuited_lookup[prime_product] = rank rank += 1 rank = LookupTable.MAX_PAIR + 1 for h in highcards: prime_product = Card.prime_product_from_rankbits(h) self.unsuited_lookup[prime_product] = rank rank += 1
class Deck: """ Class representing a deck. The first time we create, we seed the static deck with the list of unique card integers. Each object instantiated simply makes a copy of this object and shuffles it. """ _FULL_DECK_LEDUC = [1, 1, 2, 2, 3, 3] _FULL_DECK_HUNL = [ Card.new(rank + suit) for suit, val in Card.CHAR_SUIT_TO_INT_SUIT.items() for rank in Card.STR_RANKS ] _FULL_DECK_KUHN = [1, 2, 3] def __init__(self, deck_size): assert deck_size in (3, 6, 52) self.cards = Deck.GetFullDeck(deck_size) shuffle(self.cards) def draw(self, n=1): if n == 1: return self.cards.pop(0) cards = [] for i in range(n): cards.append(self.draw()) return cards def __str__(self): return Card.print_pretty_cards(self.cards) @staticmethod def GetFullDeck(deck_size): if deck_size == 6: return list(Deck._FULL_DECK_LEDUC) elif deck_size == 52: return list(Deck._FULL_DECK_HUNL) else: return list(Deck._FULL_DECK_KUHN)
def repr_hole(hole): return repr([Card.int_to_str(c) for c in hole])
def repr_board(board): return repr([[Card.int_to_str(c) for c in round_cards] for round_cards in board])
import random from ESMCCFR import ESMCCFR_P from deuces2.card import Card from Strategy import Strategy print("Welcome to Heads Up Texas No Limit Hold'Em") infoset_strategy_map = pickle.load(open('strategy.pkl', 'rb')) utility_methods = ESMCCFR_P() State = utility_methods.initialize_State() player = random.randint(1, 2) print("You are player", player) if player == 1: print("You are the big blind, you post", State.p1_contrib) print("Your private card is", Card.int_to_str(State.p1_card)) elif player == 2: print("You are the small blind, you post", State.p2_contrib) print("Your private card is", Card.int_to_str(State.p2_card)) while not State.is_terminal(): players_turn = State.get_players_turn() possible_actions = State.get_possible_actions(players_turn) infoset = State.get_infoset(players_turn) if players_turn == player: print("The current community card is", [Card.int_to_str(c) for c in infoset.flop_card]) print("You can bet the following amounts:", possible_actions) action = int(input('Your action: ')) State.update(players_turn, action) else:
def __str__(self): return Card.print_pretty_cards(self.cards)
def pretty(self, card): return Card.int_to_pretty_str(card)
from deuces2.card import Card print(Card.int_to_str(1))
def flushes(self): """ Straight flushes and flushes. Lookup is done on 13 bit integer (2^13 > 7462): xxxbbbbb bbbbbbbb => integer hand index """ # straight flushes in rank order straight_flushes = [ 7936, # int('0b1111100000000', 2), # royal flush 3968, # int('0b111110000000', 2), 1984, # int('0b11111000000', 2), 992, # int('0b1111100000', 2), 496, # int('0b111110000', 2), 248, # int('0b11111000', 2), 124, # int('0b1111100', 2), 62, # int('0b111110', 2), 31, # int('0b11111', 2), 4111 # int('0b1000000001111', 2) # 5 high ] # now we'll dynamically generate all the other # flushes (including straight flushes) flushes = [] gen = self.get_lexographically_next_bit_sequence(int('0b11111', 2)) # 1277 = number of high cards # 1277 + len(str_flushes) is number of hands with all cards unique rank for i in range(1277 + len(straight_flushes) - 1): # we also iterate over SFs # pull the next flush pattern from our generator f = next(gen) # if this flush matches perfectly any # straight flush, do not add it notSF = True for sf in straight_flushes: # if f XOR sf == 0, then bit pattern # is same, and we should not add if not f ^ sf: notSF = False if notSF: flushes.append(f) # we started from the lowest straight pattern, now we want to start ranking from # the most powerful hands, so we reverse flushes.reverse() # now add to the lookup map: # start with straight flushes and the rank of 1 # since theyit is the best hand in poker # rank 1 = Royal Flush! rank = 1 for sf in straight_flushes: prime_product = Card.prime_product_from_rankbits(sf) self.flush_lookup[prime_product] = rank rank += 1 # we start the counting for flushes on max full house, which # is the worst rank that a full house can have (2,2,2,3,3) rank = LookupTable.MAX_FULL_HOUSE + 1 for f in flushes: prime_product = Card.prime_product_from_rankbits(f) self.flush_lookup[prime_product] = rank rank += 1 # we can reuse these bit sequences for straights # and high cards since they are inherently related # and differ only by context self.straight_and_highcards(straight_flushes, flushes)