'''HiLo''' is a simple number-guessing game: for each guess, you get the answer "too high" or "too low", until you guess right. With this game, you can explain how binary seaching works. ---- #! /usr/bin/tclsh # HiLo.tcl - HaJo Gurt - 2005-06-20 # Simple Guess-the-number - game # # !! Run this in tclsh84 - wish has a bug with "gets" !! # See also: http://wiki.tcl.tk/10794 - [gets workaround] proc input1 {prompt} { #: Get input from user puts -nonewline $prompt set n [gets stdin] ;# implicit return } proc input {prompt} { #: Get input from user, accept only numbers set ok 0 while {$ok==0} { puts -nonewline $prompt set n [gets stdin] set ok [string is integer -strict $n] if {$ok==0} { puts "'$n' is invalid !\a" } ;# "\a": bell } return $n } proc inputA {prompt} { #: Test: "Automatic" input, simulates user puts -nonewline $prompt incr ::x ;# Global variable x } proc random { {range 100} } { #: Return a number in the range 0 .. $range-1 return [expr {int(rand()*$range)}] } #########.#########=#########^#########+#########*#########_#########$##### proc HiLo { {Max 100} } { #: Play the game #set Secret 11 ;# Test set Secret [expr {[random $Max] +1 }] puts "Guess my number (1 .. $Max)" set Try 0 while 1 { incr Try set Guess [ input "Your guess #$Try: " ] ;# Test: Replace "input" with "inputA" if {$Guess < $Secret} { puts "$Guess is too low" } if {$Guess > $Secret} { puts "$Guess is too high" } if {$Guess == $Secret} { puts "$Guess is correct - You needed $Try guesses."; break } if {$Try >= 12} { puts "You won't guess it..."; break } ;# Emergency-break } puts "Bye!" } #########.#########=#########^#########+#########*#########_#########$##### set x 0 ;# Test: starting value for inputA catch {console show} ;# when running in wish: open console-window #HiLo 1024 HiLo ;# default: 100 ---- [HJG] It looks like the biggest problem with this program is the simple [gets] for reading from the user. Even the FAQ at http://www.tcl.tk/man/tcl8.4/TclCmd/gets.htm and the tutorial at [tcltutorial] doesn't have useful information about this... Is there a simpler way for "input" than [gets workaround], e.g. without a gui ? [MG] If you're using wish / Tk and have a GUI, you could have an entry widget where it can entered, and print the messages to a (deactivated, so it can't be altered) text widget. The entry widget would also allow for easy validation of the input - in the above, for instance, you could enter text or other non-numeric data, which would still work as being greater/less than the number in question. [HJG] I'm not sure what you mean, concerning ''gets''. In tclsh84 ''gets'' works fine, but in wish ''gets'' returns an empty string. [LV] What operating system and version of Tcl are you using? My guess is that you are using Windows (or you are launching the Tk application from a menu or launch button where no stdin is available), because I've used gets and Tk together on Solaris and they worked okay if the user started the application up from a console that had stdin and stdout set up. I do remember reading about issues with stdin and stdout on Windows, and needing to ensure that a [console] was open for the user to see the information. I just tried the following: === # in a cygwin ksh xterm $ cat tst.tk #! wish package require Tk console show puts "This is a test" set ans [gets stdin] puts $ans button .e -text Exit -command {exit 0;} $ wish tst.tk This is a test testing testing === On the screen is a Tk console as well as a button . I press the button and the application terminates. So I see the stdout, I type in the stdin and the application sees it. And I see the Tk button. So it all seems to work on this Windows XP system, using ActiveTcl 8.4.10.1. So I would like this behavior of ''gets'' under wish fixed, preferably with something simpler than the [gets workaround] from RS, because GUI-elements in a text-environment look somewhat strange. - [RS] One should always use [tclsh] these days, and [package require] [Tk] where needed. This way, stdin should remain available... [HJG] I tried that, but then scripts which use Tk keep their console window - that does not look good. I cannot get rid of it with "''console hide''", and "''wm withdraw .''" hides the Tk-window. On the page [tclsh vs. wish] I could not find advice about this, and it looks like most scripts here in the wiki use [wish] without "package require Tk". [LV] If you are writing a graphical user interface, then don't use gets to get input from the user - use an [entry] widget or a [text] widget. A version of HiLo with a full GUI is at [HiLo2], and an international version at [HiLo-international] ---- !!!!!! %| [Category Games] |% !!!!!!