//ShakeOTheDay.java import java.util.*; /** * A program to calculate the probability of winning the "Shake * of the Day" dice game at a certain watering hole in Madison, * Wisconsin (using Monte Carlo methods). It turns out to be a * hard problem for statistically unsophisticated bar-goers to * solve analytically because, as in Yahtzee, you can save dice * that match the number of the day in each roll (and only reroll * the remaining dice). This program was written to finally put * to rest an ongoing argument over whether or not it was * advantageous (from a "pot odds" perspective) to play the game, * given some known jackpot size (which of course isn't known * exactly in practice, but you can estimate by looking at the * jar they keep the money in). * * Rules: You get three rolls to achieve a "Yahtzee" on whatever * Shake of the Day number happens to be posted (here we chose 5, * which was the number on the day we actually wrote the thing). * After each roll, you can save any nice that match the goal * and just reroll the remainging ones. * * Assumptions: In reality, you get two shakes for a dollar and * can purchase an additional shake for an extra dollar. We * assumed a pure strategy where you always choose to make * _either_ two or three rolls. * * Interpretation: If you run the code, you'll find that * (for a sufficiently large value of numTries), the probability * of winning if you never buy the extra roll is 0.25%, which * means you should only play if theres ~400 bucks in the pot. * If you always buy the extra shake, the odds go to 1.33%, so * it's worth playing if there's $150 or so in the pot. * * Interesting psychological observation: Kyle has never played * this game, even when the pot appears to be large enough to * make it worth the risk. Matt continues to play it, even when * there's clearly not $150 to be won. * * Disclaimer: We wrote this code just for fun, and it shouldn't * be interpreted as formal advice for playing "Shake of the Day" * or as a statement about the fairness of the game. Who cares? * It's just a dice game in a bar. Also, I realize this * implementation isn't especially efficient (my roommate wrote * another version in way fewer lines that performs a lot better). * But I'm a modeler, and I was in a data structures class at the * time, both of which are factors in the way I went about writing * this thing. * * Written by: Kyle Oliver * * Enjoy! */ public class ShakeOTheDay { static boolean youWin = false; public static void main(String [] args) { Random rand = new Random(); int key = 5; int numTries = 10000000; int numWins = 0; int numShakes = 3; for (int i = 0; i < numTries; i++) { int[] bar = {0, 0, 0, 0, 0}; int rollsLeft = numShakes; while (rollsLeft > 0) { bar = shake(bar, key, rand); // see if we won yet int numYouNeed = 5; int numYouHave = 0; for (int j: bar) { if (j == key) { numYouHave ++; } } if (numYouNeed == numYouHave) { ShakeOTheDay.youWin = true; } rollsLeft --; } if (ShakeOTheDay.youWin == true) { numWins ++; } ShakeOTheDay.youWin = false; } double totalWins = numWins; double percentage = totalWins / numTries * 100; System.out.println("The odds of winning with " + numShakes + " shakes are " + percentage + "% (n = " + numTries + ")."); } private static int rollDie(Random rand) { return rand.nextInt(6) + 1; } private static int[] shake(int[] bar, int key, Random rand) { for (int i = 0; i < bar.length; i++) { if (bar[i] == 0) { int roll = rollDie(rand); if (roll == key) bar[i] = roll; } } return bar; } }