#!/usr/bin/env python """ Craps simulation See for example http://en.wikipedia.org/wiki/Craps Chap 9, Exercise 7, pg 292 of Zelle's "Python Programming" Jim Mahoney, Oct 24 2006 for the Intro Programming class --- output (on a PowerBook, with test games and all defaults ) ---- thirty:Desktop$ ./craps.py Testing 5 games === game 1 === first roll is 8 roll 2 is 8 which makes the point and wins. === game 2 === first roll is 10 roll 2 is 7 which is a seven-out and loses. === game 3 === first roll is 9 roll 2 is 3 roll 3 is 5 roll 4 is 6 roll 5 is 7 which is a seven-out and loses. === game 4 === first roll is 9 roll 2 is 9 which makes the point and wins. === game 5 === first roll is 8 roll 2 is 2 roll 3 is 9 roll 4 is 8 which makes the point and wins. Calculating the odds of winning at craps... number of games simulated = 10000 number of games won = 4887 odds of winning are = 0.489 +- 0.010 at 95% confidence thirty:Desktop$ --- output (on cs, without tests, with 1e6 simulated games) ---- mahoney@cs oct_25.attachments$ time ./craps.py Calculating the odds of winning at craps... number of games simulated = 1000000 number of games won = 492328 odds of winning are = 0.4923 +- 0.0010 at 95% confidence real 0m29.382s user 0m29.372s sys 0m0.004s mahoney@cs oct_25.attachments$ """ from math import sqrt from random import randint def roll(): """ Return the result of rolling one 6-sided die. """ return randint(1,6) def game(verbose=True): """ Play a game of craps. Return True or False for a win or a loss. If 'verbose' is set (by default it is), then print out a description as well. """ first_roll = roll() + roll() if (verbose): print " first roll is", first_roll if (first_roll in (2,3,12)): if (verbose): print " which craps out and loses." return False elif (first_roll in (7,11)): if (verbose): print " which wins outright." return True else: roll_number = 1 while True: roll_number = roll_number + 1 next_roll = roll() + roll() if (verbose): print " roll", roll_number, "is", next_roll if (next_roll == first_roll): if (verbose): print " which makes the point and wins." return True elif (next_roll == 7): if (verbose): print " which is a seven-out and loses." return False def test_games(n_games=5): """ Run a bunch of verbose games """ print "Testing", n_games, "games " print for i in range(n_games): print "=== game", i+1, "===" game(verbose=True) print def calculate_odds(n_games=1e4, verbose=True): """ Calculate the odds of winning by running a number of games (1000 games by default). Return the measured odds as the fraction wins/n_games. If 'verbose' is True (the default), then print the odds too.""" if (verbose): print "Calculating the odds of winning at craps..." (wins, games) = (0, 0) n_games = int(n_games) while (games < n_games): games = games + 1 if ( game(verbose=False) ): wins = wins + 1 odds = 1.0 * wins / n_games # sigma_1 = estimated standard deviation of odds of a single game # sigma_n = estimated standard deviation of odds from n games # statistics say true value is in +-2*sigma with 95% probability. sigma_1 = sqrt( odds * (1.0 - odds) ) sigma_n = sigma_1 / sqrt( 1.0 * n_games ) if (verbose): print " number of games simulated = %8i" % n_games print " number of games won = %8i" % wins print " odds of winning are =" + \ " %.4f +- %.4f at 95%% confidence" % (odds, 2*sigma_n) return odds ## un-comment the next line to see the verbose test games. # test_games() # We need about a million games to get enough statistics to show # that the odds of winning are really less than a half. # On cs (with a 2Hgz dual core AMD64 cpu) this takes about half a minute. calculate_odds(n_games=1e6)