Пример #1
0
def play_the_board(cards, board_cards):
    hand = [eval7.Card(s) for s in (cards[:2], cards[2:])]
    board = [
        eval7.Card(s)
        for s in [board_cards[i:i + 2] for i in range(0, len(board_cards), 2)]
    ]
    hand_type = eval7.hand_type(eval7.evaluate(hand + board))
    board_type = eval7.hand_type(eval7.evaluate(board))

    if hand_type != board_type:
        return False
    # cannot have a higher pair/trips
    elif hand_type in ['High Card', 'Pair', 'Trips']:
        return True
    # can have a higher two pair, if evaluation is highly different
    elif hand_type in ['Two Pair']:
        # do something
        numbers = [
            'A', 'K', 'Q', 'J', 'T', '9', '8', '7', '6', '5', '4', '3', '2'
        ]
        return [2 if (cards+board_cards)[::2].count(i) == 2 else 0 for i in numbers] == \
               [2 if board_cards[::2].count(i) == 2 else 0 for i in numbers]
    # five card hands will evaluate to the same
    else:
        return eval7.evaluate(hand + board) == eval7.evaluate(board)
def getScore(c1, c2, iters=10000):
    score = 0
    for i in range(iters):
        deck = eval7.Deck()
        deck.shuffle()
        myHand = [c1, c2]

        d = deck.deal(52)
        d.remove(c1)
        d.remove(c2)

        oppHand = []
        for i in range(2):
            oppHand.append(d.pop(0))

        street = []
        for i in range(5):
            street.append(d.pop(0))

        myHand = myHand + street
        oppHand = oppHand + street

        if eval7.evaluate(myHand) > eval7.evaluate(oppHand):
            score += 1

    return score / iters
Пример #3
0
def calc_win_prob_by_sampling_eval7(sim_num, hole_cards, board_cards, data):
    """
    Calculate the probability to win current players by sampling unknown cards
    Compute the probability to win one player first
    And then take the power of virtual player count
    """
    o_hole_cards = []
    o_board_cards = []
    deck = eval7.Deck()
    # remove hole cards and board cards from deck
    for card in hole_cards:
        card = eval7.Card(card)
        o_hole_cards.append(card)
        deck.cards.remove(card)
    board_cards_to_draw = 5
    for card in board_cards:
        board_cards_to_draw -= 1
        card = eval7.Card(card)
        o_board_cards.append(card)
        deck.cards.remove(card)
    vpc_weighted = 1
    rivals_count = get_rivals_count(data)
    win = 0
    succeeded_sample = 0
    start = time.time()
    if board_cards_to_draw:
        for _ in range(sim_num // rivals_count):
            simulate_cards = deck.sample(board_cards_to_draw + 2 * rivals_count)
            o_board_sample = o_board_cards + simulate_cards[:board_cards_to_draw]
            my_rank = eval7.evaluate(o_board_sample + o_hole_cards)
            won = True
            for i in range(board_cards_to_draw, board_cards_to_draw + 2 * rivals_count, 2):
                if my_rank < eval7.evaluate(o_board_sample + simulate_cards[i:i + 2]):
                    won = False
                    break
            if won:
                win += 1
            succeeded_sample += 1
    else:
        my_rank = eval7.evaluate(o_board_cards + o_hole_cards)
        n = sim_num * 1.1
        for _ in range(n // rivals_count):
            won = True
            simulate_cards = deck.sample(2 * rivals_count)
            for i in range(0, 2 * rivals_count, 2):
                if my_rank < eval7.evaluate(o_board_cards + simulate_cards[i:i + 2]):
                    won = False
                    break
            if won:
                win += 1
            succeeded_sample += 1
    print("==== sampling result ==== win : %d, total : %d, takes: %f seconds" %
          (win, succeeded_sample, time.time() - start))
    win_one_prob = win * vpc_weighted / succeeded_sample

    # win_all_prob = win_one_prob ** virtual_player_count(data)
    print("==== Win probability ==== " + str(win_one_prob))
    return win_one_prob
Пример #4
0
 def showdown(self):
     '''
     Compares the players' hands and computes payoffs.
     '''
     score0 = eval7.evaluate(self.deck.peek(5) + self.hands[0])
     score1 = eval7.evaluate(self.deck.peek(5) + self.hands[1])
     if score0 > score1:
         winnings = [self.pot, 0]
     elif score0 < score1:
         winnings = [0, self.pot]
     else:  # split the pot
         winnings = [self.pot // 2, self.pot // 2]
     return TerminalState(winnings, self)
Пример #5
0
 def showdown(self):
     '''
     Compares the players' hands and computes payoffs.
     '''
     score0 = eval7.evaluate(list(map(PERM.get, self.deck.peek(5) + self.hands[0])))
     score1 = eval7.evaluate(list(map(PERM.get, self.deck.peek(5) + self.hands[1])))
     if score0 > score1:
         delta = cfg.STARTING_STACK - self.stacks[1]
     elif score0 < score1:
         delta = self.stacks[0] - cfg.STARTING_STACK
     else:  # split the pot
         delta = (self.stacks[0] - self.stacks[1]) // 2
     return TerminalState([delta, -delta], self)
Пример #6
0
    def calculate_strength(self, hole, board_cards, iters):
        '''
        A Monte Carlo method meant to estimate the win probability of a pair of 
        hole cards. Simlulates 'iters' games and determines the win rates of our cards
        Arguments:
        hole: a list of our two hole cards
        iters: a integer that determines how many Monte Carlo samples to take
        '''
        deck = eval7.Deck()  #eval7 object!
        hole_cards = [eval7.Card(card)
                      for card in hole]  #card objects, used to evaliate hands
        board_cards = [eval7.Card(card) for card in board_cards if card]

        for card in board_cards:
            deck.cards.remove(card)
        for card in hole_cards:
            deck.cards.remove(card)

        score = 0

        for _ in range(iters):  #take 'iters' samples
            deck.shuffle()  #make sure our samples are random

            _COMM = 5 - len(board_cards)  #the number of cards we need to draw
            _OPP = 2

            draw = deck.peek(_COMM + _OPP)

            opp_hole = draw[:_OPP]
            community = draw[_OPP:]

            our_hand = hole_cards + community + board_cards  #the two showdown hands
            opp_hand = opp_hole + community + board_cards

            our_hand_value = eval7.evaluate(
                our_hand
            )  #the ranks of our hands (only useful for comparisons)
            opp_hand_value = eval7.evaluate(opp_hand)

            if our_hand_value > opp_hand_value:  #we win!
                score += 2

            elif our_hand_value == opp_hand_value:  #we tie.
                score += 1

            else:  #we lost....
                score += 0

        hand_strength = score / (2 * iters)  #this is our win probability!

        return hand_strength
Пример #7
0
def projectEulerProblemFiftyFour(myList):
    total = 0
    for x in myList:
        a = x[0:5]
        b = x[5:]
        oneHand = []
        for card in a:
            oneHand.append(eval7.Card(card[0]+card[1].lower()))
        twoHand = []
        for card in b:
            twoHand.append(eval7.Card(card[0]+card[1].lower()))
        if(eval7.evaluate(oneHand)>eval7.evaluate(twoHand)):
            total+=1
    return total
Пример #8
0
def play_game(network_1, network_2, blinds, hands):
    for _ in range(hands):

        # Draw and distribute cards
        cards = deck.sample(9)
        p1_hole_cards = cards[0:2]
        p2_hole_cards = cards[2:4]
        board = cards[4:9]
        p1_cards = p1_hole_cards + board
        p2_cards = p2_hole_cards + board

        # Create the input to p1: a 52 value array filled with zeroes and two indices
        # where the value is 1. These two indices corresponds to p1_hole_cards.
        p1_input = np.zeros(52)
        card_id_1 = p1_hole_cards[0].rank + p1_hole_cards[0].suit * 13
        card_id_2 = p1_hole_cards[1].rank + p1_hole_cards[1].suit * 13
        p1_input[card_id_1] = 1
        p1_input[card_id_2] = 1
        p1_answer = get_answer(network_1["weights"], p1_input)

        if p1_answer != 0:

            p2_input = np.zeros(52)
            card_id_1 = p2_hole_cards[0].rank + p2_hole_cards[0].suit * 13
            card_id_2 = p2_hole_cards[1].rank + p2_hole_cards[1].suit * 13
            p2_input[card_id_1] = 1
            p2_input[card_id_2] = 1
            p2_answer = get_answer(network_2["weights"], p2_input)

            if p2_answer != 0:
                p1_eval = eval7.evaluate(p1_cards)
                p2_eval = eval7.evaluate(p2_cards)
                if p1_eval > p2_eval:
                    network_1["performance"] += blinds
                    network_2["performance"] -= blinds
                elif p1_eval < p2_eval:
                    network_1["performance"] -= blinds
                    network_2["performance"] += blinds

            else:
                # Player 2 folded
                network_1["performance"] += 1
                network_2["performance"] -= 1

        else:
            # Player 1 folded
            network_1["performance"] -= 0.5
            network_2["performance"] += 0.5
Пример #9
0
 def calculate(self, hand_range_string, board_card_strings):
     """Calculate the probabilities of each hand type."""
     for key in hand_types + draw_types + pair_types:
         self[key] = 0.0
     board = map(eval7.Card, board_card_strings)
     hr = hand_range.HandRange(hand_range_string)
     hr.exclude_cards(board)
     if len(board) < 3:
         raise ValueError("Not enough cards in board!")
     for hand, prob in hr.iteritems():
         if not prob == 0.0:
             cards = board + list(hand)
             result = eval7.evaluate(cards)
             hand_type = eval7.hand_type(result)
             self[hand_type] += prob
             if len(cards) < 7 and hand_types.index(hand_type) < 5:
                 # No flush or better, so there may be draws.
                 if self.check_flush_draw(cards):
                     self["Flush Draw"] += prob
                 if hand_type != 'Straight':
                     straight_draw_type = self.check_straight_draw(cards)
                     if straight_draw_type is not None:
                         self[straight_draw_type] += prob
             if hand_type == "Pair":
                 # Break down pairs by type.
                 self[self.pair_type(hand, board)] += prob
Пример #10
0
def canbe_straight(cards):
    count = 0
    for c in [eval7.Card(x + "d") for x in eval7.ranks]:
        if not c.rank in [x.rank for x in cards]:
            hand_type = eval7.hand_type(eval7.evaluate(cards + [c]))
            if hand_type in ["Straight", "Straight Flush"]:
                count += 1
    return count
Пример #11
0
 def rank_hand_py(self, player):
     print('Player ' + player.name + ' hand: ' + player.hole_cards_str())
     cards = [eval7.Card(s) for s in
              (str(player.hole_cards[0]), str(player.hole_cards[1]), str(self.community[1][0]),
               str(self.community[1][1]), str(self.community[1][2]), str(self.community[2][0]),
               str(self.community[3][0]))]
     rank = eval7.evaluate(cards)
     handtype = eval7.handtype(rank)
     print(player.name + ' hand rank: ' + str(rank) + ', hand type: ' + handtype)
     return rank
Пример #12
0
def calc_num_outs(curr_hand):
    # no outs pre flop
    if len(curr_hand) == 2:
        return 0

    # calculate outs after flop and turn
    deck = eval7.Deck()
    remaining_cards = list(set(deck.cards) - set(curr_hand))
    num_outs = 0
    curr_strength = eval7.evaluate(curr_hand)
    curr_rank = eval7.handtype(curr_strength)
    for card in remaining_cards:
        hand = curr_hand + [card]
        hand_strength = eval7.evaluate(hand)
        hand_rank = eval7.handtype(hand_strength)
        if hand_strength > curr_strength and hand_rank != curr_rank:
            num_outs += 1

    return num_outs
Пример #13
0
    def is_consistent_with_result(self, p, result):
        board_and_winner_true = [
            eval7.Card(c)
            for c in p.map_str(result.board_cards + result.winner_hole_cards)
        ]
        board_and_loser_true = [
            eval7.Card(c)
            for c in p.map_str(result.board_cards + result.loser_hole_cards)
        ]

        score_winner = eval7.evaluate(board_and_winner_true)
        score_loser = eval7.evaluate(board_and_loser_true)

        # If the losing hand has a higher score than the winning score, then the permutation is
        # inconsistent with observations.
        if score_winner <= score_loser:
            return False
        else:
            return True
Пример #14
0
    def showdown(self):
        '''
        Compares the players' hands and computes payoffs.
        '''

        global STRAIGHTS

        score0 = eval7.evaluate(list(self.deck.peek(5) + self.hands[0]))
        score1 = eval7.evaluate(list(self.deck.peek(5) + self.hands[1]))
        if score0 > score1:
            delta = STARTING_STACK - self.stacks[1]
            if eval7.hand_type(score0) == 'Straight':
                STRAIGHTS[0] += 1
        elif score0 < score1:
            delta = self.stacks[0] - STARTING_STACK
            if eval7.hand_type(score1) == 'Straight':
                STRAIGHTS[1] += 1
        else:  # split the pot
            delta = (self.stacks[0] - self.stacks[1]) // 2
        return TerminalState([delta, -delta], self)
Пример #15
0
def evaluate(data):
    if data["game"]["board"] is not None:
        cards = data["self"]["cards"] + data["game"]["board"]
    else:
        cards = data["self"]["cards"]
    hand = [eval7.Card(x.capitalize()) for x in cards]
    score = eval7.evaluate(hand)
    type = eval7.hand_type(score)
    suitcount = maxsuitcount(hand)
    straight = canbe_straight(hand)
    return (hand, score, type, suitcount, straight)
Пример #16
0
 def handle_round_over(self, game_state, terminal_state, active):
     '''
     Called when a round ends. Called NUM_ROUNDS times.
     Arguments:
     game_state: the GameState object.
     terminal_state: the TerminalState object.
     active: your player's index.
     Returns:
     Nothing.
     '''
     my_delta = terminal_state.deltas[
         active]  # your bankroll change from this round
     previous_state = terminal_state.previous_state  # RoundState before payoffs
     street = previous_state.street  # 0, 3, 4, or 5 representing when this round ended
     my_cards = previous_state.hands[active]  # your cards
     opp_cards = previous_state.hands[
         1 - active]  # opponent's cards or [] if not revealed
     board_cards = previous_state.deck[:street]
     if opp_cards != []:  # we have a showdown
         new_perms = []
         for proposal_perm in self.proposal_perms:  # check if valid
             my_perm_cards = [proposal_perm[c] for c in my_cards]
             opp_perm_cards = [proposal_perm[c] for c in opp_cards]
             board_perm_cards = [proposal_perm[c] for c in board_cards]
             my_cards_available = my_perm_cards + board_perm_cards
             opp_cards_available = opp_perm_cards + board_perm_cards
             my_strength = eval7.evaluate(my_cards_available)
             opp_strength = eval7.evaluate(opp_cards_available)
             # consistent with my win
             if my_strength > opp_strength and my_delta > 0:
                 new_perms.append(proposal_perm)
             # consistent with opp win
             if my_strength < opp_strength and my_delta < 0:
                 new_perms.append(proposal_perm)
             # consistent with a tie
             if my_strength == opp_strength and my_delta == 0:
                 new_perms.append(proposal_perm)
         if len(new_perms) >= 10:
             self.proposal_perms = new_perms
     if game_state.round_num == NUM_ROUNDS:
         print(game_state.game_clock)
Пример #17
0
def showdown(p, board_state):
    '''
    Computes a showdown between two players, assessed using p as the desired permutation.
    OUTPUTS:
     1: a > b
     0: a = b
    -1: a > b
    '''
    #proposed_dict = pdict(p)
    #pa = [perm_dict[x] for x in a]
    #pb = [perm_dict[x] for x in b]
    #pboard = [perm_dict[x] for x in board]
    a, b, board = board_state
    pa = [translate_card(p, x) for x in a]
    pb = [translate_card(p, x) for x in b]
    pboard = [translate_card(p, x) for x in board]

    a_val = eval7.evaluate(pa + pboard)
    b_val = eval7.evaluate(pb + pboard)

    if a_val > b_val:
        #print(a)
        #print("beats")
        #print(b)
        if a_val == 4:
            return 2
        return 1
    elif a_val < b_val:
        #print(b)
        #print("beats")
        #print(a)
        if b_val == 4:
            return -2
        return -1
    else:
        #print(a)
        #print("ties")
        #print(b)
        return 0
Пример #18
0
    def get_action(self, game_state, round_state, active):
        '''
        Where the magic happens - your code should implement this function.
        Called any time the engine needs an action from your bot.

        Arguments:
        game_state: the GameState object.
        round_state: the RoundState object.
        active: your player's index.

        Returns:
        Your action.
        '''
        legal_actions = round_state.legal_actions()  # the actions you are allowed to take
        #street = round_state.street  # 0, 3, 4, or 5 representing pre-flop, flop, river, or turn respectively
        #my_cards = round_state.hands[active]  # your cards
        #board_cards = round_state.deck[:street]  # the board cards
        #my_pip = round_state.pips[active]  # the number of chips you have contributed to the pot this round of betting
        #opp_pip = round_state.pips[1-active]  # the number of chips your opponent has contributed to the pot this round of betting
        #my_stack = round_state.stacks[active]  # the number of chips you have remaining
        #opp_stack = round_state.stacks[1-active]  # the number of chips your opponent has remaining
        #continue_cost = opp_pip - my_pip  # the number of chips needed to stay in the pot
        #my_contribution = STARTING_STACK - my_stack  # the number of chips you have contributed to the pot
        #opp_contribution = STARTING_STACK - opp_stack  # the number of chips your opponent has contributed to the pot
        #if RaiseAction in legal_actions:
        #    min_raise, max_raise = round_state.raise_bounds()  # the smallest and largest numbers of chips for a legal bet/raise
        #    min_cost = min_raise - my_pip  # the cost of a minimum bet/raise
        #    max_cost = max_raise - my_pip  # the cost of a maximum bet/raise

        def check_fold():
            if CheckAction in legal_actions: return CheckAction()
            return FoldAction()
        
        # STRATEGY: fold-to-win if possible, shove if pair, otherwise check-fold
        if game_state.bankroll > ceil((NUM_ROUNDS-game_state.round_num) * (SMALL_BLIND + BIG_BLIND)/2):
            return check_fold()
        if len(legal_actions) == 1:
            return legal_actions.pop()()
        ev = eval7.evaluate([eval7.Card(s) for s in round_state.hands[active]])
        handtype = ev >> 24
        if handtype >= 1: # pair or higher
            if RaiseAction in legal_actions:
                return RaiseAction(STARTING_STACK)
            elif CallAction in legal_actions:
                return CallAction()
            else:
                soft_assert(CheckAction in legal_actions)
                return CheckAction()
        else:
            return check_fold()
Пример #19
0
    def __init__(self, *items):
        cards = []
        for item in items:
            if isinstance(item, str):
                cards += [Card(item[x:x+2]) for x in range(0, len(item), 2)]
            elif hasattr(item, 'cards'):
                cards += item.cards
            else:
                cards += [item]

        self.cards = list(reversed(sorted(set(cards))))
        self.name  = ''.join([c.name for c in self.cards])
        self.mask  = eval7.evaluate(self.cards)
        super().__init__()
Пример #20
0
def monte_carlo_prob(hole_cards: list,
                     shared_cards: list,
                     remaining_cards: list = [],
                     iters: int = 50) -> float:
    if remaining_cards == []:
        remaining_cards = all_cards_excluding(hole_cards + shared_cards)

    # print(f"Monte Carlo can see {len(shared_cards)} community cards")
    above = 0  # hands that beat ours
    below = 0  # hands that ours beats
    equiv = 0  # hands that are equivalent to ours

    for _ in range(iters):
        drawn_cards = draw_random_cards(remaining_cards, 7 - len(shared_cards))

        # future_shared is the possible
        future_shared = shared_cards + drawn_cards[2:]

        pool = future_shared + hole_cards
        opp_pool = future_shared + drawn_cards[:2]

        hand = eval7.evaluate([eval7.Card(card) for card in pool])
        opp_hand = eval7.evaluate([eval7.Card(card) for card in opp_pool])
        if hand > opp_hand:
            above += 1
        elif hand < opp_hand:
            below += 1
        else:
            equiv += 1

    wins = float(above + (equiv / 2.0))

    assert (above + below + equiv == iters)
    total = float(above + below + equiv)

    return wins / total
Пример #21
0
def create_opp_hand_from_rank_distribution(opp_hand_rank_probas, public_cards, my_hand):
    deck = Deck()
    potential_hands = []

    remaining_cards = list(set(deck.cards) - set(public_cards + my_hand))
    selected_hand_rank = random.choices(['High Card', 'Pair', 'Two Pair', 'Trips', 'Straight', 'Flush', 'Nuts'], weights=opp_hand_rank_probas[0])
    for hand in itertools.combinations(remaining_cards, 2):
        hand_strength = eval7.evaluate(public_cards + list(hand))
        hand_rank = eval7.handtype(hand_strength)
        # print(selected_hand_rank)
        if hand_rank in selected_hand_rank:
            potential_hands.append(hand)
        elif selected_hand_rank == 'Nuts' and hand_rank in ['Quads', 'Full House', 'Straight Flush']:
            potential_hands.append(hand)

    return (remaining_cards[0], remaining_cards[1]) if len(potential_hands) == 0 else random.choice(potential_hands)
Пример #22
0
def handTypes(cards, board):

    hand = [eval7.Card(c) for c in cards + board]
    madeHand = eval7.handtype(eval7.evaluate(hand))

    handRanks, handSuits = zip(*(cards + board))
    handRanks = set(handRanks)
    suitCounts = Counter(handSuits)

    isOESD, isGSSD, isBDSD = straightDraws(handRanks)
    isFD, isBDFD = flushDraws(suitCounts)
    isOvercards = overcards(cards, board)

    draws = set()
    comboDraws = set()

    if isOvercards:
        draws.add('overcards')

    # if made hand is worse than a flush
    if madeHandTypes.index(madeHand) > madeHandTypes.index('Flush'):
        if isFD:
            draws.add('flush draw')
            if madeHand == 'Pair':
                comboDraws.add('FD+Pair')
            if isOESD:
                comboDraws.add('FD+OESD')
            elif isGSSD:
                comboDraws.add('FD+gutshot')
        elif isBDFD:
            if isBDSD:
                comboDraws.add('BDFD+BDSD')

    # if made hand is worse than a straight
    if madeHandTypes.index(madeHand) > madeHandTypes.index('Straight'):
        if isOESD:
            draws.add('OESD')
            if madeHand == 'Pair':
                comboDraws.add('OESD+Pair')
        elif isGSSD:
            draws.add('gutshot')
            if madeHand == 'Pair':
                comboDraws.add('gutshot+Pair')
        elif isBDSD:
            draws.add('BDSD')
            
    return madeHand, draws, comboDraws
Пример #23
0
 def test_evaluate(self):
     cases = (
         (['2c', '3d', '4h', '5s', '7s', '8d', '9c'], 484658, 'High Card'),
         (['2c', '3d', '4h', '4s', '7s', '8d', '9c'], 16938576, 'Pair'),
         (['2c', '3d', '4h', '4s', '7s', '7d', '9c'], 33892096, 'Two Pair'),
         (['2c', '3d', '4h', '7s', '7c', '7d', '9c'], 50688512, 'Trips'),
         (['2c', '3d', '4h', '5s', '7c', '7d', '6c'], 67436544, 'Straight'),
         (['Ac', '3h', '4h', '5s', '2h', 'Jh', 'Kd'], 67305472, 'Straight'),
         (['Ac', '3h', 'Th', '5s', 'Qh', 'Jh', 'Kd'], 67895296, 'Straight'),
         (['2c', '3h', '4h', '5s', 'Jh', '7h', '6h'], 84497441, 'Flush'),
         (['Ac', 'Th', 'Ts', 'Ks', 'Kh', 'Kd'], 101416960, 'Full House'),
         (['Ac', '3h', 'Th', 'Ks', 'Kh', 'Kd', 'Kc'], 118210560, 'Quads'),
         (['3c', '2c', '5c', 'Ac', '4c', 'Kc'], 134414336, 'Straight Flush'),
     )
     for card_strs, expected_val, expected_type in cases:
         cards = tuple(map(eval7.Card, card_strs))
         value = eval7.evaluate(cards)
         handtype = eval7.handtype(value)
         self.assertEqual(value, expected_val)
         self.assertEqual(handtype, expected_type)
Пример #24
0
 def test_evaluate(self):
     cases = (
         (['2c', '3d', '4h', '5s', '7s', '8d', '9c'], 484658, 'High Card'),
         (['2c', '3d', '4h', '4s', '7s', '8d', '9c'], 16938576, 'Pair'),
         (['2c', '3d', '4h', '4s', '7s', '7d', '9c'], 33892096, 'Two Pair'),
         (['2c', '3d', '4h', '7s', '7c', '7d', '9c'], 50688512, 'Trips'),
         (['2c', '3d', '4h', '5s', '7c', '7d', '6c'], 67436544, 'Straight'),
         (['Ac', '3h', '4h', '5s', '2h', 'Jh', 'Kd'], 67305472, 'Straight'),
         (['Ac', '3h', 'Th', '5s', 'Qh', 'Jh', 'Kd'], 67895296, 'Straight'),
         (['2c', '3h', '4h', '5s', 'Jh', '7h', '6h'], 84497441, 'Flush'),
         (['Ac', 'Th', 'Ts', 'Ks', 'Kh', 'Kd'], 101416960, 'Full House'),
         (['Ac', '3h', 'Th', 'Ks', 'Kh', 'Kd', 'Kc'], 118210560, 'Quads'),
         (['3c', '2c', '5c', 'Ac', '4c',
           'Kc'], 134414336, 'Straight Flush'),
     )
     for card_strs, expected_val, expected_type in cases:
         cards = tuple(map(eval7.Card, card_strs))
         value = eval7.evaluate(cards)
         handtype = eval7.handtype(value)
         self.assertEqual(value, expected_val)
         self.assertEqual(handtype, expected_type)
Пример #25
0
 def find_winning_hand(self, winners_hand, deck):
     '''
     returns the hand with highest evaluation score
     '''
     max_score = 0
     max_hand = []
     hand = [eval7.Card(winners_hand[0]), eval7.Card(winners_hand[1])]
     for card1 in deck:
         hand.append(eval7.Card(card1))
         for card2 in deck:
             if card2!=card1:
                 hand.append(eval7.Card(card2))
                 for card3 in deck:
                     if card3!=card1 and card3!=card2:
                         hand.append(eval7.Card(card3))
                         score = eval7.evaluate(hand)
                         if score>max_score:
                             max_score = score
                             max_hand = hand
                         hand.remove(eval7.Card(card3))
                 hand.remove(eval7.Card(card2))
         hand.remove(eval7.Card(card1))
     final_hand = []
     suit_dict = {0:"c", 1: "d", 2:"h", 3: "s"}
     for card in max_hand:
         c = str(card.rank+2)+suit_dict[card.suit]
         if c not in winners_hand:
             if card.rank>=8:
                 if str(card.rank)=="8":
                     c = "T"+suit_dict[card.suit]
                 elif str(card.rank)=="9":
                     c = "J"+suit_dict[card.suit]
                 elif str(card.rank)=="10":
                     c = "Q"+suit_dict[card.suit]
                 elif str(card.rank)=="11":
                     c = "K"+suit_dict[card.suit]
                 elif str(card.rank)=="12":
                     c = "A"+suit_dict[card.suit]
             final_hand.append(c)
     return final_hand  
Пример #26
0
def decide_showdown(table_cards: Iterable[TexasCard], assist=True):
    """
    If table cards have duplicates, the eval7 implementation might go wrong!
    so check for it
    @param table_cards: five to seven cards
    @return:
    """
    if len(set(table_cards)) < len(tuple(table_cards)):
        raise ValueError('Duplicated cards')
    table_cards: List[TexasCard] = TexasCard.sort_desc(table_cards)
    hand = [eval7.Card(c.to_eval7_str()) for c in table_cards]
    int_type = eval7.evaluate(hand)
    str_type = eval7.handtype(int_type)
    best_type = STR_MAP[str_type]

    if assist and best_type == StraightFlush:
        # check with my implementation
        best = detect.decide_showdown(table_cards)
        assert isinstance(best, StraightFlush) or isinstance(best, RoyalFlush)
        if best.__class__ == RoyalFlush:
            best_type = RoyalFlush
    return best_type
Пример #27
0
import eval7
Пример #28
0
    def get_action(self, game_state, round_state, active):
        '''
        Where the magic happens - your code should implement this function.
        Called any time the engine needs an action from your bot.

        Arguments:
        game_state: the GameState object.
        round_state: the RoundState object.
        active: your player's index.

        Returns:
        Your action.
        '''
        legal_actions = round_state.legal_actions(
        )  # the actions you are allowed to take
        #street = round_state.street  # 0, 3, 4, or 5 representing pre-flop, flop, river, or turn respectively
        #my_cards = round_state.hands[active]  # your cards
        #board_cards = round_state.deck[:street]  # the board cards
        my_pip = round_state.pips[
            active]  # the number of chips you have contributed to the pot this round of betting
        opp_pip = round_state.pips[
            1 -
            active]  # the number of chips your opponent has contributed to the pot this round of betting
        my_stack = round_state.stacks[
            active]  # the number of chips you have remaining
        opp_stack = round_state.stacks[
            1 - active]  # the number of chips your opponent has remaining
        #continue_cost = opp_pip - my_pip  # the number of chips needed to stay in the pot
        my_contribution = STARTING_STACK - my_stack  # the number of chips you have contributed to the pot
        opp_contribution = STARTING_STACK - opp_stack  # the number of chips your opponent has contributed to the pot
        #if RaiseAction in legal_actions:
        #    min_raise, max_raise = round_state.raise_bounds()  # the smallest and largest numbers of chips for a legal bet/raise
        #    min_cost = min_raise - my_pip  # the cost of a minimum bet/raise
        #    max_cost = max_raise - my_pip  # the cost of a maximum bet/raise

        # "check" down if already all-in
        if len(legal_actions) == 1:
            return CheckAction()

        # x/f to victory if we can
        if game_state.bankroll > ceil((NUM_ROUNDS - game_state.round_num) *
                                      (SMALL_BLIND + BIG_BLIND) / 2):
            return CheckAction(
            ) if CheckAction in legal_actions else FoldAction()

        # Simple hardcoded / eval7 strategy.
        street = round_state.street
        my_hand = round_state.hands[active]
        board = round_state.deck[:street]

        # reorder cards for consistent key in dict
        my_hand = my_hand[::-1] if CARDS.index(my_hand[0]) < CARDS.index(
            my_hand[1]) else my_hand

        # raise fraction / sizes
        # these are parameters to be tweaked (maybe by stats on opponent)
        if street == 0:
            RAISE_FRACTION = 0.33  # continue with 1/3 of our defends as 3bets
            RAISE_SIZE = 1  # raise (1x)pot
            MDF_FACTOR = 1.05  # slightly looser pre
        else:
            RAISE_FRACTION = 0.15
            RAISE_SIZE = 0.75  # bet 3/4 pot
            MDF_FACTOR = 0.6  # slightly tighter post

        if my_pip == 1 and street == 0:  # open 85% of our button preflop
            raise_range = mdf = bluff_range = 0.85
        else:
            # calculate defend frequency and raise frequency
            if my_pip == 0 and opp_pip == 0:
                raise_range = RAISE_FRACTION
                mdf = RAISE_FRACTION
            else:
                mdf = MDF_FACTOR * 2 * my_contribution / (
                    (opp_pip - my_pip) + 2 * my_contribution)
                raise_range = mdf * RAISE_FRACTION

            bluff_range = mdf * (1 + (RAISE_SIZE) /
                                 (1 + 2 * RAISE_SIZE) * RAISE_FRACTION)

        bluff_range = mdf  ### TEMP: other bots don't seem to fold too much so let's just not bluff for now. let's try changing this later

        # re-sort range based on board texture
        if street > 0 and street != self.sorted_street:
            hand_values = {}

            trans_board = [
                ALL_RANKS[self.value_ranks[c[0]]] + c[1] for c in board
            ]
            new_range = []
            for hand in self.range:
                if not hand[0] in board and not hand[1] in board:
                    trans_hand = [
                        ALL_RANKS[self.value_ranks[c[0]]] + c[1] for c in hand
                    ]
                    value = eval7.evaluate(
                        [eval7.Card(s) for s in trans_hand + trans_board])

                    # don't value straights at all
                    if (value >> 24) == 4:
                        # remove single cards so we only have pair/2p/trips ranking left
                        counts = np.unique(
                            [x[0] for x in trans_hand + trans_board],
                            return_counts=True)
                        duplicates = [
                            counts[0][i] for i in range(len(counts[0]))
                            if counts[1][i] > 1
                        ]

                        # new value based on just duplicate cards
                        value = eval7.evaluate([
                            eval7.Card(s) for s in trans_hand + trans_board
                            if s[0] in duplicates
                        ])

                    hand_values[hand] = value

                    new_range += [hand]

            self.range = sorted(new_range,
                                key=lambda l: hand_values[l],
                                reverse=True)
            self.sorted_street = street

            print('====================')
            print('Ranks:', self.value_ranks)
            print(my_hand, board)
            print([ALL_RANKS[self.value_ranks[c[0]]] + c[1] for c in my_hand],
                  [ALL_RANKS[self.value_ranks[c[0]]] + c[1] for c in board],
                  '(translated)')
            # print('Top 20 hands in range:', [(h, hand_values[h]) for h in self.range[:20]])
            # print('Range: ', self.range)

        # rank current hand in our range
        N = len(self.range)
        hand_position = self.range.index(tuple(my_hand)) / N

        print('Hand %:', hand_position, my_hand,
              [ALL_RANKS[self.value_ranks[c[0]]] + c[1] for c in my_hand],
              self.value_ranks)
        print(raise_range, '(raise)', mdf, '(defend)', bluff_range, '(bluff)')

        # determine whether hand is a raise/call/bluff-raise/check/fold

        # currently commented out range updates; to be "unexploitable" our ranges should be
        # restricted at each decision (otherwise can be overbluffed if we show weakness), but
        # that results in us overvaluing weak hands.
        # e.g. if we check flop, we eliminate all ~pair+ holdings
        #      then on turn if we bet the top 33% of our range, we'll have to start value-betting high card hands
        # to do it properly we need some "slowplay" range to protect our delayed value hands
        if (hand_position < raise_range or mdf < hand_position < bluff_range
            ) and opp_contribution < STARTING_STACK:
            raise_size = min(int(opp_pip + RAISE_SIZE * 2 * opp_contribution),
                             my_pip + my_stack)

            if street == 0:
                self.range = self.range[:ceil(N * raise_range)] + self.range[
                    int(N * mdf):int(ceil(N * bluff_range))]

            print('RAISE:', raise_size)
            return RaiseAction(raise_size)
        elif hand_position < mdf and opp_pip > my_pip:
            if street == 0:
                self.range = (
                    self.range[:int(N * raise_range)] if opp_pip == my_pip +
                    my_stack else
                    []) + self.range[int(N * raise_range):int(ceil(N * mdf))]

            print('CALL')
            return CallAction()
        elif my_pip == opp_pip:
            if street == 0:
                self.range = self.range[int(N * raise_range):int(ceil(
                    N * mdf))] + self.range[int(N * bluff_range):]

            print('CHECK')
            return CheckAction()
        else:
            return FoldAction()
Пример #29
0
    def calc_win_prob_by_sampling_eval7(self, hole_cards, board_cards, data, sim_num):
        """
        Calculate the probability to win current players by sampling unknown cards
        Compute the probability to win one player first
        And then take the power of virtual player count
        """

        o_hole_cards = []
        o_board_cards = []
        deck = eval7.Deck()
        # remove hole cards and board cards from deck
        for card in hole_cards:
            card = eval7.Card(card)
            o_hole_cards.append(card)
            deck.cards.remove(card)
        board_cards_to_draw = 5
        for card in board_cards:
            board_cards_to_draw -= 1
            card = eval7.Card(card)
            o_board_cards.append(card)
            deck.cards.remove(card)
        # vpc_weighted = virtual_player_count_weighted()
        rivals_count = 1  # self.get_rivals_count(data)
        win = 0
        succeeded_sample = 0
        start = time.time()
        # TODO: Remove small rivals
        if board_cards_to_draw:
            n = sim_num
            index = 10
            for iteration in range(n // rivals_count):
                simulate_cards, _ = self.exclude_impossible_rivals_lookup(deck, board_cards_to_draw, rivals_count)
                o_board_sample = o_board_cards + simulate_cards[:board_cards_to_draw]
                my_rank = eval7.evaluate(o_board_sample + o_hole_cards)
                won = True
                for i in range(board_cards_to_draw, board_cards_to_draw + 2 * rivals_count, 2):
                    if my_rank < eval7.evaluate(o_board_sample + simulate_cards[i:i + 2]):
                        won = False
                        break
                if won:
                    win += 1
                succeeded_sample += 1
                if iteration == index:
                    print("==== sampling result ==== win : %d, total : %d, probability : %f, takes: %f seconds" %
                          (win, succeeded_sample, win / succeeded_sample, time.time() - start))
                    index *= 10
        else:
            my_rank = eval7.evaluate(o_board_cards + o_hole_cards)
            n = sim_num
            index = 10
            for iteration in range(n // rivals_count):
                won = True
                simulate_cards, _ = self.exclude_impossible_rivals_lookup(deck, 0, rivals_count)
                # simulate_cards = deck.sample(2 * rivals_count)
                for i in range(0, 2 * rivals_count, 2):
                    if my_rank < eval7.evaluate(o_board_cards + simulate_cards[i:i + 2]):
                        won = False
                        break
                if won:
                    win += 1
                succeeded_sample += 1
                if iteration == index:
                    print("==== sampling result ==== win : %d, total : %d, probability : %f, takes: %f seconds" %
                          (win, succeeded_sample, win / succeeded_sample, time.time() - start))
                    index *= 10
        print("==== sampling result ==== win : %d, total : %d, probability : %f, takes: %f seconds" %
              (win, succeeded_sample, win / succeeded_sample, time.time() - start))
        return win / succeeded_sample
Пример #30
0
def river_action_wrapped(cards,
                         board_cards,
                         opponents,
                         bet,
                         pot,
                         raised=False,
                         first_bet=False,
                         pot_type=2):
    hand = [eval7.Card(s) for s in (cards[:2], cards[2:])]
    board = [
        eval7.Card(s)
        for s in [board_cards[i:i + 2] for i in range(0, len(board_cards), 2)]
    ]
    current_hand = eval7.hand_type(eval7.evaluate(hand + board))

    # if you have nuts, raise or jam
    RFI = "22+, 32s, 53s+, 63s+, 74s+, 84s+, 95s+, T6s+, J6s+, " \
          "Q4s+, K2s+, A2s+, A2o+, K8o+, Q8o+, J8o+, T8o+, 98o+"
    TBet = "ATo+, KJo+, QJo+, 44+, 65s, 76s, 87s, 97s+, T8s+, J9s+, Q9s+, K9s+, A2s+"
    FBet = "TT+, AJs+, KQs, AQo+"
    villain_ranges = {2: RFI, 3: TBet, 4: FBet}
    villain = eval7.HandRange(villain_ranges[pot_type])
    equity = eval7.py_hand_vs_range_monte_carlo(hand, villain, board, 1000)

    if raised:
        if equity > 0.99:
            return "Raise " + str(2.5 * bet)
        elif equity > 0.95:
            return "Call"
        else:
            return "Fold"

    if equity > 0.97:
        if bet > 0:
            return "Raise " + str(2.5 * bet)
        else:
            return "Bet " + str(0.8 * pot)

    # else, look into non-raising methods
    # multi-way pot
    if opponents > 1:
        # someone bet, only call if top pair or better (< 2 rounds of bets)
        if bet > 0:
            if first_bet:
                if current_hand != 'High Card' and not play_the_board(
                        cards, board_cards):
                    if current_hand == 'Pair':
                        if not tpttk(cards, board_cards):
                            return "Fold"
                    return "Call"
            if play_the_board(cards, board_cards):
                return "Fold"
            if current_hand == 'High Card' or current_hand == 'Pair':
                return "Fold"
            elif current_hand == 'Two Pair':
                if paired_card(board_cards) and max(list(
                        board_cards[::2])) >= highest_two_pair(
                            cards, board_cards):
                    return "Fold"
                return "Call"
            else:
                return "Call"

        # no one bet, bet if you have trips or better
        if current_hand not in ['High Card', 'Pair', 'Two Pair'
                                ] and not play_the_board(cards, board_cards):
            return "Bet " + str(pot * 0.8)
        else:
            return "Check"

    # heads up
    else:
        # someone bet, only call if enough equity, above 80%
        if bet > 0:
            if first_bet:
                if equity > bet / (bet + pot):
                    return "Call"
                else:
                    return "Fold"
            elif equity > 0.80:
                return "Call"
            else:
                return "Fold"
        else:
            if equity > 0.80:
                return "Bet " + str(pot * 0.8)
            else:
                return "Check"
Пример #31
0
def betting_round_2_wrapped(cards,
                            board_cards,
                            opponents,
                            bet,
                            pot,
                            preflop_agg=False,
                            position=False,
                            raised=False,
                            pot_type=2):
    hand = [eval7.Card(s) for s in (cards[:2], cards[2:])]
    board = [
        eval7.Card(s)
        for s in [board_cards[i:i + 2] for i in range(0, len(board_cards), 2)]
    ]
    current_hand = eval7.hand_type(eval7.evaluate(hand + board))

    if raised:
        if current_hand in ['High Card', 'Pair', 'Two Pair'] or play_the_board(
                cards, board_cards):
            return "Fold"
        else:
            return "Call"

    # multi-way pot, bluff less
    if opponents > 1:
        # someone bet again, only call if have top pair (if bet < pot) or better
        if bet > 0:
            if play_the_board(cards, board_cards):
                return "Fold"
            if current_hand == 'High Card':
                return "Fold"
            elif current_hand == 'Pair':
                if not tpttk(cards, board_cards):
                    return "Fold"
                else:
                    return "Call"
            elif current_hand == 'Two Pair':
                if paired_card(board_cards):
                    return "Fold"
                return "Call"
            else:
                return "Call"

        # no one bet, bet if you are pre-flop aggressor IP
        if (preflop_agg or position) and current_hand not in ['High Card', 'Pair'] and \
                not play_the_board(cards, board_cards):
            return "Bet " + str(pot * 0.70)
        else:
            return "Check"

    # heads up
    else:
        # since not playing limp pot, pots are either RFI, 3-bet, 4-bet+
        RFI = "22+, 32s, 53s+, 63s+, 74s+, 84s+, 95s+, T6s+, J6s+, " \
              "Q4s+, K2s+, A2s+, A2o+, K8o+, Q8o+, J8o+, T8o+, 98o+"
        TBet = "ATo+, KJo+, QJo+, 44+, 65s, 76s, 87s, 97s+, T8s+, J9s+, Q9s+, K9s+, A2s+"
        FBet = "TT+, AJs+, KQs, AQo+"
        villain_ranges = {2: RFI, 3: TBet, 4: FBet}
        villain = eval7.HandRange(villain_ranges[pot_type])
        equity = eval7.py_hand_vs_range_monte_carlo(hand, villain, board, 1000)

        # someone bet, only call if above 75% equity, since second bullet
        if bet > 0:
            if equity > 0.75:
                return "Call"
            else:
                return "Fold"

        # no one bet, bet if you are pre-flop aggressor and have > 50% equity against range
        if (preflop_agg or position) and equity > 0.5:
            return "Bet " + str(pot * 0.7)
        else:
            return "Check"