예제 #1
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 = list(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.items():
         if not prob == 0.0:
             cards = board + list(hand)
             result = eval7.evaluate(cards)
             hand_type = eval7.handtype(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
예제 #2
0
파일: util.py 프로젝트: zachwdawson/zbot
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
예제 #3
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
예제 #4
0
파일: util.py 프로젝트: zachwdawson/zbot
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)
예제 #5
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
예제 #6
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)
예제 #7
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)
예제 #8
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
예제 #9
0
import eval7
예제 #10
0
    def update(self, state):
        curr_public_cards = state['public_cards']
        prev_public_cards = [] if self.prev_state is None else self.prev_state[
            'public_cards']
        curr_hand = state['hand']
        prev_hand = [] if self.prev_state is None else self.prev_state['hand']
        self.prev_stage = self.stage

        # new hand
        if len(curr_public_cards) < len(
                prev_public_cards) or curr_hand != prev_hand:
            self.stage = 0
            self.prev_stage = 0
            self.opp_num_raises_total = 0
            self.my_num_raises_total = 0
            self.prev_opp_num_raises_total = 0
            self.prev_my_num_raises_total = 0
            self.opp_num_raises_curr_phase = 0
            self.opp_stack_committed_curr_phase = 0
            self.action = None
            self.prev_action = None
            self.my_last_action = None
            self.prev_my_last_action = None
            self.opp_last_action = None
            self.prev_opp_last_action = None
            self.highest_card = None
            self.prev_highest_card = None
            self.num_queens = None
            self.num_kings = None
            self.num_aces = None
            self.hand_rank = None
            self.hand_strength = None
            self.prev_hand_strength = None
            self.winning_prob = None
            self.prev_winning_prob = None
            self.num_outs = None
            self.prev_num_outs = None
            self.hand = state['hand']

            self.prev_dealer = self.dealer
            if 'check' in state['legal_actions'] and sum(
                    state['raise_nums']) == 0:
                self.dealer = True
            elif 'call' in state['legal_actions'] and sum(
                    state['raise_nums']) == 1:
                self.dealer = True
            else:
                self.dealer = False

        # hand
        full_hand = list(map(rlcardtoeval7, curr_hand + curr_public_cards))
        eval7_strength = eval7.evaluate(full_hand)
        self.prev_hand_strength = self.hand_strength
        self.hand_strength = eval7_strength / MAX_EVAL_HS  # scales to between 0 and 1. Needed for P(win)
        self.hand_rank = eval7.handtype(eval7_strength)
        self.prev_num_outs = self.num_outs
        self.num_outs = calc_num_outs(full_hand)
        self.prev_winning_prob = self.winning_prob
        self.winning_prob = calc_win_prob(
            list(map(rlcardtoeval7, curr_public_cards)),
            list(map(rlcardtoeval7, curr_hand)), self.num_outs)

        # stage
        if len(curr_public_cards) == 0:
            self.stage = 0
        elif len(curr_public_cards) == 3:
            self.stage = 1
        elif len(curr_public_cards) == 4:
            self.stage = 2
        else:
            self.stage = 3

        if self.stage > self.prev_stage:
            self.opp_num_raises_curr_phase = 0
            self.opp_stack_committed_curr_phase = 0
            self.my_num_raises_curr_phase = 0
            self.my_stack_committed_curr_phase = 0

        # raises
        new_raises = np.subtract(
            state['raise_nums'],
            [0, 0, 0, 0]) if self.prev_state is None else np.subtract(
                state['raise_nums'], self.prev_state['raise_nums'])
        new_raises = np.sum(new_raises)
        if self.prev_action == 'raise':
            opp_raises = new_raises - 1
        else:
            opp_raises = new_raises
        if self.opp_last_action == 'raise':
            my_raises = new_raises - 1
        else:
            my_raises = new_raises

        self.prev_opp_num_raises_total = self.opp_num_raises_total
        self.prev_my_num_raises_total = self.my_num_raises_total
        self.opp_num_raises_total = self.opp_num_raises_total + opp_raises
        self.my_num_raises_total = self.my_num_raises_total + my_raises
        self.my_num_raises_curr_phase = self.my_num_raises_curr_phase + my_raises
        self.my_stack_committed_curr_phase = self.my_stack_committed_curr_phase + 1 \
            if (my_raises == 0 and action_to_num(self.action)) == 1 else 0
        self.opp_num_raises_curr_phase = self.opp_num_raises_curr_phase + opp_raises
        self.opp_stack_committed_curr_phase = self.opp_stack_committed_curr_phase + opp_raises
        self.opp_stack_committed_curr_phase = self.opp_stack_committed_curr_phase + 1 \
            if (opp_raises == 0 and self.dealer and self.my_last_action == 'raise') else 0

        # Action
        self.prev_opp_last_action = self.opp_last_action
        self.opp_last_action = 2 if opp_raises > 0 else 1
        self.prev_action = self.opp_last_action
        self.my_last_action = self.action

        # Board Info
        num_aces, num_kings, num_queens = 0, 0, 0
        eval7_cards = list(map(rlcardtoeval7, curr_public_cards))
        highest_card = eval7_cards[0] if len(curr_public_cards) > 0 else None
        for card in eval7_cards:

            if card > highest_card:
                highest_card = card

            if 'A' in str(card):
                num_aces += 1
            elif 'K' in str(card):
                num_kings += 1
            elif 'Q' in str(card):
                num_queens += 1
        self.prev_highest_card = self.highest_card
        self.highest_card = None if highest_card is None else highest_card.rank
        self.num_queens = num_queens
        self.num_kings = num_kings
        self.prev_num_aces = self.num_aces
        self.num_aces = num_aces