What is the probability of getting yahtzee?

$\begingroup$

What is the probability of getting a yahtzee using $N$ dice with $X$ sides in $Y$ throws in a single round?

Which side of the dice appears on the yahtzee with doesn't matter (i.e. it doesn't matter if I throw ones, or twos, etc.). I also assume perfect strategy is used; that is, after each throw, one saves the number at which the most dice landed (in case of a tie, one just picks at random).

$\endgroup$ 6

4 Answers

$\begingroup$

What follows is a solution to a smaller problem; I don't have a good way to determine the probabilities of exactly k of some kind being the most of any kind on the first roll, but the work below could be used from that point to get an answer.

Let $f(N,X,Y)$ be the probability of getting all 1s with N dice, each with X sides, in at most Y rolls, where after each roll, 1s are retained and only non-1 dice are re-rolled. Working 1 roll at a time, the first roll could have exactly $k=0,\dots,N$ 1s. The probability of exactly k 1s in a single roll is ${N\choose k}\left(\frac{1}{X}\right)^k\left(\frac{x-1}{x}\right)^{N-k}$ and having k 1s in the first roll, we then need $N-k$ 1s in the remaining $Y-1$ rolls. So, $$f(N,X,Y)=\sum_{k=0}^{N}{N\choose k}\left(\frac{1}{X}\right)^k\left(\frac{x-1}{x}\right)^{N-k}f(N-k,X,Y-1).$$ Also, the probability of all 1s on 0 dice is 1 (0 of the 0 dice are guaranteed to be 1), so $f(0,X,Y)=1$, and the probability of all 1s on $N\ge 0$ dice in 0 rolls is 0 (can't get any 1s without rolling some dice), so $f(N,X,0)=0$ for $N\ge 0$. This is a complete definition of $f(N,X,Y)$, though it does not lend itself to easy computation. (However, software like Mathematica may be able to compute from this definition. In Mathematica: f[n_, x_, y_] := If[n == 0, 1, If[y == 0, 0, Sum[ Binomial[n, k]*(1/x)^k*(1 - 1/x)^(n - k)*f[n - k, x, y - 1], {k, 0, n}]]].)

$\endgroup$ 2 $\begingroup$

According to Wikipedia "the probability of a Yahtzee for any three-roll turn is about 0.04603 (or $\frac{347897}{7558272}$), or roughly 1 in 22 attempts."

$\endgroup$ $\begingroup$

This isn't a complete answer to your question, but at least it is a closed form. For 5 normal (6-sided), dice, the exact probability of achieving a yahtzee, following the optimum strategy, given $n$ rolls is

$1+\frac{53}{13} \left(\frac{5}{6}\right)^{2n+1}+\frac{11 \cdot 5^n}{13 \cdot 2^{n+5} \cdot 3^{3n+1}} -\frac{5^n}{8 \cdot 3^{2n-2}} -\frac{7 \cdot 5^{n+1}}{ 2^{n+5} 3^{n-1}} $

For example, setting $n=3$ gives $\frac{347897}{7558272}$.

$\endgroup$ $\begingroup$

Well I am not able to give you an analytical answer, but this question just screamed to be programmed. Now I am sorry that I haven't used Matlab ( which would be much less code ) but I implemented it in c++. The code is simply your rules implemented in my not so good c++. I used g++ 4.6.3 on Ubuntu 12.04. If you run the code, it will print the results and also write the pairs (number of dices | avg. number of throws) in out.txt. The result is plotted attached, plotted with gnuplot for number of dices $\leq$ 40.

See the results here as I dont know much about gnuplot and couldn't upload a .ps to MathSE I had to upload it there. For every number of dices, 10000 experiments have been player. The code is probably terrible slow so everyone feel free to improve it ;)

This here does the same computation for number of dices $\leq 400$ but only 1000 experiments each.

Maybe you can use this to varify any of the formulas.

yahtzee.cpp:

#include <iostream>
#include <stdlib.h>
#include <stdio.h>
#include <time.h>
#include <vector>
#include <fstream>
using namespace std;
int hasYourNumber(vector<int>,int );
int sum(int* ,int );
int mostFrequent ( vector<int> );
vector<int>throwDice(int);
int role();
void playYahtzee(int,int,bool);
int main ( void ) { int REP = 10000; // Number of repeting the experiment bool echo = 0; // print information (yes 1,no 0) for (int numberOfDices=1;numberOfDices<40;numberOfDices++){ playYahtzee(numberOfDices,REP,echo); } return 0;
}
void playYahtzee(int N,int REP,bool echo){// N dices with 6 faces each; srand( time(NULL) ); // initialize random generator int* throws = new int[REP]; // save number of throws for each experiment vector <int> dices; // save dices that came up in one throw inside this, vector just for size(), my way... for (int k = 0;k<REP;k++){ bool first = true; // is it the first throw? int AmountOfYourNumber = 0; // how often as our number occured int yourNumber = -1; // whats your number int numberOfThrows = 0; // how often have we been throwing in this round while (AmountOfYourNumber<N){ // finish if our number has occured N times numberOfThrows++; dices.clear(); dices = throwDice(N-AmountOfYourNumber); // place random integers between 1 and 6 inside if (first){ yourNumber = mostFrequent(dices);// choose the most frequent number AmountOfYourNumber += hasYourNumber(dices,yourNumber); // how often has it your number first = false; }else{ AmountOfYourNumber += hasYourNumber(dices,yourNumber); } if (echo){ // some output mostly for debugging printf("Your number is %d and it has occured %d times in throw 1 to %d.\n", yourNumber, AmountOfYourNumber,numberOfThrows); printf("\tNumbers in this throw:\n\t"); for (int i=0;i<dices.size();i++) printf("%d\t",dices[i]); printf("\n \n"); } } throws[k] = numberOfThrows; // save number of throws } double avg = double(sum(throws,REP))/double(REP); // calculate average printf("Average number (over %d repetitions) of attempts, when playing with %d dices equals %g\n",REP,N,avg); ofstream output; output.open ("out.txt",fstream::app); output << N << " " << avg<< endl; output.close();
}
int sum(int* throws,int N){ // = sum_i throws[i] int s = 0; for (int i=0;i<N;i++) s+= throws[i]; return s;
}
int hasYourNumber(vector<int> dices,int yourNumber){ // calculates how often yournumber is in dices int N = 0; for (int i=0;i<dices.size();i++){ if ( dices[i] == yourNumber) N++; } return N;
}
int mostFrequent ( vector<int> dices){ // which is the most frequent number, takes first best int freq [6] = {0,0,0,0,0,0}; for (int i=0;i<dices.size();i++){ freq[dices[i]-1]++; } int yourNumber = -1; int max = 0; for (int i=0;i<6;i++){ if (freq[i]>max) {yourNumber = i+1 ; max = freq[i];} } return yourNumber;
}
vector <int> throwDice(int M){ // throws M dices vector <int> dices; for (int i=0;i<M;i++) dices.push_back(role()); return dices;
}
int role(){ // throws one dice return rand() % 6 +1;
}
$\endgroup$

Your Answer

Sign up or log in

Sign up using Google Sign up using Facebook Sign up using Email and Password

Post as a guest

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

You Might Also Like