This is the GUI-version of [HiLo]: ---- # HiLo2.tcl - HaJo Gurt - 2005-06-20 # Simple number-guessing-game with GUI #########.#########:#########^#########+#########-#########*#########$##### proc random { {range 100} } { # Return a number in the range 0 .. $range-1 return [expr {int(rand()*$range)}] } proc Disp { {w .res1} {str ""} } { # Output string to one of the text-widgets $w insert end "\n" $w insert end $str $w see end ;# scroll to bottom } proc Disable {} { # Disable entry-widget, highlight Newgame-Button .inp1 config -state readonly .but1 config -bg green } proc NewGame {} { # Start a new game set ::nGuess 0 #set ::Secret 13 set ::Secret [expr {[random $::Max] +1 }] .res1 delete 0.0 end .res2 delete 0.0 end Disp .res1 " Guess my number:\n" Disp .res2 " (1 .. $::Max) \n" .inp1 config -state normal .but1 config -bg grey } proc TestNum {} { ;# ?? # Test if input is numeric set ok [string is integer $::Guess] if {$ok==0} {bell} return $ok } proc Update {} { # Process input, update display global Secret Guess nGuess set ok [string is integer $::Guess] if {$ok==0} { bell ;# alert: input-error } else { incr ::nGuess if {$Guess < $::Secret} { Disp .res1 "$Guess is too low" } if {$Guess > $::Secret} { Disp .res2 "$Guess is too high" } if {$Guess == $::Secret} { Disable Disp .res1 "$Guess is correct.\nYou needed $nGuess guesses."; } } set Guess "" ;# clear input-field } proc Init {} { # Initialize values, build GUI global Max Secret Guess nGuess set Max 100 frame .f1 frame .f2 ;# -bg blue -relief ridge pack .f1 .f2 -pady 2 text .res1 -width 20 -height 10 text .res2 -width 20 -height 10 pack .res1 .res2 -in .f1 -side left tk_optionMenu .opt1 Max 16 64 100 128 256 512 1000 1024 2048 4096 8192 button .but1 -text "New game" -command {NewGame} label .lx -text "" -anchor c -padx 12 ;# Spacer label .lab1 -text "Guess:" entry .inp1 -width 5 -textvariable Guess ;#-validatecommand TestNum -validate key pack .opt1 .but1 .lx .lab1 .inp1 -in .f2 -side left -padx 2 -pady 2 bind .inp1 {Update} wm title . "HiLo 2" } Init NewGame focus -force .inp1 ---- [HJG] The options -relief and -validatecommand did not work as expected, but otherwise everything works fine. [MG] The problem with your -validatecommand there is that you're checking the -textvariable for the widget, to see if the new text is valid. The way the validation works, though, is that you check before the value actually changes (and thus before the -textvariable is altered), to decide whether the change can happen or not. If you change it to use entry .inp1 -width 5 -textvariable Guess -validatecommand {TestNum %P} -validate key then TestNum will be called with one arg - the %P will be substituted with the value of the entry widget if the change goes ahead. (There are several other validations available - check the 'Validation' section of the entry widget manpage.) In this particular instance, you'd want to check that the string entered is either a number, or blank - which your TestNum already does. So, all you need to do is change it to take an argument, and check that instead of $::Guess proc TestNum {value} { # Test if input is numeric set ok [string is integer $value] if {$ok==0} {bell} return $ok } And then it should work OK. One other update you might want to add: In your Update proc, you use [[string is integer $::Guess]] to see if the update should go ahead. The problem with that is that the empty string passes the test. If you change that one to be [[string is integer -strict $::Guess]] it will stop people being able to guess "", and actually work on integers alone. [MG] adds: the problem you're having with the -relief on the frame .f2 is that it's -borderwidth is set to 0. If you use frame .f2 -bg blue -relief ridge -borderwidth 3 the ridge will show up. ---- [Category Games]