Yahtzee in Mathematica

Rules of Yahtzee (simplified)

Roll five dice, and re-roll some of them until all five dice show the same number.

Roll five dice. Suppose we get 1, 2, 1, 3, 1.

Keep the values that occur the most. In this example, we have three 1s.

Re-roll the other dice. In this case, re-roll the two dice that are not 1s. Suppose we get 1 and 4.

Repeat. In this example, we now have 1, 1, 1, 1, 4. Re-roll the die that isn’t a 1 until it shows a 1.

Question

What is the average number of rolls until all five dice show the same number?

Let’s use a simulation to find out.

Simulating Yahtzee

To simulate rolling a die, use the RandomInteger function:

RandomInteger[{1,6}]

RandomInteger can also roll many dice at once:

RandomInteger[{1,6},5]

We can write our own function to make this a bit easier to use:

rollDice[n_]:=RandomInteger[{1,6},n]

Try it out:

currRolls=rollDice[5]

Next, we need to count the number of 1s, 2s, ..., 6s that appear in currRolls. Store these counts in a list called matches.

matches={};
Do[ AppendTo[matches,Count[currRolls,i]], {i,1,6}];
matches

Now we need to find the largest number in our list matches, as well as which number on the dice was the most common roll.

maxMatch=Max[matches] (* number of times the most common roll appears *)

matchValue=Position[matches,maxMatch][[1,1]] (* number of the most common roll *)

Now remove all non-match dice. One way to do this is to simply reconstruct currRolls to contain maxMatch entries, each of which is matchValue.

currRolls=Table[matchValue,maxMatch]

If all dice don’t show the same number, then re-roll the non-matching dice.

currRolls=Join[currRolls,rollDice[5-Length[currRolls]]]

At this point, we want to again count the number of matched dice. We could re-run the line of code above that does that. However, a more elegant solution is to write a loop that rolls the dice, counts matches, and re-rolls as many times as necessary until all five dice show the same number. We will put this loop in a module, so we can run it easily. The module will return the number of rolls.

rollYahtzee:=Module[{numRolls=0,currRolls={}},
While[Length[currRolls] < 5,
(* roll the dice *)
numRolls+=1;
currRolls=Join[currRolls,rollDice[5-Length[currRolls]]];

(* testing only:
Print[currRolls]; *)

(* count the number of matches *)
matches={};
Do[ AppendTo[matches,Count[currRolls,i]], {i,1,6}];

maxMatch=Max[matches]; (* number of times the most common roll appears *)
matchValue=Position[matches,maxMatch][[1,1]];(* number shown on the most common roll *)

(* remove all non-matched dice *)
currRolls=Table[matchValue,maxMatch]
];

(* now all 5 dice show the same value, so return numRolls *)
numRolls
]

Try it out:

rollYahtzee

Average number of rolls

Simulate Yahtzee many times and record how many rolls each simulation takes. Then compute the average number of rolls.