Which is better probability-wise two pair or pocket pair two pairs

121 Views Asked by At

In Texas holdem on the flop is it better for someone to have two pairs where the pair is a pocket pair combined with a pair on the flop, or is it better to have a two pair where the two hole cards match with two cards on the flop? I mean specifically, what are the chances of him being beaten by another player making a two pair or the probability of him making another two pair based on how the board is.

So I'm comparing for example this:

Hole cards: TsTc
Flop cards: 5c5hKd
Hand: TsTc5c5h - two pair

With this:

Hole cards: Ts5c
Flop cards: Tc5hKd
Hand: TsTc5c5h - two pair

I could ask on the poker stackexchange but I figured you mathematicians would come up with a more accurate answer. If my question is not clear, please let me know so I can edit it.

1

There are 1 best solutions below

7
On BEST ANSWER

Given your hole cards and the flop, there are $$\binom{47}{2,2,43} = \frac{47!}{2!\; 2! \; 43!} = 1,070,190$$ possible continuations of the game with two more community cards and two cards for your opponent's hole cards. By exhaustive enumeration, also known as brute force, the number of continuations in which you win in the first scenario is $771,110$ and the number in the second scenario is $935,385$. (I used a Python program.)

So your probability of winning in the first scenario is $771,110 / 1,070,190 = 0.729536$ and in the second scenario is $935,385 / 1,070,190 = 0.874036$.

EDIT

By request, here is the Python program used in the solution. Most of the code was copied from an example presented in a Udacity course, CS212, "Design of Computer Programs" taught by Peter Norvig. The heart of the CS212 code is the function hand_rank, which returns an object representing the rank of a five card poker hand. The representation of the rank is elegant and ingenious: an integer representing the class of hand (one pair, flush, etc.) followed by a list which serves to rank hands of the same class. The code runs under Python 2.7.

# Compare two scenarios in Texas hold-em by brute-force enumeration.

import itertools

def wins(hole, flop):
    """Try all possible outcomes of hold-em with given hole and flop cards, 
    return number of wins."""
    # First construct the complete 52-card deck.
    deck = [r+s for r in '23456789TJQKA' for s in 'SHDC']
    # Remove the given hole and flop cards from the deck.
    for x in hole+flop:
        deck.remove(x)
    nwins = 0
    # Itertools does not provide a convenient method to extract two sets
    # of two cards each from the deck.  So we draw four cards and break
    # the four cards into two sets of two, which can be done in six ways.
    for (a,b,c,d) in itertools.combinations(deck, 4):
        for (x,y) in [[[a,b],[c,d]], 
                      [[a,c],[b,d]], 
                      [[a,d],[b,c]],
                      [[b,c],[a,d]],
                      [[b,d],[a,c]],
                      [[c,d],[a,b]]]:
            common = flop + x  # 5 common cards
            ophole = y         # opponent's hole cards
            mybest = best_hand(common + hole)
            opbest = best_hand(common + ophole)
            if hand_rank(mybest) > hand_rank(opbest):
                nwins += 1
    return nwins

# Code from Udacity CS212, "Design of Computer Programs", starts here

def best_hand(hand):
    "From a 7-card hand, return the best 5 card hand."
    return max(itertools.combinations(hand,5), key=hand_rank)

def hand_rank(hand):
    "Return a value indicating the ranking of a hand."
    ranks = card_ranks(hand) 
    if straight(ranks) and flush(hand):
        return (8, max(ranks))
    elif kind(4, ranks):
        return (7, kind(4, ranks), kind(1, ranks))
    elif kind(3, ranks) and kind(2, ranks):
        return (6, kind(3, ranks), kind(2, ranks))
    elif flush(hand):
        return (5, ranks)
    elif straight(ranks):
        return (4, max(ranks))
    elif kind(3, ranks):
        return (3, kind(3, ranks), ranks)
    elif two_pair(ranks):
        return (2, two_pair(ranks), ranks)
    elif kind(2, ranks):
        return (1, kind(2, ranks), ranks)
    else:
        return (0, ranks)

def card_ranks(hand):
    "Return a list of the ranks, sorted with higher first."
    ranks = ['--23456789TJQKA'.index(r) for r, s in hand]
    ranks.sort(reverse = True)
    return [5, 4, 3, 2, 1] if (ranks == [14, 5, 4, 3, 2]) else ranks

def flush(hand):
    "Return True if all the cards have the same suit."
    suits = [s for r,s in hand]
    return len(set(suits)) == 1

def straight(ranks):
    """Return True if the ordered 
    ranks form a 5-card straight."""
    return (max(ranks)-min(ranks) == 4) and len(set(ranks)) == 5

def kind(n, ranks):
    """Return the first rank that this hand has 
    exactly n-of-a-kind of. Return None if there 
    is no n-of-a-kind in the hand."""
    for r in ranks:
        if ranks.count(r) == n: return r
    return None

def two_pair(ranks):
    """If there are two pair here, return the two 
    ranks of the two pairs, else None."""
    pair = kind(2, ranks)
    lowpair = kind(2, list(reversed(ranks)))
    if pair and lowpair != pair:
        return (pair, lowpair)
    else:
        return None 

# End of code from CS212

print wins('TS TC'.split(), '5C 5H KD'.split()) # scenario 1
print wins('TS 5C'.split(), 'TC 5H KD'.split()) # scenario 2