/** * Context: I'm making a variable length board game. There is a deck of cards * that tell the players what to do each turn. 5 of the cards are 'Discard * Energy' cards and after drawing all 5 of these cards the players will have no * energy left and they lose the game. Depending on the distribution of these * cards, the game will last a different number of turns. If all 5 cards are at * the top of the deck, the game will be over in 5 turns. If one of the cards * finds its way to the bottom of the deck, every turn card will be drawn before * the game is over. I'm ok with this, as long as 'most' games last a minimum * number of turns. I think 15 turns is a good length of time. So my question is * this: how many non-'discard energy' cards should I include in the deck? Is * there an equation that will tell me the percentage of games that last at * least 15 rounds given the total number of cards? What about an equation that * tells me the percentage of games that will be shorter than 10 games? * Alternatively, what if I said I wanted 90% of the game to last 15 turns or * longer. How many cards would I need? Thanks! * * http://www.reddit.com/r/CasualMath/comments/16i6eo/ * probability_question_how_long_will_my_game_last/ * * Goal: * * Make a program that simulates drawing cards until a target number of special * cards are hit and then prints out the the probability and cumumaltive * probability of each number of turns * */ public class HowLongWillMyGameLast { public static void main(String[] args) { /* * The use of doubles for integer values is to avoid having to recast to * skip integer division */ // control variables double totalNumberOfCards = 21; double numberOfEnergyCards = 5; int numberOfTrials = 1_000_000; boolean showCumulative = true; // data /* index represents finishing turn, value how many times finished there */ double[] numberFinishedOnTurnN = new double[(int) totalNumberOfCards + 1]; for (int i = 1; i <= numberOfTrials; i++) { double deck = totalNumberOfCards; double energyCards = numberOfEnergyCards; int turn = 0; while (energyCards > 0) { if (Math.random() >= 1.0 - (energyCards / deck)) { energyCards--; deck--; } else { deck--; } turn++; if (deck < 0) { // check for infinite loops System.out .println("drawing cards from a non-existant deck :-("); System.exit(1); } } numberFinishedOnTurnN[turn] += 1; } // end of simulations // calculate average number of turns Double averageNumberOfTurns = 0.0; for (int i = 0; i < numberFinishedOnTurnN.length; i++){ averageNumberOfTurns += i*(numberFinishedOnTurnN[i]/numberOfTrials); } // printouts System.out.println("There were " + (int) totalNumberOfCards + " in the deck, of which " + (int) numberOfEnergyCards + " were energy cards. " + numberOfTrials + " trials were run." ); System.out.println("On average the games lasted " + averageNumberOfTurns.toString().substring(0,5) + " turns"); if(showCumulative){ double cumulativeFinishes = 0; for (int i = numberFinishedOnTurnN.length-1; i >= (int) numberOfEnergyCards ; i--){ cumulativeFinishes += numberFinishedOnTurnN[i]; System.out.println((int)(cumulativeFinishes/numberOfTrials * 100) + "%" + " of the games finished on turn " + i + " or later"); } } else { for (int i = (int) numberOfEnergyCards; i < numberFinishedOnTurnN.length; i++){ if (numberFinishedOnTurnN[i] > 0.0){ System.out.println((int)(numberFinishedOnTurnN[i]/numberOfTrials * 100) + "%" + " of the games finished on turn " + i); } } } } }