# Scissors, paper, stone. Donal K. Fellows. donal@ugglan.demon.co.uk # The algorithm behind this is not that good. Producing a good # algorithm (especially one that adapts to the way that the user # plays) would be an interesting AI project. Myself, I think that AI # is boring, so I find the creation of algorithms to make these sorts # of games _very_ tedious. Better algorithms are welcome! if {[catch {expr rand()}]} { # ---------------------------------------------------------------------- # Random number generator - adapted from algorithm in "ML for the # Working Programmer" by Larry Paulson, Cambridge University Press, 1991 set tcl_precision 17; # Full precision please! proc nextrand seed { return [expr \ (16807.0*$seed)-2147483647.0*floor(16807.0*$seed/2147483647.0)] } proc srand seed { # Magic! The default range of integers is from 0 to 99 proc rand {{range 100}} [join [list "set seed \[nextrand $seed\]" \ {srand $seed} \ {return [expr int(($seed/2147483647.0)*$range)]}] \;] } # Initialise from the clock. This is not as good as I would like, but # it will do... srand [clock seconds]; rand; rand; rand } else { # Use the builtin instead proc rand {{range 100}} {expr {int(rand()*$range)}} } # ---------------------------------------------------------------------- # The mechanics of the game set f0 0 set f1 0 set cur 3 proc computerchoose {} { global f0 f1 cur lastuser if $cur==3 { set cur [rand 3] } elseif $f0==0&&$f1==0&&[rand 3]==0 { set cur [rand 3] } elseif $f1!=2&&[rand 2] { set cur [expr $lastuser+1] if $cur>2 {set cur 0} } elseif [rand 4]==0 { set cur [rand 3] } } proc userchoose {i} { global f0 f1 cur lastuser set f0 $f1 set f1 [report $i $cur] set lastuser $i computerchoose } proc report {u c} { global cscore uscore .uval conf -text "You chose: [lindex {Paper Scissors Stone} $u]" .cval conf -text "I chose: [lindex {Paper Scissors Stone} $c]" if {$u==$c} { .whowon conf -text "A draw!" return 1 } elseif { $c==0 && $u==1 || $c==1 && $u==2 || $c==2 && $u==0 } { .whowon conf -text "You won!" incr uscore return 0 } else { .whowon conf -text "I won!" incr cscore return 2 } } # ---------------------------------------------------------------------- # Create the user interface pack [frame .fb] -side bottom -fill x -expand 1 pack [button .fb.1 -text Paper -command {userchoose 0}] -side left -expand 1 -fill x pack [button .fb.2 -text Scissors -command {userchoose 1}] -side left -expand 1 -fill x pack [button .fb.3 -text Stone -command {userchoose 2}] -side left -expand 1 -fill x pack [frame .fr] -side right pack [frame .fr.m] [label .fr.sc -text SCORES] [frame .fr.y] -side top -fill both -expand 1 pack [label .fr.m.l -text Me:] -side left pack [label .fr.m.s -textvariable cscore] -side left -fill x -expand 1 pack [label .fr.y.l -text You:] -side left pack [label .fr.y.s -textvariable uscore] -side left -fill x -expand 1 pack [label .uval] [label .cval] [label .whowon] -side top set cscore 0 set uscore 0 computerchoose if ![array exist embed_args] { . conf -width 190 -height 90 pack propagate . 0 } # ---------------------------------------------------------------------- # Use bitmaps (an afterthought) image create bitmap paper -data {#define paper_width 32 #define paper_height 16 static unsigned char paper_bits[] = { 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0xb0, 0x01, 0x00, 0x00, 0x0c, 0x06, 0x00, 0x80, 0x03, 0x18, 0x00, 0x60, 0x00, 0x60, 0x00, 0x18, 0x00, 0x80, 0x80, 0x07, 0x00, 0x40, 0x60, 0x00, 0x00, 0x20, 0x1c, 0x00, 0x00, 0x1c, 0x02, 0x00, 0x00, 0x03, 0x03, 0x00, 0xc0, 0x00, 0x0c, 0x00, 0x3c, 0x00, 0x30, 0x00, 0x03, 0x00, 0xc0, 0xc1, 0x00, 0x00, 0x00, 0x26, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00}; } image create bitmap scissors -data {#define scissors_width 32 #define scissors_height 16 static unsigned char scissors_bits[] = { 0xf8, 0x1f, 0x00, 0x00, 0x18, 0x10, 0x00, 0x00, 0x30, 0x10, 0x00, 0x3e, 0xe0, 0x18, 0xc0, 0x07, 0x80, 0x0b, 0xf0, 0x01, 0x00, 0x0e, 0x7c, 0x00, 0x00, 0xb8, 0x1f, 0x00, 0x00, 0x60, 0x06, 0x00, 0x00, 0x40, 0x02, 0x00, 0x00, 0xf0, 0x0f, 0x00, 0x00, 0x1c, 0x3e, 0x00, 0x00, 0x0f, 0xf8, 0x00, 0xc0, 0x19, 0xe0, 0x03, 0x70, 0x10, 0x00, 0x0f, 0x18, 0x10, 0x00, 0x38, 0xf8, 0x1f, 0x00, 0x00}; } image create bitmap stone -data {#define stone_width 32 #define stone_height 16 static unsigned char stone_bits[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0xf0, 0xff, 0x00, 0x00, 0x78, 0xf7, 0x00, 0x00, 0xfe, 0xf7, 0x01, 0x00, 0xfd, 0xe7, 0x01, 0x00, 0xeb, 0x2f, 0x03, 0x00, 0xe7, 0xdf, 0x03, 0x80, 0x5f, 0xee, 0x07, 0x80, 0xbf, 0xef, 0x05, 0x80, 0x77, 0xef, 0x07, 0x80, 0xfe, 0xff, 0x07, 0x80, 0x3f, 0xff, 0x02, 0x00, 0xff, 0xf7, 0x03, 0x00, 0x7e, 0xff, 0x00, 0x00, 0xf8, 0x03, 0x00}; } .fb.1 conf -image paper .fb.2 conf -image scissors .fb.3 conf -image stone