Guess the number/With feedback (player): Difference between revisions

From Rosetta Code
Content added Content deleted
No edit summary
(Go solution)
Line 208: Line 208:
My guess is: 57 Score(h, l or c)?: c
My guess is: 57 Score(h, l or c)?: c
I solved it!</pre>
I solved it!</pre>
=={{header|Go}}==
<lang go>
package main

import (
"bufio"
"fmt"
"os"
)

func main() {
lower, upper := 1, 100
fmt.Printf(`Instructions:
Think of integer number from %d to %d and I will guess it.
After each guess, you respond with l,h,or c depending on
if my guess was too low, too high, or correct.
Press enter when you are thinking of a number. `, lower, upper)
in := bufio.NewReader(os.Stdin)
in.ReadString('\n')
for {
guess := (upper+lower)/2
fmt.Printf("My guess: %d (l/h/c) ", guess)
s, err := in.ReadString('\n')
if err != nil {
fmt.Println("\nSo, bye.")
return
}
switch s {
case "l\n":
lower = guess + 1
case "h\n":
upper = guess - 1
case "c\n":
fmt.Println("I did it. :)")
return
default:
fmt.Println("Please respond by pressing l, h, or c")
}
}
}
</lang>


=={{header|J}}==
=={{header|J}}==

Revision as of 21:29, 6 January 2011

Task
Guess the number/With feedback (player)
You are encouraged to solve this task according to the task description, using any language you may know.

The task is to write a player for the game that follows the following rules:

The scorer will choose a number between set limits. The computer player will print a guess of the target number. The computer asks for a score of whether its guess is higher than, lower than, or equal to the target. The computer guesses, and the scorer scores, in turn, until the computer correctly guesses the target number.

The computer should guess intelligently based on the accumulated scores given. One way is to use a binary search based algorithm.

C.f: Guess the number/With Feedback, Bulls and cows/Player

Ada

<lang Ada>with Ada.Text_IO; procedure Guess_Number_Player is

  procedure Guess_Number (Lower_Limit : Integer; Upper_Limit : Integer) is
     type Feedback is (Lower, Higher, Correct);
     package Feedback_IO is new Ada.Text_IO.Enumeration_IO (Feedback);
     My_Guess : Integer := Lower_Limit + (Upper_Limit - Lower_Limit) / 2;
     Your_Feedback : Feedback;
  begin
     Ada.Text_IO.Put_Line ("Think of a number!");
     loop
        Ada.Text_IO.Put_Line ("My guess: " & Integer'Image (My_Guess));
        Ada.Text_IO.Put ("Your answer (lower, higher, correct): ");
        Feedback_IO.Get (Your_Feedback);
        exit when Your_Feedback = Correct;
        if Your_Feedback = Lower then
           My_Guess := Lower_Limit + (My_Guess - Lower_Limit) / 2;
        else
           My_Guess := My_Guess + (Upper_Limit - My_Guess) / 2;
        end if;
     end loop;
     Ada.Text_IO.Put_Line ("I guessed well!");
  end Guess_Number;
  package Int_IO is new Ada.Text_IO.Integer_IO (Integer);
  Lower_Limit : Integer;
  Upper_Limit : Integer;

begin

  loop
     Ada.Text_IO.Put ("Lower Limit: ");
     Int_IO.Get (Lower_Limit);
     Ada.Text_IO.Put ("Upper Limit: ");
     Int_IO.Get (Upper_Limit);
     exit when Lower_Limit < Upper_Limit;
     Ada.Text_IO.Put_Line ("Lower limit must be lower!");
  end loop;
  Guess_Number (Lower_Limit, Upper_Limit);

end Guess_Number_Player;</lang>

AutoHotkey

Works with the AutoHotkey entry at: http://rosettacode.org/wiki/Guess_the_number/With_feedback

<lang AutoHotkey>MaxGuesses = 50

GetParams(LowerBound,UpperBound) If Not GuessNum(LowerBound,UpperBound,MaxGuesses)

MsgBox, 16, Error, Could not guess number within %MaxGuesses% guesses.

GetParams(ByRef LowerBound,ByRef UpperBound) {

WinWait, Number Guessing ahk_class #32770
Sleep, 100
WinGet, InputID, ID
ControlGetText, Temp1, Static1, ahk_id %InputID%
Temp2 := InStr(Temp1,A_Space,False,32)
LowerBound := SubStr(Temp1,31,Temp2 - 31)
UpperBound := SubStr(Temp1,Temp2 + 5,-1)

}

GuessNum(LowerBound,UpperBound,MaxGuesses) {

Loop, %MaxGuesses%
{
 Guess := LowerBound + ((UpperBound - LowerBound) // 2)
 Temp1 := SendGuess(Guess)
 ToolTip % Temp1
 If Temp1 = Too Low
  LowerBound = %Guess%
 Else If Temp1 = Too High
  UpperBound = %Guess%
 Else
  Return, 1
}

}

SendGuess(Guess) {

WinGet, InputID, ID, Number Guessing ahk_class #32770
ControlSetText, Edit1, %Guess%, ahk_id %InputID%
ControlSend, Button1, {Enter}, ahk_id %InputID%
Loop
{
 Sleep, 50
 IfWinExist, Correct ahk_class #32770
  Return
 Else IfWinExist, Incorrect ahk_class #32770
  Break
}
ControlGetText, Temp1, Static2
WinClose
WinWaitClose
IfInString, Temp1, low
 Return, "Too Low"
Else
 Return, "Too High"

}</lang>

Clojure

{trans|Python} <lang Clojure>(defn guessgame []

 (def inclusive-range [1 100])
 (def difference (apply - (reverse inclusive-range)))
 (def target (+ (first inclusive-range) (rand-int difference)))
 (defn getguess [i]
   (printf "Your guess (%d):" i)
   (read))
 (do 
  (printf "Guess my target number that is inside %s (inclusive).\n" inclusive-range)
  (loop [i 1]
     (let [guess (getguess i)]

(if (== guess target) (do (println "Correct") (println "Thanks for playing.")) (do (cond (not (number? guess)) (printf "Your input of '%s' is not a number.\n" guess) (or (< guess (first inclusive-range) (> guess (second inclusive-range)))) (println " Out of range!") (< guess target) (println " Too low.") (> guess target) (println " Too high.")) (recur (inc i))))))))</lang> Output

user=> (guessgame)
1
Guess my target number that is inside [1 100] (inclusive). 
Your guess (1): Too low.
99
Your guess (2): Too high.
50
Your guess (3): Too high.
25
Your guess (4): Too low.
35
Your guess (5): Too low.
40
Your guess (6): Too high.
37
Your guess (7): Too low.
38
Your guess (8):Correct
Thanks for playing.
nil

Fortran

Works with: Fortran version 95 and later

<lang fortran>program Guess_a_number_Player

 implicit none
 
 integer, parameter :: limit = 100
 integer :: guess, mx = limit, mn = 1
 real :: rnum
 character(1) :: score
 
 write(*, "(a, i0, a)") "Think of a number between 1 and ", limit, &
                        " and I will try to guess it." 
 write(*, "(a)")  "You score my guess by entering: h if my guess is higher than that number"
 write(*, "(a)")  "                                l if my guess is lower than that number"
 write(*, "(a/)") "                                c if my guess is the same as that number"
 call random_seed
 call random_number(rnum)
 guess = rnum * limit + 1
 do
   write(*, "(a, i0, a,)", advance='no') "My quess is: ", guess, "   Score(h, l or c)?: "
   read*, score
   select case(score)
     case("l", "L")
       mn = guess
       guess = (mx-guess+1) / 2 + mn 
       
     case("h", "H")
       mx = guess
       guess = mx - (guess-mn+1) / 2 
     case("c", "C")
       write(*, "(a)") "I solved it!"
       exit
     case default
       write(*, "(a)") "I did not understand that"
   end select
 end do

end program</lang> Output

Think of a number between 1 and 100 and I will try to guess it.
You score my guess by entering: h if my guess is higher than that number
                                l if my guess is lower than that number
                                c if my guess is the same as that number

My guess is: 58   Score(h, l or c)?: h
My guess is: 29   Score(h, l or c)?: l
My guess is: 44   Score(h, l or c)?: l 
My guess is: 51   Score(h, l or c)?: l 
My guess is: 55   Score(h, l or c)?: l 
My guess is: 57   Score(h, l or c)?: c
I solved it!

Go

<lang go> package main

import (

   "bufio"
   "fmt"
   "os"

)

func main() {

   lower, upper := 1, 100
   fmt.Printf(`Instructions:

Think of integer number from %d to %d and I will guess it. After each guess, you respond with l,h,or c depending on if my guess was too low, too high, or correct. Press enter when you are thinking of a number. `, lower, upper)

   in := bufio.NewReader(os.Stdin)
   in.ReadString('\n')
   for {
       guess := (upper+lower)/2
       fmt.Printf("My guess: %d (l/h/c) ", guess)
       s, err := in.ReadString('\n')
       if err != nil {
           fmt.Println("\nSo, bye.")
           return
       }
       switch s {
       case "l\n":
           lower = guess + 1
       case "h\n":
           upper = guess - 1
       case "c\n":
           fmt.Println("I did it. :)")
           return
       default:
           fmt.Println("Please respond by pressing l, h, or c")
       }
   }

} </lang>

J

<lang j>require 'misc' guess=:3 :0

 'lo hi'=.y
 while.lo < hi do.
   smoutput 'guessing a number between ',(":lo),' and ',":hi
   guess=.lo+?hi-lo
   select.{.deb tolower prompt 'is it ',(":guess),'? '
     case.'y'do. smoutput 'Win!' return.
     case.'l'do. lo=.guess+1
     case.'h'do. hi=.guess-1
     case.'q'do. smoutput 'giving up' return.
     case.   do. smouput 'options: yes, low, high, quit'
   end.
 end.

)</lang>

Example session:

<lang> guess 1 100 guessing a number between 1 and 100 is it 86? hi guessing a number between 1 and 85 is it 56? hi guessing a number between 1 and 55 is it 24? lo guessing a number between 25 and 55 is it 29? lo guessing a number between 30 and 55 is it 43? lo guessing a number between 44 and 55 is it 53? hi guessing a number between 44 and 52 is it 51? hi guessing a number between 44 and 50 is it 48? lo guessing a number between 49 and 50 is it 49? lo 50</lang>

This could be made more efficient by replacing guess=.lo+?hi-lo with guess=.<.-:lo+hi. (The above example would have finished on the first guess, but the range 1..100 would never take more than 6 guesses -- the remaining answers would be determined after six guesses.)

PARI/GP

<lang PARI/GP> guessnumber2(b)={ my(c=0,d=b,a=0); for(x=1,b,

   for(y=1,b,
       if(a<c||a==c||a==d||a>d,
          a=random(b),
          break()
         )
    );
    print("I guess "a" am I h,l,or e ?");
    g=input();
    if(g==h,
    d=a,
    if(g==l,
       c=a,
       if(g==e,
          break()
       )
    )
 )
);

} </lang>

PicoLisp

Translation of: PureBasic

<lang PicoLisp>(de guessTheNumber (Min Max)

  (prinl "Think of a number between " Min " and " Max ".")
  (prinl "On every guess of mine you should state whether my guess was")
  (prinl "too high, too low, or equal to your number by typing 'h', 'l', Or '='")
  (use Guess
     (loop
        (NIL (> Max Min)
           (prinl "I think somthing is strange here...") )
        (prin
           "My guess is "
           (setq Guess (+ Min (/ (- Max Min) 2)))
           ",is this correct? " )
        (flush)
        (NIL
           (case (uppc (car (line)))
              ("H" (setq Max Guess))
              ("L" (setq Min Guess))
              ("=" (nil (prinl "I did it!")))
              (T (prinl "I do not understand that...")) ) ) ) ) )</lang>

Output:

: (guessTheNumber 1 99)
Think of a number between 1 and 99.
On every guess of mine you should state whether my guess was
too high, too low, or equal to your number by typing 'h', 'l', Or '='
My guess is 50,is this correct? h
My guess is 25,is this correct? h
My guess is 13,is this correct? l
My guess is 19,is this correct? l
My guess is 22,is this correct? =
I did it!

PureBasic

<lang PureBasic>min=0 max=100

If OpenConsole()

 PrintN("Think of a number between "+Str(min)+" and "+Str(max)+".")
 PrintN("On every guess of mine you should state whether my guess was")
 PrintN("too high, too low, or equal to your number by typing 'h', 'l', Or '='")
 Repeat
   If max<=min
     PrintN("I think somthing is strange here...")
     Break
   EndIf
   Guess=(max-min)/2+min
   Print("My guess is "+Str(Guess)+",is this correct? "): Respons.s=UCase(Input())
   If Respons="H":     min=Guess
   ElseIf Respons="L": max=Guess
   ElseIf Respons="="
     PrintN("I did it!")
     Break
   Else
     PrintN("I do not understand that...")
   EndIf
 ForEver

EndIf</lang>

Python

<lang python>inclusive_range = mn, mx = (1, 10)

print(\ Think of a number between %i and %i and wait for me to guess it. On every guess of mine you should state whether the guess was too high, too low, or equal to your number by typing h, l, or =  % inclusive_range)

i = 0 while True:

   i += 1
   guess = (mn+mx)//2
   txt = input("Guess %2i is: %2i. The score for which is (h,l,=): "
               % (i, guess)).strip().lower()[0]
   if txt not in 'hl=':
       print("  I don't understand your input of '%s' ?" % txt)
       continue
   if txt == 'h':
       mx = guess-1
   if txt == 'l':
       mn = guess+1
   if txt == '=':
       print("  Ye-Haw!!")
       break
   if (mn > mx) or (mn < inclusive_range[0]) or (mx > inclusive_range[1]):
       print("Please check your scoring as I cannot find the value")
       break
       

print("\nThanks for keeping score.")</lang>

Sample Game-play

Think of a number between 1 and 10 and wait for me to guess it.
On every guess of mine you should state whether the guess was
too high, too low, or equal to your number by typing h, l, or =

Guess  1 is:  5. The score for which is (h,l,=): l
Guess  2 is:  8. The score for which is (h,l,=): l
Guess  3 is:  9. The score for which is (h,l,=): l
Guess  4 is: 10. The score for which is (h,l,=): =
  Ye-Haw!!

Thanks for keeping score.

REXX

<lang rexx> /*REXX program to play guess-the-number (with itself!). */

parse arg low high . /*let them choose the range.*/ if low== then low=1 if high== then high=1000

?=random(low,high)

say info="Try to guess my number (it's between" low 'and',

    high" inclusive)."
 do j=1
 say info
 say
 call guesser
   select
   when guess>? then info=right("It's too high.",40)
   when guess<? then info=right("It's too low. ",40)
   otherwise leave
   end
 end

say say 'Congratulations! You guessed the secret number in' j "tries." say exit


guesser: upper info if \datatype(newlow ,'N') then newlow =low if \datatype(newhigh,'N') then newhigh=high oldGuess=guess if pos('HIGH',info)\==0 then newhigh=guess if pos('LOW' ,info)\==0 then newlow =guess guess=newlow+(newhigh-newlow)%2 if guess==oldguess then guess=guess+1 say 'My guess is' guess return </lang> Output shown is from playing several games:


Try to guess my number  (it's between 1 and 1000 inclusive).

My guess is 500
                          It's too low.

My guess is 750
                          It's too low.

My guess is 875
                          It's too high.

My guess is 812
                          It's too low.

My guess is 843
                          It's too high.

My guess is 827
                          It's too high.

My guess is 819
                          It's too low.

My guess is 823
                          It's too low.

My guess is 825

Congratulations!  You guessed the secret number in 9 tries.

_________________________________________________________________


Try to guess my number  (it's between 1 and 1000 inclusive).

My guess is 500
                          It's too high.

My guess is 250
                          It's too high.

My guess is 125
                          It's too high.

My guess is 63
                          It's too high.

My guess is 32
                          It's too low.

My guess is 47
                          It's too low.

My guess is 55
                          It's too low.

My guess is 59
                          It's too high.

My guess is 57
                          It's too low.

My guess is 58

Congratulations!  You guessed the secret number in 10 tries.

_________________________________________________________________


Try to guess my number  (it's between 1 and 1000 inclusive).

My guess is 500
                          It's too high.

My guess is 250
                          It's too low.

My guess is 375
                          It's too high.

My guess is 312
                          It's too low.

My guess is 343
                          It's too low.

My guess is 359
                          It's too high.

My guess is 351

Congratulations!  You guessed the secret number in 7 tries.

_________________________________________________________________


Try to guess my number  (it's between 1 and 1000 inclusive).

My guess is 500
                          It's too low.

My guess is 750
                          It's too high.

My guess is 625
                          It's too low.

My guess is 687
                          It's too high.

My guess is 656

Congratulations!  You guessed the secret number in 5 tries.

_________________________________________________________________


Try to guess my number  (it's between 1 and 1000 inclusive).

My guess is 500
                          It's too high.

My guess is 250
                          It's too high.

My guess is 125

Congratulations!  You guessed the secret number in 3 tries.

Tcl

<lang tcl>set from 1 set to 10 fconfigure stdout -buffering none while 1 {

   set guess [expr {($from+$to) / 2}]
   puts -nonewline "Guess: $guess\tWas it lower (<) equal (=) or higher (>)? "
   switch -- [gets stdin] {

< { set from [expr {$guess + 1}] } > { set to [expr {$guess - 1}] } = { puts "Found it: $guess" break } default { puts "What sort of a response was that?!" }

   }
   if {$to < $from} {

puts "No answer possible?!" break

   }

}</lang> Sample run:

Guess: 5	Was it lower (<) equal (=) or higher (>)? <
Guess: 8	Was it lower (<) equal (=) or higher (>)? >
Guess: 6	Was it lower (<) equal (=) or higher (>)? =
Found it: 6