Keep guessing
Ask again after a wrong guess, count attempts and reject numbers outside the rules.
A clue needs a next guess. We’ll keep Lucky Number running until the answer is correct, then show how many guesses it took. After that, we’ll make the program enforce its own instructions.
Continue with Give a useful clue,
with the secret restored to 7. Keep that program in memory. If you are
joining here, enter the complete first listing into an empty 48K BASIC program;
the preceding lesson explains numeric input, comparisons and entering THEN.
Return to the question
Add lines 35 and 70. Keep the other lines:
10 LET secret=7
20 PRINT "Guess a whole number 1 to 10"
30 INPUT "Your guess ";g
35 CLS
40 IF g=secret THEN PRINT "Correct!"
50 IF g<secret THEN PRINT "Too low"
60 IF g>secret THEN PRINT "Too high"
70 IF g<>secret THEN GO TO 30
For line 35, type its number and press V for CLS. The screen clears after
we enter a guess, before the new clue appears. The clue stays visible while
the next question waits at the bottom. This keeps repeated guesses from
filling the display with old messages.
Line 70 reads: if the guess is not equal to the secret, go to line 30.
<> means “not equal”. It is a single Spectrum token, so do not enter it as
a separate < followed by >.
To enter line 70, type its number, press U for IF, then type g. Hold
left Option/Alt and press W for <>, then release both keys. Type secret, use
left Option/Alt+G for THEN, release the keys, then press G for GO TO and type
30. Press Enter to store the line. We stay in Host Keyboard mode throughout.
GO TO 30 changes which instruction runs next. Instead of falling off the
end of the listing, BASIC returns to the INPUT line. This repeated route
through the instructions is a loop.
Run it and guess 4, 9, then 7. The first two guesses produce clues
and another question. With 7, line 40 prints Correct!; the condition in line
70 is false, so execution reaches the end and BASIC reports 0 OK.
Foundations: Until You Get It traces a loop
that repeats until an answer is right. Our IF and GO TO express that idea
using numbered lines, rather than pseudocode’s REPEAT … UNTIL.
Does GO TO 30 run lines 10 and 20 again?
No. Execution resumes at line 30. The secret remains in memory, and the
opening instruction is not printed again. GO TO changes the next instruction;
it does not start a fresh run.
Count the accepted guesses
Add lines 15, 36 and 80:
10 LET secret=7
15 LET tries=0
20 PRINT "Guess a whole number 1 to 10"
30 INPUT "Your guess ";g
35 CLS
36 LET tries=tries+1
40 IF g=secret THEN PRINT "Correct!"
50 IF g<secret THEN PRINT "Too low"
60 IF g>secret THEN PRINT "Too high"
70 IF g<>secret THEN GO TO 30
80 PRINT "Guesses: ";tries
Line 15 starts tries at zero: no guesses have been made yet. This is
initialisation, giving a value its starting state. Line 36 reads the old
value, adds one and stores the result back in the same variable. Type the
plus sign with your usual key in Host Keyboard mode.
LET tries=tries+1 is an instruction to update a value, not a claim that two
mathematical expressions are equal. With tries at 2, BASIC calculates 3,
then replaces the stored 2 with 3. Foundations: A Box That Grows From Itself
traces this kind of update one step at a time.
Run with 4, 9, then 7 again. The counts are 1, 2 and 3. Line 80 is
reached only after a correct guess lets execution pass line 70. Its semicolon
joins Guesses: to the value in tries.
Now run again and guess 7 first. Expect Guesses: 1: RUN reaches line
15 and starts a fresh count. The loop goes back to 30, after initialisation,
so later guesses in the same run do not reset it.
If the count is always 1, check that line 70 returns to 30, not 10 or 15. Trace which lines execute before changing anything else.
Enforce the promised range
At present, 11 and 6.5 both count as guesses. We asked for whole numbers from
1 to 10; we should check that before increasing tries or giving a clue.
Add lines 31, 32, 33, 90, 100, 110 and 120:
10 LET secret=7
15 LET tries=0
20 PRINT "Guess a whole number 1 to 10"
30 INPUT "Your guess ";g
31 IF g<1 THEN GO TO 100
32 IF g>10 THEN GO TO 100
33 IF g<>INT g THEN GO TO 100
35 CLS
36 LET tries=tries+1
40 IF g=secret THEN PRINT "Correct!"
50 IF g<secret THEN PRINT "Too low"
60 IF g>secret THEN PRINT "Too high"
70 IF g<>secret THEN GO TO 30
80 PRINT "Guesses: ";tries
90 STOP
100 CLS
110 PRINT "Whole number from 1 to 10"
120 GO TO 30
Lines 31 and 32 reject numbers below 1 or above 10. Either failed range check
sends execution to line 100. Line 33 rejects a fraction using INT:
INT 6.5is 6, so 6.5 is not equal to its integer result.INT 7is 7, so a whole number passes this check unchanged.
An integer is a whole number. INT rounds down to an integer; it does
not round to the nearest one. These positive examples are enough for our
range check. Negative numbers have already been rejected by line 31.
For line 33, enter IF g<> using the same keys as line 70. To insert INT,
press and release Shift+left Option/Alt together, then press R. The shift chord
selects the Spectrum’s extended keyword mode; R then enters INT. Type g
and continue with THEN GO TO 100 using the keyword keys already described.
For line 90, type the number, hold left Option/Alt and press A for STOP, release
both keys, then press Enter. STOP ends execution here. It prevents a successful
round from continuing into the rejection message below.
We now have two routes:
- An accepted guess reaches line 35, clears the screen and increases the count at line 36. The comparisons give their usual clue or success message.
- A rejected number jumps to line 100. That clears the screen, prints the rule and returns to the question. It never reaches the counter or the clues.
We keep the supplied value in g long enough to test it. Writing
LET g=INT g instead would change 6.5 into 6 and silently treat it as a
different guess. Here we ask the player to choose again.
Try the edges
Run the program and enter these answers in order:
| Answer | What should happen | Accepted guesses so far |
|---|---|---|
| 0 | Show the whole-number rule and ask again | 0 |
| 11 | Show the same rule and ask again | 0 |
| 6.5 | Show the same rule and ask again | 0 |
| 1 | Too low |
1 |
| 10 | Too high |
2 |
| 7 | Correct! and Guesses: 3 |
3 |

The final 9 STOP statement report is BASIC confirming that it reached our
STOP. It is not a failure. R enters RUN when you want to start again.
Check a correct first guess too: the result should still be Guesses: 1.
Try several wrong guesses before choosing 7. Each new clue replaces the old
one, rather than eventually producing a scroll? prompt. This version shows
only the latest clue; remembering earlier clues is the player’s job. Keeping
a visible history would be a different design choice.
If line 36 came before the three checks, would 6.5 count?
Yes. The counter would increase before the program discovered that the guess broke the rule. The order matters: validate the value, then count and use it.
These checks act on numeric values that INPUT has accepted. They are not a
general text parser: a word or a malformed expression may still produce a
BASIC input report. A valid expression such as 3+4 produces 7 and counts as
one correct guess. Our game checks the resulting value.
Keep this version
Save with SAVE "lucky", wait for the tape prompt, press Enter and wait for
0 OK. Export the recording to lucky.tap. When reopening it, use
LOAD "lucky" so an earlier recording is not mistaken for this program.
Remember a name; keep the program
explains the export and tape controls. After loading, try 0, 4 and 7: the
finished count should be 2.
The secret is still visible in line 10. That has let us test the clues, loop and count with predictable results. Choose a new secret lets the Spectrum choose within the same range.
Sources
Steven Vickers, edited by Robin Bradbeer, ZX Spectrum BASIC Programming,
second edition (Sinclair Research, 1983), chapter 1 (keyboard modes), chapter 2
(GO TO, input and variables), chapter 3, pp. 25–27 (comparisons and STOP),
chapter 9, p. 59 (INT), chapter 15 (CLS and display areas), and chapter 20
(named tape programs).