Throwing Two Dice

GWM

After reading throw a dice, I decided to look into throwing 2 dice since many games such as monopoly throw 2 dice on each turn.

Using 2 dice makes life more interesting. The most likely throw is 7 - you can never throw 1, there is 1 way to throw 2, 2 ways to throw 3 (2,1 & 1,2) 3 ways to throw 4 (1,3; 3,1; 2,2) and so on. The following code provides some routines for emulating 1 or 2 dice using the simple rand() function. Paste this code into wish as it uses a Tk based histogram to plot the frequency.

sheila: Many games that I play involve throwing N dice, where N can be > 2. Also, I've played games that use 4, 6, 20, etc. sided die. I wrote a little tcl program once to assist in one of the games. I should go look for it. This one is cool, and would be easy to play with die other than 6 sides.

 proc throwdice {} {
        set ok 0
        while {!$ok} {
                set sc [expr 1+int(6*rand())]
                if {$sc<7} {set ok 1}
        }
        return $sc
 }
 proc throw2dice {} {
        lappend all  [throwdice]
        lappend all  [throwdice]
        return $all
 }
 proc throw2dicesum {} {
        set thro [ throw2dice]
        return [expr [lindex $thro 0]+[lindex $thro 1]]
 }

 #throwdice emulates a single dice of 6 sides.
 #throw2dice returns a list of the results of 2 throwdice;
 #throw2dicesum returns the sum of two dice.

 proc getfrequency {n} {
  # check how often we arrive at each 'square' from 0 with 2 dice thrown to reach square n at least.
        set i 0
        array set bins {}
        set maxbin $n
        while {$i<=$maxbin} { set bins($i) 0; incr i}        
        set i 0
        while {$i<40000} { ;# do this number of repeats to get statistical sample.
                set j 0
                set pos 0
                while {$pos<$n} { ;# continue until we reach N
                        set thro [throw2dicesum]
                        incr pos $thro
                        if {$pos<=$n} { ;# if > n then dont count any more.
                                incr bins($pos)
                        }
                }
                incr i
        }
        puts "Histogram of frequency of reaching square N from origin."
        set i 0
        while {$i<$maxbin} {
                puts "position\t$i\treached\t$bins($i)\ttimes"
                incr i
        }
        histogram [array get bins] 300 250
        return 0
 }
 global ready
 set ready 0
 proc histogram {slist wid ht} { ;# render a histogram
        global ready
        array set scores $slist
        set nms [lsort -integer [array names scores]]
        catch {destroy .h} {}
        catch {destroy .b} {}
        canvas .h -width $wid -height $ht -bg beige
          pack .h
        set nbars [array size scores] ;#how many histogram bars
        set nax [expr $nbars/10] ;# axis spacing
        set hwid [expr $wid/ $nbars]
        set i 0
        set hmax -9999999 ;# largest y value 
        set hmin  9999999 ;# smallest y value
        while {$i<$nbars} {
                set f $scores([lindex $nms $i])
                set hmax [ expr {$f>$hmax} ? $f : $hmax]
                set hmin [ expr {$f<$hmin} ? $f : $hmin]
                incr i
        }

        if {$hmax>$hmin} {
        set i 0
        set nay 100
        while {$nay<$hmax} {
                set yp [expr $ht-0.75*$nay-20]
                .h create line  0 $yp $wid $yp -fill red
                incr nay 100
        }
        set nax 10
        while {$i<$nbars} {
                set x [expr $hwid*$i]
                set rhs [expr $x+$hwid/2]
                set f [expr $ht-20-.75*$ht*$scores([lindex $nms $i])/$hmax]
                .h create rectangle  $x [expr $ht-20] $rhs $f -fill gray
                if {[expr $i>=$nax]} {
                .h create line  $x [expr $ht-20] $x 0 -fill red
                        incr nax 10
                }
                incr i
                incr x $hwid
        }
        update

        button .b  -text "Next" -command "incr ready" ;# when ready is changed, proceeds with commands
        pack .b
        }
 }
 
 getfrequency 36

Proc getfrequency finds how often you land on each square 0 to n (eg 0-36) no matter how many throws of the dice this takes. Proc histogram produces a Tk plot of the frequency of landing on each square. You will find that the number of times your throw lands on a particular square increases, then decreases, and then oscillates a little. It is remarkable that the rise and fall for squares up to 13 are almost linear. This is due to the probability of each throw increasing and decreasing linearly rather than in a nice bell shaped curve you might have expected [L1 ]. However landing at 7 can be done by throwing a 7 on first throw, OR by throwing 5&2, 2&5, 4&3, 3&4 or 2&2&3 or 2&3&2 or 3&2&2 (taking longer to get there but increasing the number of ways of reaching 7); this increases the probability of landing on 7 above the simple linear probability.

 Histogram of frequency of reaching square N from origin.
 position        0        reached        0        times
 position        1        reached        0        times
 position        2        reached        1128        times
 position        3        reached        2177        times

... this output is numerical results used in the histogram.