Poker Simulation.

You’ve now done several exercises calculating the probability of getting various hands in poker. We’re now going to use the computer to check some of these computations. We’ll also estimate some more difficult problems computationally.

Cards.

Our first Mathematica problem is going to be generating cards and hands automatically. We can represent a card as a list with two elements, the suit and the value. We’ll use numbers to represent the suits:

1 = Hearts
2 = Diamonds
3 = Clubs
4 = Spades

It’s going to be convenient to play “Aces high”, and also to represent the face cards by numerical values, so the cards will have values from 2-14 with

11 = Jack
12 = Queen
13 = King
14 = Ace

We can then represent the deck as the set of pairs where one element is chosen from {1,..,4} and the other from {2,...,14}. In Mathematica, we can do this with the Tuples command. The Tuples command inputs a list of lists and outputs all the “Tuples” with one element from each list. For instance, to make a list of all possible Fiesta dinnerware of various types and colors:

Tuples[{{"Plate","Bowl","Saucer","Mug"},{"Blue","Red","Orange"}}]

Making the deck is then pretty simple:

Deck = Tuples[{{1,2,3,4},{2,3,4,5,6,7,8,9,10,11,12,13,14}}]

Length[Deck]

Generating Hands.

We can generate hands by taking a random assortment of 5 cards from the Deck.

Hand = RandomSample[Deck,5]

Poker Code. (Reading this is optional.)

We now need to score poker hands. To do so, we’ll introduce two more pieces of Mathematica. We can refer to elements of a list by number with [[ ]].

Hand[[3]]

To refer to elements in “nested” lists, we just add more indices:

Hand[[3,2]]

We can replace indices with “All”. If we want to see the list of suits, for instance, we use

CardSuits[Hand_] := Hand[[All,1]]

CardSuits[Hand]

If we want to see the list of values, we use

CardValues[Hand_] := Hand[[All,2]]

Now we can start scoring hands. Just to have a test or two, let’s try a lucky player who has a full house: 7’s in Hearts and Diamonds (suits 1 and 2) and Jacks in Hearts, Clubs, and Spades:

FullHouseHand = {{1,7},{2,7},{3,11},{4,11},{1,11}}

StraightHand = {{2,5},{3,9},{1,6},{3,7},{4,8}}

StraightHand2 = {{2,10},{2,13},{1,12},{3,11},{4,9}}

JackHighHand = {{1,7},{2,3},{3,5},{4,11},{1,9}}

PairOfKingsHand = {{2,13},{4,13},{2,5},{3,7},{3,6}}

PairOfKingsHand2 = {{1,13},{3,13},{1,11},{4,4},{2,9}}

QueensAndFives = {{2,11},{2,5},{3,5},{4,12},{3,12}}

High card.

HighCard[Hand_] := {"HighCard",Max[CardValues[Hand]]};

HighCard[FullHouseHand]

We also need some code which decides which of a collection of high card hands is the winner (or if there’s a tie). In this case, the value of the hand is decided by the value of the high card. Unfortunately, this requires some intermediate-level Mathematica, so please just take this on faith:

HighCardWinner[hands_] := {Last[Keys[#]],Flatten[(Position[hands,#]& /@#[Last[Keys[#]]]),2]}&@KeySortBy[GroupBy[hands,HighCard[#]&],Last]

It gives the winning hand type, and the player (or players) who win (or tie) for the best high card hand:

HighCardWinner[{StraightHand,FullHouseHand,JackHighHand}]

HighCardWinner[{StraightHand,JackHighHand}]

Pair.

To look for pairs, we can get a list of every two-element subset of our cards with “Subsets[Hand,{2}]”. We’ll then to select the subsets with the same value (these are the pairs). The way to do this is to write a test function which returns “True” if the values of two cards are equal and “False” otherwise:

PairQ[Cards_] := TrueQ[Cards[[1,2]] == Cards[[2,2]]];

We can test various suit-value pairs:

PairQ[{{1,11},{2,9}}]

PairQ[{{2,3},{3,3}}]

Now we can find ALL the pairs:

Pairs[Hand_] := Tuples[{{"Pair"},Select[Subsets[Hand,{2}],PairQ]}]

Pairs[FullHouseHand]

Notice that all two element subsets of the three Jacks are listed as pairs. This is correct.

PairHandQ[Hand_] := (#[[1,2]]>1)&@(Reverse@SortBy[Tally[CardValues[Hand]],Last]);

As before, when more than one player holds a pair, the winner (or winners) are decided by the value of the pair. This can be extracted with the following, that gives the winning hand and the player or players who win, given a list of hands which contain:

BestPair[Hand_] := ({#[[1]],#[[2,1,2]]}&)@(First@MaximalBy[Pairs[Hand],#[[2,1,2]]&])

PairWinner[hands_] := {Last[Keys[#]],Flatten[(Position[hands,#]& /@#[Last[Keys[#]]]),2]}&@KeySort[GroupBy[hands,BestPair]]

PairWinner[{PairOfKingsHand,FullHouseHand,PairOfKingsHand2}]

Two pair.

Finding two pair hands is pretty much the same. If “Cards” is a list of two lists (of two cards each), we just check to see whether each is a pair and use the logical “and” esc-and-esc to see if both are pairs:

TwoPairQ[Cards_] := TrueQ[PairQ[Cards[[1]]] ∧ PairQ[Cards[[2]]]]

Now we need to generate all pairs of disjoint 2 element subsets of our hand, and check them with TwoPairQ. This requires some Mathematica magic that’s beyond our current level, so I’ll just write it:

TwoPairs[Hand_] := Tuples[{{"TwoPair"},
Select[
Select[
Subsets[Subsets[Hand,{2}],{2}], (* All pairs of two element subsets *)
DisjointQ[#[[1]],#[[2]]]&],
TwoPairQ]}
]

We can check that it works:

TwoPairs[QueensAndFives]

If we just want to know whether there are two pairs and don’t really care about extracting them, this is faster, though more obscure:

TwoPairHandQ[Hand_] := (#[[1,2]]==4 ∨ #[[2,2]]>1)&@(Reverse@SortBy[Tally[CardValues[Hand]],Last]);

Figuring out the winner when two or more players have two pair requires us to compare the highest value pair and then the secondary pair. So we first have to figure out those for each hand, then compare them

BestPairs[Hand_] := {"TwoPair",First[ReverseSort@(ReverseSort[{#[[2,1,2,2]],#[[2,2,2,2]]}]& /@ TwoPairs[Hand])]}

BestPairs[FullHouseHand]

BestPairs[QueensAndFives]

TwoPairWinner[hands_] := {Last[Keys[#]],Flatten[(Position[hands,#]& /@#[Last[Keys[#]]]),2]}&@KeySort[GroupBy[hands,BestPairs]]

TwoPairWinner[{FullHouseHand,QueensAndFives}]

Three of a kind.

Three of a kind is easier to check, because we just look at three element subsets for triples of cards with the same value:

ThreeOfAKindQ[Cards_] := TrueQ[Cards[[1,2]] == Cards[[2,2]] == Cards[[3,2]]]

ThreeOfAKind[Hand_] := Tuples[{{"ThreeOfAKind"},Select[Subsets[Hand,{3}],ThreeOfAKindQ]}]

ThreeOfAKind[FullHouseHand]

ThreeOfAKindHandQ[Hand_] :=(Reverse@SortBy[Tally[CardValues[Hand]],Last])[[1,2]]≥3;

This actually gets easier because there’s only one way to be a three of a kind hand (and you can’t tie with another player). So we can simplify things:

BestThreeOfAKind[hand_] := {"ThreeOfAKind",ThreeOfAKind[hand][[1,2,1,2]]}

ThreeOfAKindWinner[hands_] := {Last[Keys[#]],Flatten[(Position[hands,#]& /@#[Last[Keys[#]]]),2]}&@KeySort[GroupBy[hands,BestThreeOfAKind]]

ThreeOfAKindWinner[{FullHouseHand}]

Straight.

To check whether we have a straight, we just need to check whether the values are all different and the maximum is 4 more than the minimum. Here we recall the If statement. As a sort of grace note, when we return a straight, we use SortBy[Hand,Last] to sort the hand by card values. This is certainly optional.

StraightQ[Cards_] := TrueQ[DuplicateFreeQ[CardValues[Cards]] ∧ (Max[CardValues[Cards]] - Min[CardValues[Cards]] == 4)]

Straight[Hand_] := Tuples[{{"Straight"},SortBy[#,Last]& /@Select[Subsets[Hand,{5}],StraightQ]}]

Straight[FullHouseHand]

Straight[StraightHand2]

StraightHandQ[Hand_] := TrueQ[Length[Straight[Hand]]>0]

To compare two straights, again we just compare values of the high card in the straight. That’s relatively easy:

BestStraight[hand_] := {"Straight",Straight[hand][[1,2,5,2]]}

StraightWinner[hands_] := {Last[Keys[#]],Flatten[(Position[hands,#]& /@#[Last[Keys[#]]]),2]}&@KeySort[GroupBy[hands,BestStraight]]

StraightWinner[{StraightHand,StraightHand2}]

Flush.

To check whether we have a flush, we just check whether all of the cards have the same suit. That’s easy.

FlushQ[Cards_] := TrueQ[Cards[[1,1]]==Cards[[2,1]]==Cards[[3,1]] == Cards[[4,1]] == Cards[[5,1]]]

Flush[Hand_] := Tuples[{{"Flush"},SortBy[#,Last]& /@Select[Subsets[Hand,{5}],FlushQ]}]

FlushHandQ[Hand_] := FlushQ[Hand]

To compare a pair of flushes to see who wins, we simply compare the card values in the flush in lexicographic order. Since they are already sorted by value,

FlushWinner[hands_] := {Last[Keys[#]],Flatten[(Position[hands,#]& /@#[Last[Keys[#]]]),2]}&@KeySort[GroupBy[hands,Flush]]

Now we write down a little code for generating random hands which are all flushes:

Outer[List,{RandomChoice[Range[4]]},RandomSample[Range[2,14],5]][[1]]

Using it, we can generate some test hands:

FlushHand = {{1,9},{1,2},{1,5},{1,13},{1,10}};

FlushHand2 = {{2,5},{2,12},{2,9},{2,2},{2,14}};

FlushHand3 = {{2,5},{2,12},{2,13},{2,2},{2,14}};

And verify that FlushWinner works as expected

FlushWinner[{FlushHand,FlushHand2,FlushHand3}]

Full House.

Checking for a full house requires us to divide the hand into 3-and-2 subsets and look for three-of-a-kind and pair.

FullHouseQ[Cards_] := TrueQ[Cards[[1,1,2]]==Cards[[1,2,2]]==Cards[[1,3,2]] ∧ Cards[[2,1,2]]==Cards[[2,2,2]]]

To divide the hand, we can use Complement. Again, this involves some Mathematica magic that’s above our current level (the “pure function”  {#,Complement[Hand,#]}& ), so we just write it down:

FullHouse[Hand_] := Tuples[{{"FullHouse"},Select[{#,Complement[Hand,#]}& /@ Subsets[Hand,{3}],FullHouseQ]}]

FullHouse[FullHouseHand]

FullHouseHandQ[Hand_] := (#[[1,2]]==3 ∧#[[2,2]]==2)&@(Reverse@SortBy[Tally[CardValues[Hand]],Last]);

FullHouseHandQ[FullHouseHand]

Now we need to compare Full House hands. These are scored lexicographically by the value of the triple, then the value of the pair. So we need to write

BestFullHouse[hand_] := {"FullHouse",{#[[1,2,1,1,2]],#[[1,2,2,1,2]]}}&@FullHouse[hand]

BestFullHouse[FullHouseHand]

FullHouseWinner[hands_] := {Last[Keys[#]],Flatten[(Position[hands,#]& /@#[Last[Keys[#]]]),2]}&@KeySort[GroupBy[hands,BestFullHouse]]

For testing, we’ll generate some random full house hands:

Transpose[{RandomChoice[Range[4],5],RandomSample[Join[ConstantArray[RandomChoice[Range[2,14]],3],ConstantArray[RandomChoice[Range[2,14]],2]],5]}]

FullHouseHand2 = {{2,10},{3,3},{1,10},{4,10},{2,3}};

FullHouseHand3 = {{3,12},{4,7},{2,7},{1,7},{1,12}};

And verify that FullHouseWinner works as expected:

FullHouseWinner[{FullHouseHand,FullHouseHand2,FullHouseHand3}]

Four of a kind.

Four of a kind is much easier to check for, since we just check all the four element subsets.

FourOfAKindQ[Cards_] := TrueQ[Cards[[1,2]]==Cards[[2,2]]==Cards[[3,2]]==Cards[[4,2]]]

FourOfAKind[Hand_] := Tuples[{{"FourOfAKind"},Select[Subsets[Hand,{4}],FourOfAKindQ]}]

FourOfAKind[FullHouseHand]

FourOfAKind[StraightHand]

FourOfAKindHandQ[Hand_] := (#[[1,2]]==4)&@(Reverse@SortBy[Tally[CardValues[Hand]],Last]);

To score winners, we just use the value of the card which we have four of:

BestFourOfAKind[hand_] := {"FourOfAKind",#[[1,2,1,2]]}&@FourOfAKind[hand]

FourOfAKindWinner[hands_] := {Last[Keys[#]],Flatten[(Position[hands,#]& /@#[Last[Keys[#]]]),2]}&@KeySort[GroupBy[hands,BestFourOfAKind]]

Now we generate some four of a kind hands for testing:

RandomSample[{{1,#[[1,2]]},{2,#[[1,2]]},{3,#[[1,2]]},{4,#[[1,2]]},#[[2]]}&@RandomSample[Deck,2],5]

FourOfAKindHand = {{2,4},{1,4},{3,4},{4,4},{3,11}};

FourOfAKindHand2 = {{4,3},{3,3},{3,6},{1,3},{2,3}};

FourOfAKindHand3 = {{1,8},{3,11},{4,11},{1,11},{2,11}};

FourOfAKindWinner[{FourOfAKindHand,FourOfAKindHand2,FourOfAKindHand3}]

Straight flush.

This is easy, because we simply reuse the StraightQ and FlushQ tests we already wrote.

StraightFlushQ[Cards_] := TrueQ[StraightQ[Cards] ∧ FlushQ[Cards]]

StraightFlush[Hand_] := Tuples[{{"StraightFlush"},Select[Subsets[Hand,{5}],StraightFlushQ]}]

StraightFlushHandQ[Hand_] := TrueQ[Length[StraightFlush[Hand]]>0]

BestStraightFlush[hand_] := {"StraightFlush",StraightFlush[hand][[1,2,5,2]]}

We can compare winners with the old StraightWinner code:

StraightFlushWinner[hands_] := {Last[Keys[#]],Flatten[(Position[hands,#]& /@#[Last[Keys[#]]]),2]}&@KeySort[GroupBy[hands,BestStraightFlush]]

Again, we generate some straight flushes for testing:

RandomSample[{{#[[1]],#[[2]]},{#[[1]],#[[2]]+1},{#[[1]],#[[2]]+2},{#[[1]],#[[2]]+3},{#[[1]],#[[2]]+4}}&@{RandomChoice[Range[4]],RandomChoice[Range[2,10]]},5]

StraightFlushHand = {{1,12},{1,13},{1,10},{1,11},{1,9}};
StraightFlushHand2 = {{4,3},{4,5},{4,4},{4,6},{4,7}};
StraightFlushHand3 = {{4,9},{4,11},{4,13},{4,10},{4,12}};

StraightFlushWinner[{StraightFlushHand,StraightFlushHand2,StraightFlushHand3}]

HandType[hand_] := 
If[StraightFlushHandQ[hand],StraightFlush[hand][[1]],
If[FourOfAKindHandQ[hand],FourOfAKind[hand][[1]],
If[FullHouseHandQ[hand],FullHouse[hand][[1]],
If[FlushHandQ[hand],Flush[hand][[1]],
If[StraightHandQ[hand],Straight[hand][[1]],
If[ThreeOfAKindHandQ[hand],ThreeOfAKind[hand][[1]],
If[TwoPairHandQ[hand],TwoPairs[hand][[1]],
If[PairHandQ[hand],Pairs[hand][[1]],
HighCard[hand]]]]]]]]];

HandRank[hand_] :=HandType[hand][[1]]

HandRankNumber[type_] := type /. {"HighCard"->0,"Pair" -> 1,"TwoPair"->2 ,"ThreeOfAKind"->3,"Straight"->4,"Flush"->5,"FullHouse"->6,"FourOfAKind"->7,"StraightFlush"->8}

WinningHand[hands_] := Block[{byType,bestRankHands,winningHands},
byType=KeySortBy[GroupBy[hands, HandRank],HandRankNumber];
bestRankHands = {#,byType[#]}& @ Last[Keys[byType]];
winningHands = If[bestRankHands[[1]]=="HighCard",HighCardWinner[bestRankHands[[2]]],
If[bestRankHands[[1]]=="Pair",PairWinner[bestRankHands[[2]]],
If[bestRankHands[[1]]=="TwoPair",TwoPairWinner[bestRankHands[[2]]],
If[bestRankHands[[1]]=="ThreeOfAKind",ThreeOfAKindWinner[bestRankHands[[2]]],
If[bestRankHands[[1]]=="Straight",StraightWinner[bestRankHands[[2]]],
If[bestRankHands[[1]]=="Flush",FlushWinner[bestRankHands[[2]]],
If[bestRankHands[[1]]=="FullHouse",FullHouseWinner[bestRankHands[[2]]],
If[bestRankHands[[1]] == "FourOfAKind",FourOfAKindWinner[bestRankHands[[2]]],
If[bestRankHands[[1]]=="StraightFlush",StraightFlushWinner[bestRankHands[[2]]]
]]]]]]]]];
{DeleteDuplicates[Flatten[Position[hands,#]&/@bestRankHands[[2,DeleteDuplicates[winningHands[[2]]]]]]],winningHands[[1]]}
]

Counting Hands.

After a lot of background work, we’ve defined functions called

PairHandQ
TwoPairHandQ
ThreeOfAKindHandQ
StraightHandQ
FlushHandQ
FullHouseHandQ
FourOfAKindHandQ
StraightFlushHandQ

You can now check the “naive” counts of different types of hands which you worked out before.

CountsBy[Subsets[Deck,{5}],PairHandQ]

CountsBy[Subsets[Deck,{5}],TwoPairHandQ]

CountsBy[Subsets[Deck,{5}],ThreeOfAKindHandQ]

CountsBy[Subsets[Deck,{5}],StraightHandQ]

CountsBy[Subsets[Deck,{5}],FlushHandQ]

CountsBy[Subsets[Deck,{5}],FullHouseHandQ]

CountsBy[Subsets[Deck,{5}],FourOfAKindHandQ]

CountsBy[Subsets[Deck,{5}],StraightFlushHandQ]

Work for your group.

Prove by hand that our counts above are correct. Use Mathematica to evaluate any products, binomial coefficients, etc that you like, but don’t directly enumerate anything.

Ranking Hands

By the rules of poker, if a hand has several simultaneous types (think of the full house, which is also three of a kind, two pair, and a pair), it is considered to be a hand of the best type it contains in the (best to worst) ordering

StraightFlush
FourOfAKind
FullHouse
Flush
Straight
ThreeOfAKind
TwoPairs
Pair
HighCard

Definition. The best type of a poker hand will be called the rank of the hand, and we will say that the hand is ranked as its best type.

Example. The hand {{1,5},{4,5},{2,5},{2,7},{4,7}} contains three 5’s and a pair of 7’s. The hand is simultaneously a hand with: high card 7, a pair of 7’s, a pair of 5’s, two pair (7’s over 5’s), three of a kind (7’s) and a full house (5’s over 7’s). Since the full house is the best of these classifications, we say this hand is ranked as a full house (5’s over 7’s).

The poker code above contains a function called HandRank which returns the rank of a given hand.

HandRank[{{1,5},{4,5},{2,5},{2,7},{4,7}}]

We can now get a better classification of the poker hands by counting hands ranked in different ways according to the rules:

Tally[HandRank /@ Subsets[Deck,{5}]]

The real question: Bet or Fold?

So the real question one needs to answer in poker is “How likely is it that my hand is the winning hand?”. Unfortunately, this question is firmly out of reach of the kind of brute force methods that we’ve seen so far. While the number of single hands is

Binomial[52,5]

the number of pairs of hands is

2Binomial[52,10]

and the number of possible deals for a four-player game is

4!Binomial[52,20]

although you might reduce it to

4Binomial[52,20]

if you make the observation that you don’t really care which of your three opponents has a better hand than you. That’s still far too big to write down all the possibilities! However, we can estimate the likelihood that a given hand is the winning hand if we can do two things: figure out which of several hands is the winner and then sample lots of other hands.

Finding out who won

The rules of poker are that any hand beats a hand with lower rank and loses to a hand with higher rank. If the ranks of two hands are the same, the hands are compared in a fairly complicated way (for instance, two full house hands are compared by the values of the three of a kind cards, then the values of the pair cards, and they tie if both values are the same).

All of these rules have been encoded in the function “WinningHand”, which takes a list of hands (in order by player) and returns a list showing which player(s) won and with what type of hand.

WinningHand[{StraightHand,FullHouseHand,{{3,5},{2,4},{1,7},{4,7},{4,11}},StraightFlushHand,StraightFlushHand2}]

This tells us that in the example, player 4 won with a straight flush, 9 high.

Work for your group

Generating possibilities for everyone else’s hand.

If we are given a hand of 5 cards, we know that these cards are in nobody else’s hand. Therefore, the other players are choosing their cards from the complement of our hand. Write a function called 

OtherHands[myHand_, numOtherPlayers_] 

which returns a list of “numOtherPlayers” 5-card hands chosen from the cards that remain after the cards in “myHand” are removed from the deck.

Hint: The RandomSample and Complement functions will help. You’ll also want to use Here we introduce a new function, Partition, which splits a list into sublists of a specified length-- for instance:

fruit = {"apple","orange","kiwi","guava"}

Partition[fruit,2]

Determining if your hand won.

Write a function 

	RandomWinner[myHand_,numOtherPlayers_] 

which uses the WinningHand function to determine whether your hand won (with the other players’ hands assigned randomly using your OtherHands function).

Remember that the first element of the output of WinningHand is a “winner’s circle” list of player numbers. We want to see if player number 1 (us!) is in this list. We can do this with MemberQ[list,element] which tells us whether “element” is a member of “list”.

MemberQ[fruit,"orange"]

MemberQ[fruit,"watermelon"]

Since the WinningHand function expects a list of hands, you’ll have to add “myHand” to the list of random hands produced by “OtherHands” before using WinningHand. 

You might want to look up the Prepend function, which is used like this:

Prepend[fruit,"watermelon"]

Estimating your win probability experimentally.

You’d like to know the probability that your hand will win with a given number of other players. Now that you have the RandomWinner function, use it to write a function called 

	ExperimentalWinProbability[myHand_,numOtherPlayers_] 

which counts the number of times that your hand was among the winners in a (reasonable) number of trials of “RandomWinner” and divides by the number of trials. Since each call of RandomWinner is independent of all the others, these are Bernoulli trials with success probability p equal to your win  probability.

Example: According to my computations, the hand

PairOfAcesHand = {{3,13},{2,12},{1,14},{2,14},{4,11}};

is among the winners in a four-player game about 80% of the time. Make sure that you get a comparable answer.

Work for your group.

Class poker! When you are ready to estimate probabilities, you’re ready to play poker against the other groups in class.

Applied Poker Questions.

We are now going to explore some applied probability questions regarding poker.

Several probability students have an argument about the following question: “My hand contains a pair. What is the probability that I will win the pot in a four player game?”

Student A’s argument.

Suppose the event (Subscript[A, i]) is “I lose to player i”.  My hand will lose if player i’s hand contains two pairs, three of a kind, a straight, a flush, a full house, or a straight flush. So

	P((Subscript[A, i])) = (#hands containing two pairs + #hands containing three of a kind + ... + #hands containing straight flush)/(# of hands)

Then we can compute 

	P(“I win) = 1 - P(“I lose to any other player”) = 1 - P((Subscript[A, 1])⋃ (Subscript[A, 2])⋃ (Subscript[A, 3]))

which can be computed via the inclusion-exclusion formula. Since the other players are different from each other, the events (Subscript[A, 1]), (Subscript[A, 2]), and (Subscript[A, 3]) are independent. Thus P((Subscript[A, i])⋂(Subscript[A, j])) = P((Subscript[A, i])) P((Subscript[A, j])), and P((Subscript[A, i])⋂ (Subscript[A, j])⋂(Subscript[A, k])) = P((Subscript[A, i]))P((Subscript[A, j]))P((Subscript[A, k])).

Work for your group.

Compute the probability P("I win") according to Student A’s argument. Then critique Student A’s argument. Is this the correct computation? If not, what’s wrong with the argument?

Student B’s argument.

Suppose the event (Subscript[B, i]) is “My hand beats player i’s hand”. My pairs will beat any hand that’s ranked as a high card hand. Therefore

P((Subscript[B, i])) = ”probability that player i’s hand is ranked as high card” 
                      =  (# hands ranked as high card)/(# total number of hands)

The probability that I win the pot is 

	P((Subscript[B, 1])⋂ (Subscript[B, 2])⋂ (Subscript[B, 3])) = P((Subscript[B, 1]))P((Subscript[B, 2]))P((Subscript[B, 3]))

because the other players are different from one another so the events (Subscript[B, i]) are independent events.

Work for your group.

Compute the probability P("I win") according to Student B’s argument. Then critique Student B’s argument. Is this the correct computation? If not, what’s wrong with the argument? Do Student A and Student B compute the same probability?

Student C’s argument.

Both of you are forgetting that another player might also have a pair! If player i and j both hold pairs, then i wins against another pair if the value of their paired cards is higher. This is clearly symmetric in i and j, so the probability that i wins is 0.5. Therefore, if (Subscript[C, i]) is the event “my hand beats Player i’s hand”, then 

 	P((Subscript[C, i])) = P("i's hand is ranked as high card") + 0.5 P("i's hand is ranked as pair")
 	
Just like student B said, the probability that I win the pot is

P((Subscript[C, 1])⋂ (Subscript[C, 2])⋂ (Subscript[C, 3])) = P((Subscript[C, 1]))P((Subscript[C, 2]))P((Subscript[C, 3]))

because the other players are different from one another so the events (Subscript[C, i]) are independent events.

Work for your group.

Compute the probability P("I win") according to Student C’s argument. Then critique Student C’s argument. Is this the correct computation? If not, what’s wrong with the argument? Do Students A, B, and C compute the same probability?

Student E’s argument.

I don’t entirely trust any of your arguments. I’m not exactly sure what’s wrong with them, but I know enough to know what I don’t know. The only way to solve this problem is to do a computer experiment where we pick a random hand with a pair, then 3 more random hands and see who wins. 

If we conduct enough trials of this experiment, we can come up with a small credible interval for the win probability p using the fact that these are Bernoulli trials. That’s good enough for me, and it will tell us  which of you is right.

Work for your group.

Since Student E refuses to give an argument at all, you can’t really critique it. So perform Student E’s experiment and find a 95% credible interval for the probability that a random pair wins. Finally, decide which of students A-D were closest to the truth.

True or False: There are “irrelevant” cards in your hand.

3. True or false: A poker hand contains a pair of kings (and is ranked as a pair-- it is not a full house or three or four of a kind). The chance that this hand wins a four player game does not depend on the other three cards in the hand. 

Prove your answer either by writing a formal proof or doing a computer experiment which shows that the probability that the win probabilities for two different “pair of kings” ranked hands are different is very large. (You might want to go back to the “mammogram” notebook on Bernoulli trials to see how to do this.)

Extra credit: What to discard in 5 card draw.

In a game of 5 card draw with four players, you are given the cards

FiveCardDrawHand = {{4,4},{2,9},{1,5},{4,11},{2,12}};

You may discard as many (or as few) of these cards as you like:

a) What is the win probability if you “stand pat” and keep all 5 cards?

b)The win probability if you discard certain cards depends on which cards you draw to replace them (as well as the cards everyone else has, of course). Design and code an experiment which estimates the probability of winning with a given discard set by averaging experimental win probabilities over different choices of replacement cards.

c) According to your experiment, what’s the best win probability you can obtain by discarding a subset of your cards above and which subset should you discard?