Choose a new secret
Turn a random fraction into a whole number, then test the range.
Knowing that the secret is 7 makes testing easy. It also makes the game rather short. We’ll let the Spectrum choose the secret while keeping the same useful clues.
Continue with the final listing from Keep guessing. If you are joining here, start Emu198x in the 48K setup and enter the complete first listing into an empty program. That preceding lesson explains the comparison, counting and validation lines retained here.
From a fraction to a secret
Replace line 10. Everything else stays as it was:
10 LET secret=INT (RND*10)+1
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
RND produces a pseudo-random number: a value drawn from a calculated sequence.
It can be zero but is always less than 1. The sequence is useful for games;
it is not a source of secure passwords.
Read the expression from the inside out:
| Operation | Possible results |
|---|---|
RND |
From 0 up to, but not including, 1 |
RND*10 |
From 0 up to, but not including, 10 |
INT (RND*10) |
Whole numbers 0 through 9 |
INT (RND*10)+1 |
Whole numbers 1 through 10 |
The star means multiplication. Parentheses keep the multiplication inside INT;
the final addition shifts the whole range up by one. For an illustrative value
of 0.73, these steps give 7.3, then 7, then 8.
To enter line 10, type its number, press L for LET, then type secret=.
Press and release Shift+left Option/Alt, then R for INT.
Type (, use Shift+left Option/Alt, then T for RND, and type *10)+1.
Host Keyboard mode supplies the punctuation from your usual keys.
Run the game. Use its clues to find the secret. Line 10 runs once at the start; the wrong-guess loop returns to line 30, so it does not change the answer midway. A fresh run chooses another value, which may happen to be the same one.
Foundations: Until You Get It uses the convenient
pseudocode RANDOM 1 TO 10. Here we have built that range from the functions
Sinclair BASIC actually provides.
What would happen if we left off the final +1?
The program would choose from 0 through 9. It would sometimes choose 0, while line 31 rejects every guess below 1. That round would be impossible to win. The instructions, random range and validation must agree.
Choose where the sequence begins
Add line 5:
5 RANDOMIZE
10 LET secret=INT (RND*10)+1
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
Press T after the line number for RANDOMIZE; the Spectrum keyboard labels it
RAND. This statement chooses a starting place in the sequence using the
machine’s running frame counter. RND then obtains successive values from that
sequence. They have different jobs.
We seed the sequence once at the beginning, rather than repeatedly restarting it while the player guesses. Restarting a machine in the same state and following the same timings can still repeat results. Random selection also permits the same number twice: a repeated answer is not by itself a fault.
For a repeatable test, temporarily replace line 5 with 5 RANDOMIZE 1.
Run twice and guess 1 first each time. Both runs should succeed in one guess.
This fixed starting value, called a seed, makes a fault easier to reproduce.
Restore 5 RANDOMIZE afterwards.
Test what chance can hide
Temporarily replace line 10 with 10 LET secret=1. Try 0, then 1: 0 should be
rejected, and 1 should win in one counted guess. Repeat with secret 10, testing
11 before 10. These deliberate test values check both ends of the game’s range.
Restore the random line from the listing when finished.
You can inspect individual generated secrets after a completed game with the
unnumbered command PRINT secret. Run and play several times. Values outside
1–10 would show a bug; a short run of values inside the range does not prove
that every outcome is equally likely.
To experiment with 1–100, change the multiplier in line 10, the limit in line 32, and the instructions in lines 20 and 110 together. More possible numbers mean more room for clues to help, but also a longer game. Keep 1–10 for our next lesson.
Next, Feedback and another round continues this program.
Sources
Steven Vickers, edited by Robin Bradbeer, ZX Spectrum BASIC Programming, second edition (Sinclair Research, 1983), chapter 11, “Random numbers”, pp. 73–75; appendix C, INT.