All right, here's another one of the series of hypothetically pedagogical text games in Go. This one is based on the original Bagels, which I then appropriated as Pretzels.
Here's the code:
package main
import (
"fmt"
"math/rand"
"time"
)
const (
minRange = 100
maxRange = 999
numDigits = 3
maxTries = 20
)
const (
picoStr = " -- PICO -- "
fermiStr = " -- FERMI -- "
pretzelStr = " -- PRETZEL -- "
)
func showIntro() {
fmt.Println("\nWelcome to 'PRETZELS' !!")
fmt.Println("------------------------")
fmt.Println(
"\nHere are the rules. I'm going to guess a THREE-DIGIT number, and then " +
"you have to guess it. I will give you clues as follows: \n" +
" PICO -- you got one digit correct, BUT in the wrong position\n" +
" FERMI -- you got on digit correct, AND in the right position\n" +
"PRETZEL -- you got NO digits correct.\n")
fmt.Printf("You get %d chances to guess it!\n\n", maxTries)
}
func getDigits(num int, digits []int) {
var i int
for {
digits[i] = num % 10
i++
num /= 10
if num == 0 {
break
}
}
}
func showFeedback(targetDigits []int, guess int) {
guessDigits := make([]int, numDigits)
getDigits(guess, guessDigits)
somethingMatched := false
for i := 0; i < len(guessDigits); i++ {
if guessDigits[i] == targetDigits[i] {
fmt.Printf(fermiStr)
somethingMatched = true
continue
}
for j := 0; j < len(targetDigits); j++ {
if guessDigits[i] == targetDigits[j] {
fmt.Printf(picoStr)
somethingMatched = true
break
}
}
}
if !somethingMatched {
fmt.Printf(pretzelStr)
}
fmt.Println()
}
func main() {
showIntro()
rand.Seed(time.Now().Unix())
target := minRange + rand.Intn(maxRange-minRange)
targetDigits := make([]int, numDigits)
getDigits(target, targetDigits)
var numTries int
for {
fmt.Printf("\nWhat is Guess #%d ? ", numTries+1)
var guess int
fmt.Scan(&guess)
if guess < minRange || guess > maxRange {
fmt.Printf("You MUST choose a number between %d and %d, try again ...\n\n", minRange, maxRange)
continue
}
showFeedback(targetDigits, guess)
if guess == target {
fmt.Println("\nYou got it!!\n")
break
}
if numTries > maxTries {
fmt.Println("\nOOPS ... you ran out of chances! :(\n")
fmt.Printf("(The number I thought of was %d)\n\n", target)
break
}
numTries++
}
fmt.Println("\n\n ... these pretzels are making me thirsty! ...\n")
}
and here's the eye-watering original:
5 PRINT TAB(33);"BAGELS"
10 PRINT TAB(15);"CREATIVE COMPUTING MORRISTOWN, NEW JERSEY":PRINT:PRINT
15 REM *** BAGLES NUMBER GUESSING GAME
20 REM *** ORIGINAL SOURCE UNKNOWN BUT SUSPECTED TO BE
25 REM *** LAWRENCE HALL OF SCIENCE, U.C. BERKELY
30 DIM A1(6),A(3),B(3)
40 Y=0:T=255
50 PRINT:PRINT:PRINT
70 INPUT "WOULD YOU LIKE THE RULES (YES OR NO)";A$
90 IF LEFT$(A$,1)="N" THEN 150
100 PRINT:PRINT "I AM THINKING OF A THREE-DIGIT NUMBER. TRY TO GUESS"
110 PRINT "MY NUMBER AND I WILL GIVE YOU CLUES AS FOLLOWS:"
120 PRINT " PICO - ONE DIGIT CORRECT BUT IN THE WRONG POSITION"
130 PRINT " FERMI - ONE DIGIT CORRECT AND IN THE RIGHT POSITION"
140 PRINT " BAGELS - NO DIGITS CORRECT"
150 FOR I=1 TO 3
160 A(I)=INT(10*RND(1))
165 IF I-1=0 THEN 200
170 FOR J=1 TO I-1
180 IF A(I)=A(J) THEN 160
190 NEXT J
200 NEXT I
210 PRINT:PRINT "O.K. I HAVE A NUMBER IN MIND."
220 FOR I=1 TO 20
230 PRINT "GUESS #";I,
240 INPUT A$
245 IF LEN(A$)<>3 THEN 630
250 FOR Z=1 TO 3:A1(Z)=ASC(MID$(A$,Z,1)):NEXT Z
260 FOR J=1 TO 3
270 IF A1(J)<48 THEN 300
280 IF A1(J)>57 THEN 300
285 B(J)=A1(J)-48
290 NEXT J
295 GOTO 320
300 PRINT "WHAT?"
310 GOTO 230
320 IF B(1)=B(2) THEN 650
330 IF B(2)=B(3) THEN 650
340 IF B(3)=B(1) THEN 650
350 C=0:D=0
360 FOR J=1 TO 2
370 IF A(J)<>B(J+1) THEN 390
380 C=C+1
390 IF A(J+1)<>B(J) THEN 410
400 C=C+1
410 NEXT J
420 IF A(1)<>B(3) THEN 440
430 C=C+1
440 IF A(3)<>B(1) THEN 460
450 C=C+1
460 FOR J=1 TO 3
470 IF A(J)<>B(J) THEN 490
480 D=D+1
490 NEXT J
500 IF D=3 THEN 680
505 IF C=0 THEN 545
520 FOR J=1 TO C
530 PRINT "PICO ";
540 NEXT J
545 IF D=0 THEN 580
550 FOR J=1 TO D
560 PRINT "FERMI ";
570 NEXT J
580 IF C+D<>0 THEN 600
590 PRINT "BAGELS";
600 PRINT
605 NEXT I
610 PRINT "OH WELL."
615 PRINT "THAT'S TWNETY GUESSES. MY NUMBER WAS";100*A(1)+10*A(2)+A(3)
620 GOTO 700
630 PRINT "TRY GUESSING A THREE-DIGIT NUMBER.":GOTO 230
650 PRINT "OH, I FORGOT TO TELL YOU THAT THE NUMBER I HAVE IN MIND"
660 PRINT "HAS NO TWO DIGITS THE SAME.":GOTO 230
680 PRINT "YOU GOT IT!!!":PRINT
690 Y=Y+1
700 INPUT "PLAY AGAIN (YES OR NO)";A$
720 IF LEFT$(A$,1)="YES" THEN 150
730 IF Y=0 THEN 750
740 PRINT:PRINT "A";Y;"POINT BAGELS BUFF!!"
750 PRINT "HOPE YOU HAD FUN. BYE."
999 END
And just to show how much fun this is (copy-paste and try it!), here's a sample run:
$ go run pretzels.go
Welcome to 'PRETZELS' !!
------------------------
Here are the rules. I'm going to guess a THREE-DIGIT number, and then you have to guess it. I will give you clues as follows:
PICO -- you got one digit correct, BUT in the wrong position
FERMI -- you got on digit correct, AND in the right position
PRETZEL -- you got NO digits correct.
You get 20 chances to guess it!
What is Guess #1 ? 123
-- PRETZEL --
What is Guess #2 ? 456
-- PICO --
What is Guess #3 ? 789
-- PICO -- -- PICO --
What is Guess #4 ? 100
-- PRETZEL --
What is Guess #5 ? 987
-- PICO -- -- PICO --
What is Guess #6 ? 8797
You MUST choose a number between 100 and 999, try again ...
What is Guess #6 ? 897
-- FERMI -- -- FERMI --
What is Guess #7 ? 894
-- FERMI -- -- FERMI -- -- FERMI --
You got it!!
... these pretzels are making me thirsty! ...