# 4 player card game, who has advantage? [closed]

Edit for "off topic" "correction".

I don't know why this question was considered "off topic". It seemed to draw a lot of attention. The "puzzle" was to figure out which person has the advantage which is not obvious. The pieces that need to be put together are the checks for each winner.

Also, if this type of question is "off topic", then why do they have both probability and card tags available on this site? I used both of those tags to classify my question here.

Four people, (call them C, D, E and F), decide to play a card game for fun. They use an ordinary fair deck of $52$ cards, shuffled well immediately before each hand is drawn, and randomly draw cards from it one a time without replacement, all 4 using (sharing) the same drawn cards to determine who wins. A win is defined as follows:

C wins if he gets at least one of all $13$ ranks of the cards (regardless of suit as they can be mixed suits or even all the same suit).

D wins if he gets either $6$ red cards or $6$ black cards in a row (consecutive).

E wins if she gets $4$ of a kind of ANY ONE odd rank ($A,3,5,7,9,J,K$).

F wins if she gets at least $12$ black cards and at least $12$ red cards.

Each win is based on the current hand only as there is no "carryover" from a previous hand. Each new hand starts "fresh".

It is possible for ties to occur but the rule is any and all ties are awarded as a half win for D and a half win for E. That is, if each player bet 1 dollar for a hand so that there were 4 dollars in the pot for that hand, D and E would split any ties so that they would get 2 dollars each. Note that D and E split ANY ties so even if only C and F tie, they both lose and D and E split the pot with a half win each.

So the question is who has the highest probability of winning and by how much over the competition?

Note that the minimum # of cards needed to win differs for each player:

(C: $13$), (D: $6$), (E: $4$), (F: $24$).

Another game rule is if nobody wins by the $28$th card drawn in the hand, then that hand has no winner and a new hand will be drawn. That is, $28$ cards max will be drawn per hand.

F.Y.I., my simulation has lots of "buckets" to count up interesting things and the most rare thing I see (that shows up as nonzero) out of $10,000,000$ iterations is D and E tying in only $8$ cards drawn. This is not a "bonus" tie because neither C nor F can tie with only $8$ cards drawn. It is so rare that out of $10$ million decisions, only $29$ were ties between D and E with exactly $8$ cards drawn. That one special case can probably be calculated mathematically since there are only $52 \choose 8$ card combos which is about $3/4$ billion. Even simulation of all of those hands is possible on a computer to get the exact count of winners.

$UPDATE:$ I am curious about how many actual ways there are for D and E to tie in exactly $8$ cards since it seems to be the most rare event that is happening in my simulation. I was able to quickly generate the 0.75 billion card combinations which is $52 \choose 8$ so I just have to insert the check for the ties and count them up. I have another simulation running now overnight so I don't want to stress my CPU at $100$% for many hours so I will wait until the first one finishes and then code the 2nd one and report back. Based on the simulation getting only $29$ out of $10,000,000$, I could think out of $750$ million possible $8$ card hands there should be a little over $2000$ ways to tie.

$UPDATE - 2$ Out of 1 billion simulated hands, I am seeing only $2547$ D/E ties on the $8$th drawn card. That is the most rare event I see of all the buckets I am viewing. It is almost as rare as a royal straight flush in a $5$ card poker hand ($5$ cards only).

$UPDATE - 3$ I made a mistake in that to simulate all the possible $8$ card hands to check for a D/E tie on that exact card, it is not just $52 \choose 8$ combinations because order is important, so it is $8$! more than that which is a huge number and too large to easily simulate on a computer. An example where D and E tie on the 8th card (using C=Club, H=Heart, S=Spade, D=Diamond) is AH,AD,AC,2C,3C,4C,5C,AS. That completes both the $6$ blacks in a row and quad aces on the $8$th card. So since $52!$ / $44!$ is such a huge number of hands to simulate/generate (it is over $30$ trillion), probably the best I can do (easily) is just simulate a $7$ card hand, check to make sure neither D nor E won at that point, then draw the 8th card and check if they tied on that card. Again that is only an approximation but will be faster than drawing up to $28$ cards and checking for $4$ possible winners. Note that there is no way there can be a tie on the $7$th card because a quad has $2$ of each color card so we would need those plus $6$ in a row of the same color card so that is $8$ cards minimum.

## closed as off-topic by leoll2, Engineer Toast, xnor, ghosts_in_the_code, mdc32May 10 '15 at 2:23

This question appears to be off-topic. The users who voted to close gave this specific reason:

• "This question is off-topic as it appears to be a mathematics problem, as opposed to a mathematical puzzle. For more info, see "Are math-textbook-style problems on topic?" on meta." – leoll2, Engineer Toast, xnor, ghosts_in_the_code, mdc32
If this question can be reworded to fit the rules in the help center, please edit the question.

• Doesn't this boil down to a math problem with a ton of computation? – Dennis Meng May 4 '15 at 3:43
• @DennisMeng I think a computer simulation would be the quickest/easiest way of figuring it out. Off the top of my head, F sounds easiest to get. – JS1 May 4 '15 at 4:25
• @JS1 Probably. But I was asking more because I was under the impression that math problems where you just throw computation power (either brain or computer) were considered off-topic. – Dennis Meng May 4 '15 at 4:30
• @JS1, why would F be the easiest to get when $24$ cards is the minimum for F to win but E can win with as few as $4$ cards and D could win with as few as $6$ cards and all ties involving F are a loss for F? Out of all $4$ players here, F requires the most cards to win at $24$ minimum. The average number of cards for a decision (win/tie) might even be less than that since C,D, and E require far fewer cards to possibly win, so on those hands (let's say only $20$ cards are drawn), F cannot win. – David James May 4 '15 at 10:30
• Because in puzzling.se, the more seemingly impossible it is for one event to happen, the more likely it is to be the answer =) – justhalf May 4 '15 at 11:35

It seems I am too stupid for this site: I haven't been able to post any solution that I made myself; though I can make my computer solve puzzles for me.

Here's Python code that I wrote: it runs a lot of simulations and counts victories for each player as well as losses of everyone (when nobody wins after 28 cards are drawn). A draw adds 1 point to D and E, while victory adds 2 points to the winner.

from random import choice

def countWinners(*args):
return sum(bool(x) for x in args)

deck = []
for a in ['H', 'D', 'C', 'S']:
for b in xrange(1, 14):
deck.append((a, b))

results = {'C': 0, 'D': 0, 'E': 0, 'F': 0, 'Nobody': 0}
games = 1000000
for i in xrange(games):
C = set()
D = [0, 0]
E = {1: 0, 3: 0, 5: 0, 7: 0, 9: 0, 11: 0, 13: 0}
F = {'R': 0, 'B': 0}

cards = deck[:]
cardcount = 0
if i % 1000 == 0:
print 1.0*i/games
while len(C) < 13 and D[1] < 6 and all(x < 4 for x in E.itervalues()) and any(y < 12 for y in F.itervalues()) and cardcount < 29:
card = choice(cards)
cards.remove(card)
cardcount += 1

if card[0] in ('C', 'S'):
if D[0] == 0:
D[1] += 1
else:
D[0] = 0
D[1] = 1
if card[0] in ('H', 'D'):
if D[0] == 1:
D[1] += 1
else:
D[0] = 1
D[1] = 1

if card[1] % 2 == 1:
E[card[1]] += 1

if card[0] in ('C', 'S'):
F['B'] += 1
else:
F['R'] += 1

if cardcount == 29:
results['Nobody'] += 2
else:
if countWinners(len(C) == 13, D[1] >= 6, any(x == 4 for x in E.itervalues()), all(y >= 12 for y in F.itervalues())) >= 2:
results['D'] += 1
results['E'] += 1
else:
if len(C) == 13:
results['C'] += 2
if D[1] == 6:
results['D'] += 2
if any(x == 4 for x in E.itervalues()):
results['E'] += 2
if all(y >= 12 for y in F.itervalues()):
results['F'] += 2
for player in results.keys():
print player, 1.0*results[player]/2/games


It may be not quite clear, but it seems to work. The interesting thing is that the output is this:

C 0.2471
Nobody 0.0186
E 0.242735
D 0.244535
F 0.24703


Each player wins in about 24.5% of all games! That looks quite suspicious, I must admit, but I couldn't find any bugs that I didn't fix.

UPD. After running 10.000.000 simulations the results are

C 0.2470487
Nobody 0.0184092
E 0.2423495
D 0.2435982
F 0.2485944


UPD2. 61 millions in:

C 0.247020145161
Nobody 0.0184576290323
E 0.242251653226
D 0.243597201613
F 0.248673354839


UPD3. After 130 millions the probabilities are more or less stable around

C 0.2469661
Nobody 0.0184452
E 0.2423032
D 0.2435659
F 0.2487196


I'm stopping simulations because some much, much faster solutions were added and their results seem to be consistent with the ones I've got

• Wow interesting. How long did the 1 million iterations take to run? If a reasonable amount of time, perhaps try 10 million because it seems C and F are "neck and neck". Solving this problem thru simulation relies on a good random number generator and lots of iterations. For example, if you only ran 1000 iterations, the winner might not be C like here. It seems odd and somewhat unpredictable that the "odds are even" when each of the 4 players has much different winning conditions ranging from only 4 cards min needed to as many as 24 cards min needed. Try 1000 and 10,000,000 please if you can – David James May 4 '15 at 13:58
• Also, it is interesting that in about $2$% of the hands, nobody wins! That is surprising especially when we can go up to $28$ cards drawn and there are $4$ possible ways to win (cuz of $4$ players). A loss would have to "dodge" all of those winning ways in $28$ cards such as not completing an "odd quad", $17$ or more of 1 color card... – David James May 4 '15 at 14:21
• Having a large # of iterations is important because too few will make someone draw the wrong conclusion. Worst case is if you play this game manually (or simulate it) only getting $4$ decisions. It is possible that one player can win all $4$ games and make you think they have a very strong advantage but as we can see, they are all about even. Even $1000$ decisions is too few and any of the players can be the overall "winner". Based on the results of Akiiino, it appears C is the winner but it may be too close to call. – David James May 4 '15 at 14:30
• @DavidJames, simulation took about 25 minutes, and results are almost the same, but C is not a winner anymore: C: 0.2470487; Nobody: 0.0184092; E: 0.2423495; D: 0.2435982; F: 0.2485944; I think that at this point it is almost impossible to improve the answer by brute-force simulation: the probabilities are too close to be distinguished in such way. I suppose C and F are winning more often than others, but who is the most probable winner is to be answered by math, not programming – Akiiino May 4 '15 at 14:44
• Using math alone if likely too hard so computers are our only hope. Getting it exact is not necessary, just getting consistent results is. For example, if C is the overall winner one time then F then back to C... that is not conclusive. However if F is always the overall winner then that is (assuming many iterations like at least a few million). If you ran a simulation overnight and got 1 billion decisions then I would say that is conclusive. It would be "hard" for a correct simulation to give the wrong results with that many trials. Any anomalies would get "ironed out". – David James May 4 '15 at 14:58

## A fast C program

I'll throw my C program into the mix. It runs much faster than the Python program from @Akiiino. I am able to run over 1 million hands per second, and so I ran it for 1 billion hands (taking about 13 minutes). The program listing is at the end of this answer. Here are the results:

## The original problem

The original problem did not impose a 28 card limit. I guessed that F would be the easiest to achieve and I was right:

(10 million iterations)
C) 24.9527%
D) 24.5856%
E) 24.5530%
F) 25.9087%


## With 28 cards max

With a 28 card limit, the result became closer:

(1 billion iterations)
C) 24.6989%
D) 24.3624%
E) 24.2243%
F) 24.8718%
N) 1.8426% (no winner)


If someone wants to run my program for even more iterations, feel free to do so.

## So why did I guess F?

Ok so David James asked why did I guess F? I did some quick calculations (that were admittedly not very precise) to guesstimate the avg card at which each player would win. Remember, the following is not correct math, it's just what was going through my mind:

## My rough calculations (which were bad)

Player C needs all 13 cards to win. This is very similar to the Coupon collector's problem. If each card were replaced back into the deck, it would take on average 42 cards dealt to win (according to the Wikipedia table). However, the cards are not placed back into the deck, so it takes less cards on average to win. Still, I figured the number would be closer to 42 than to 26. I guessed halfway in between so 34.

Player D needs 6 of the same color in a row to win. The odds of that happening are 1/32, starting at card 6. It is 1/32 because it is 1/64 chance for 6 reds and 1/64 chance for 6 blacks. So I figured that D would get the 6 in a row on average at card 38 (start at card 6 and takes 32 cards on average).

Player E wins by getting one of 7 four of a kinds. The odds of getting a four of a kind for a particular number (such as Ace) with 4 cards is 4/52 * 3/51 * 2/50 * 1/49 which is 1 in 270725. Given 7 different numbers (A3579JK), the chances are 1 in 38675. Now I just need to know what number of cards N is it that makes N C 4 around half that (19337), where C is the combination operator. The answer is between 27 (17550 4-card combos) and 28 (20475 4-card combos). So I called it 27.5.

Player F wins by getting 12 red and 12 black cards. Using a binomial calculator, I was able to determine that with 26 cards, the odds of getting at least a 12/12 split was 44.3%. With 27 cards, the odds went up to 55.8%. So the expected win occurs between 26 and 27 cards. So I called it 26.5.

## The reality

I made a big mistake in calculating player D. The 6 in a row of a color needs to account for the fact that you aren't putting the card back into the deck. So after you get 5 in a row of red, the odds of getting a 6th red card is much less than 50%. My guess for player C was also way off.

I modified my program to find out how many cards on average does it take each person to win:

(50 million iterations)
C) 27.997
D) 25.810 (but with a 53.6% of not even winning at all)
E) 28.904
F) 26.375


But even knowing the average card isn't good enough because you also need to take into account the distribution, and also figure out how often there are ties. Anyways, I don't know of a good way to determine the answer to this problem without a computer simulation.

Here is my program:

## The program listing

#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <time.h>

#define DEFAULT_ITERATIONS        1000000
static int simulate(void);
static int deck[52];

int main(int argc, char *argv[])
{
int iterations = DEFAULT_ITERATIONS;
int wins[5] = {0};
int i       = 0;

for (i=0;i<52;i++)
deck[i] = i;

srand(time(NULL));
if (argc > 1)
iterations = atoi(argv[1]);

// Each win earns 2 points.  A tie earns 1 point for D and 1 for E.
// wins[4] is the slot for "no winner".
for (i=0;i<iterations;i++) {
int winner = simulate();
if (winner == -1) {
// It's a tie.  Half point to D an E.
wins[1]++;
wins[2]++;
} else {
// A sole winner.
wins[winner]+=2;
}
}
for (i=0;i<5;i++) {
printf("%d) %8d wins out of %8d = %7.4lf%%\n", i, wins[i], 2*iterations,
((double) wins[i] * 100.0) / (2*iterations));
}
return 0;
}

// Returns winner 0-3, 4 for no winner, or -1 for a tie.
static int simulate(void)
{
int i;
int rankBitmap        = 0;
int redCardsInARow    = 0;
int blackCardsInARow  = 0;
int totalReds         = 0;
int totalBlacks       = 0;
int rankHistogram[13] = {0};
int win               = 0;

// Shuffle deck.
for (i=0;i<51;i++) {
int r = rand() % (52 - i);
int tmp;

// Swap card i with card i+r.
tmp       = deck[i];
deck[i]   = deck[i+r];
deck[i+r] = tmp;
}

// Deal cards one by one, and update win conditions.
for (i=0;i<28;i++) {
int card = deck[i];
int color = card & 1;
int rank  = card >> 2;

// C wins if he gets all 13 ranks.
rankBitmap |= (1 << rank);
if (rankBitmap == 0x1fff)
win |= 0x1;

// D wins by getting 6 red cards or 6 black cards in a row.
if (color) {
// Black.
redCardsInARow = 0;
if (++blackCardsInARow == 6)
win |= 0x2;
} else {
// Red.
blackCardsInARow = 0;
if (++redCardsInARow == 6)
win |= 0x2;
}

// E wins if he gets 4 of a kind of any odd rank (A3579JK) (7 chances).
if ((rank & 1) == 0) {
if (++rankHistogram[rank] == 4)
win |= 0x4;
}

// F wins by getting 12 black and 12 red cards.
if (color)
totalBlacks++;
else
totalReds++;
if (totalBlacks >= 12 && totalReds >= 12)

win |= 0x8;

if (win != 0)
break;
}
// If we dealt 28 cards, there must not be a winner.
if (i == 28)
return 4;
switch (win) {
case 0x1: return 0;
case 0x2: return 1;
case 0x4: return 2;
case 0x8: return 3;
default: return -1; // Must be a tie.
}
}

• Nice work JS1. This question was an exercise in accurate programming and to illustrate how the # of decisions is important to get correct results. Note that if you only run about 100,000 decisions of less, you may get the wrong "winner" such as C but in the longrun, F is actually the winner. Kudos to JS1 for "guessing" (educated) the correct answer of F. I tried to throw him off by pointing out things like F needs the most cards of all 4 players to even have a chance at winning but his "pre-analysis" was good enough to get it right.1 million or more decisions should give correct answer of F. – David James May 4 '15 at 22:41
• It might be fun to really optimize this simulation for speed and then try something like 1 trillion decisions. Things to "prune" would be don't even check for C winning unless 13+ cards are dealt. Same with F but don't check below 24 cards dealt.... If someone could break this up into chunks such as all possible 4 card hands, all possible 5 card hands... and count up the winners, that would be a super solution and 100% accurate. The sum of those all the up to 28 drawn cards is about 1.5 quadrillion so 1 computer may not be enough unless some clever optimizations are done but we know F wins. – David James May 4 '15 at 22:45
• Change your program to calculate the average # of drawn cards for ANY win (or tie). You can include no wins as well as it doesn't change the answer much (perhaps by half a card). I am showing under 21 cards as the average for a decision. Your numbers for ave # of cards for C,D,E, and F are higher because that is assuming no competition but they all share the same cards so the 26.5 or so average of the 4 players solo drops to about 21 when they all play together but that makes sense because it is easier for someone to win (or tie) if all 4 win conditions are active simultaneously. – David James May 4 '15 at 23:55
• JS1 - What computer did you run the simulation on where you are getting over $1$ million decisions per second? Also, can you try some register variable(s) in c to see if that helps speed things up? It seems like with some optimizations, you might be able to get close to $100$ billion decisions overnight (in $8$ to $10$ hours) and post the results. – David James May 5 '15 at 0:39
• @DavidJames It was a Windows 7 32-bit 3.2 GHz Core i5. I could get a lot more speed by using threads for parallel execution (4 cores = 4x speed). But I just whipped this program together in a hurry so I didn't bother. I doubt the results would change too much. Plus I would use a better rng because the system rand() would start to cycle at 2^32 random numbers. – JS1 May 5 '15 at 0:48

After 100,000,000 iterations, I get the following (CIs calculated based on this: http://www.evanmiller.org/statistical-formulas-for-programmers.html#prop_mci):

C: 0.246899 - 0.247071
D: 0.24354 - 0.243711
E: 0.242103 - 0.242275
F: 0.24869 - 0.248863
X: 0.018397 - 0.0184508


Which corroborates Akiiino's numbers and means that F has a real advantage, although a small one. Code below if you want.

#include <iostream>
#include <random>
#include <chrono>
#include <vector>
#include <algorithm>
#include <array>
#include <string>
using namespace std;

void report(string name, double x, double z) {
double n = z / 2;
double p = x / z;
double c0 = (p + 2 / n) / (1 + 4 / n);
double c1 = 2 * sqrt((p * (1 - p) + 1 / n) / n) / (1 + 4 / n);
cout << name << ": " << (c0 - c1) << " - " << (c0 + c1) << endl;
}

int main() {
array<int, 52> cards; // rank then suit, alternating colors of suits
for(int i = 0; i < 52; ++i)
cards[i] = i;

long long c = 0, d = 0, e = 0, f = 0;

mt19937_64 rnd(chrono::system_clock::now().time_since_epoch().count());

for(long long z = 2, r = 2;; z += 2) {
shuffle(cards.begin(), cards.end(), rnd);

array<int, 26> counts = {};

int dr = 0, db = 0;
for(int i = 0; i < 28; ++i) {
counts[cards[i] % 26] += 1;

int cs = 1, es = 0;
for(int j = 0; j < 13; ++j) {
if(counts[j] + counts[j + 13] == 0)
cs = 0;
if(j % 2 == 0 && counts[j] + counts[j + 13] == 4)
es = 1;
}

if(cards[i] % 26 < 13) {
dr += 1;
db = 0;
} else {
db += 1;
dr = 0;
}
int ds = (dr >= 6 || db >= 6);

int fs = 0, fr = 0, fb = 0;
for(int j = 0; j < 13; ++j)
fr += counts[j];
for(int j = 13; j < 26; ++j)
fb += counts[j];

fs = (fr >= 12 && fb >= 12);

if(cs + ds + es + fs > 0) {
if(cs + ds + es + fs > 1) {
d += 1;
e += 1;
} else {
c += 2 * cs;
d += 2 * ds;
e += 2 * es;
f += 2 * fs;
}
break;
}
}

if(z == r) {
cout << (z / 2) << endl;
report("C", c, z);
report("D", d, z);
report("E", e, z);
report("F", f, z);
report("X", z - c - d - e - f, z);
cout << endl;

r *= 10;
}
}
}

• Nice work too. Computer simulation of the actual game is great for these type of counting problems and one of the few practical solutions. Perhaps I can encapsulate my simulation for checking and counting winners into a single subroutine and then call it, first simulating all possible 4 card hands, then simulating all possible 5 card hands... and build a table of winners for C,D,E, and F. That would work when the # of drawn cards is low like single digits but not for something like 20 cards drawn as the number of card combinations is huge. Simulation of 1 million or more hands is the way! – David James May 4 '15 at 23:44
• A little bit of statistics can make the results of these types of simulations much more robust. With those confidence intervals (assuming I've calculated them correctly) you can say what the chance is that the difference is just due to random luck, and in this case, it's pretty clear that the difference between C and F isn't just luck. – Joshua Taylor May 5 '15 at 2:30

## Exact odds of D and E tying on the eighth card

This seemed like a separate question so I'm giving an answer just for this part of it. You can count exactly how many hands will cause D and E to tie on the eighth card dealt.

For the first card, there are 28 cards that are part of the 4 of a kinds. For the second card, the card dealt must be the same rank and color as the first card, meaning there is only one possible card. Example: first card is AS, second card must be AC. Therefore, the first 2 cards have 28 possibilities.

The next 6 cards must all be of the opposite color to the first two cards. In addition, one of the first five and also the last of these 6 cards must match the rank of the first two cards.

To find out how many possibilities there are, first consider the 4 cards that are not part of the 4 of a kind. There are 24 C 4 ways of choosing these four cards, times 4! ways of ordering them.

To those 4 cards, one of the matching ranked cards must be added to make the first five cards. That matching card can be placed in one of 5 positions. In other words, the 4 nonmatching cards plus the one matching card can have 5! possible orderings.

Finally, the two matching cards can be swapped, doubling the number of ways the last 6 cards can be made. The total is now:

28 * 24C4 * 5! * 2 = 71406720 possibilities


Out of:

52! / 44! = 3.034e13 total possibilities


Which is approximately:

 1 in 424923 chance


You could also calculate it exactly if you wanted to.

• I ran another simulation of $1$ billion $8$ card hands and according to your formula, I should have gotten $2353.37$ "winners". My results were $2334$ winners which is very close (within $1$%). I was curious about this case because it is the most rare event of all the events I have buckets to count up (wins & ties for all different card counts). – David James May 10 '15 at 2:52
• To put that "rareness" into perspective, it is about $11$ times as rare as getting an "odd quad" dealt in the first $4$ cards. My simulation told me that happened $25,532$ times out of 1 billion hands. – David James May 10 '15 at 3:13
• @DavidJames "Odd quad": 28*3*2*1 chances out of 52*51*50*49 total = 25856.5 expected out of 1 billion hands. – JS1 May 10 '15 at 5:11
• Maybe why our results are about $1$% off is because I first checked if either D or E won at $7$ cards dealt before I then process the $8$th card and check for a tie. If I didn't do that check, my numbers would have been slightly higher. – David James May 10 '15 at 10:36
• This "puzzle" is interesting because it is not obvious to someone trying to solve it who has the advantage. Someone could "argue" any of C,D,E, or F has the advantage and it would be hard to dispute without actually running a computer simulation of 1 million or more decisions. Just playing the game with a deck of cards wont tell you the long term winner. The only "bias" I see that might "give away" that F may have an advantage is that the first $12$ cards are all guaranteed good cards for F whereas that is not true for any other player but amazingly they all have about identical probabilities. – David James May 10 '15 at 10:47