**Summary**
[HJG] '''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.
**Code**
----
======tcl
#! /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
======
----
**Comments**
A version of HiLo with a full GUI is at [HiLo2],
and an international version (using msgcat) at [HiLo-international].
[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.
----
<> Games | Tcl/Tk games