Skip to content
Game 1

Grow a new round

Choose a random first item, preserve the sequence across successful rounds and end a finite challenge with an accurate score.

A fixed order is useful for checking the game, but soon becomes familiar. We’ll choose a new first item, then add one choice after each successful round. The beginning must stay the same: learning the growing order is the challenge.

Continue from the fixed-order game, with line 280 restored to s$="314". The input, rendering and comparison routines already do the jobs we need. We’ll change when the sequence is created and extended, and give the score a precise meaning: rounds completed.

Keyboard notes for this lesson

In extended mode, T gives RND, R gives INT, and Y gives STR$. Left Option/Alt+B gives *.

Choose one item, then count a completed round

Replace 280, 1160, 1170 and 1820. Add 285, 1180, 1190 and 1830:

280 LET s$=STR$ (INT (RND*4)+1)
285 LET done=0
1160 LET done=done+1
1170 PRINT AT 18,0;"Order complete.               "
1180 PRINT AT 19,0;"Rounds completed: ";done
1190 STOP
1820 PRINT AT 19,0;"Rounds completed: ";done
1830 STOP

The new expression at 280 combines operations in a useful order:

Expression What it supplies
RND A pseudo-random number from 0 up to, but not including, 1
RND*4 A number from 0 up to, but not including, 4
INT (RND*4) One of the whole numbers 0, 1, 2, 3
INT (RND*4)+1 One of our panel numbers 1, 2, 3, 4
STR$ (INT (RND*4)+1) Its text form: "1", "2", "3" or "4"

The brackets after STR$ make the complete numeric expression its input.

For these non-negative values, INT discards the fractional part. More generally it gives the greatest integer no larger than its input: negative values need that fuller definition. Adding 1 moves the four possible results to our four identifiers. STR$ turns the resulting number into text for s$. We keep numeric operations inside and convert only after they are finished.

If RND supplied 0.74, which panel would we choose?

Show the explanation

Multiplying by 4 gives 2.96. INT gives 2, then adding 1 gives panel 3. STR$ supplies the character "3". The intermediate 2 is not yet the panel number; the range shift still has to happen.

The Spectrum generates its pseudo-random values by calculation. A repeated choice is allowed and does not by itself show that the generator has failed. We do not reject equal neighbours: recognising two separate signals on the same panel is part of the game.

Line 285 starts done at 0. A wrong answer reaches the failure block without changing it. A fully correct response reaches 1160, which adds 1, then prints the result. The two outcomes use the same wording, Rounds completed:.

Run this checkpoint several times. Each run presents one choice. Repeat it correctly to see 1 completed round; choose a different valid panel to see 0. An unrelated key still changes neither the sequence nor the count. Several runs may choose the same panel, and a short sample cannot establish how evenly the generator distributes choices.

Complete one-random-choice checkpoint
10 BORDER 0
20 PAPER 0
30 INK 7
40 CLS
50 PRINT "BRIGHT SPARK"
100 LET lit=0
110 FOR p=1 TO 4
120 GO SUB 500
130 NEXT p
240 PRINT AT 2,7;"1"
250 PRINT AT 2,23;"2"
260 PRINT AT 11,7;"3"
270 PRINT AT 11,23;"4"
275 PRINT AT 20,0;"1-4 choose. Hold q to quit."
280 LET s$=STR$ (INT (RND*4)+1)
285 LET done=0
290 GO TO 1000
500 LET pr=3
510 LET pc=2
520 LET colour=2
530 LET inkcol=7
540 LET note=0
550 IF p=2 THEN LET pc=18
560 IF p=2 THEN LET colour=1
570 IF p=2 THEN LET note=4
580 IF p=3 THEN LET pr=12
590 IF p=3 THEN LET colour=4
600 IF p=3 THEN LET inkcol=0
610 IF p=3 THEN LET note=7
620 IF p=4 THEN LET pr=12
630 IF p=4 THEN LET pc=18
640 IF p=4 THEN LET colour=6
650 IF p=4 THEN LET inkcol=0
660 IF p=4 THEN LET note=12
670 PAPER colour
680 INK inkcol
690 BRIGHT lit
700 FOR r=pr TO pr+5
710 PRINT AT r,pc;"            "
720 NEXT r
770 IF lit=1 THEN PRINT AT pr+2,pc+5;"*"
780 PAPER 0
790 INK 7
800 BRIGHT 0
810 RETURN
900 LET lit=1
910 GO SUB 500
920 BEEP 0.15,note
930 LET lit=0
940 GO SUB 500
950 PAUSE 10
960 RETURN
1000 PRINT AT 18,0;"WATCH                         "
1010 FOR i=1 TO LEN s$
1020 IF INKEY$="q" THEN GO TO 1900
1030 LET p=VAL s$(i)
1040 GO SUB 900
1050 NEXT i
1060 IF INKEY$="q" THEN GO TO 1900
1070 PRINT AT 18,0;"Release the keys.              "
1080 GO SUB 1600
1090 PRINT AT 18,0;"YOUR TURN                     "
1100 FOR i=1 TO LEN s$
1110 GO SUB 1500
1120 GO SUB 900
1130 GO SUB 1600
1140 IF k$<>s$(i) THEN GO TO 1800
1150 NEXT i
1160 LET done=done+1
1170 PRINT AT 18,0;"Order complete.               "
1180 PRINT AT 19,0;"Rounds completed: ";done
1190 STOP
1500 LET k$=INKEY$
1510 IF k$="" THEN GO TO 1500
1520 IF k$="q" THEN GO TO 1900
1530 IF k$<"1" THEN GO TO 1580
1540 IF k$>"4" THEN GO TO 1580
1550 LET p=VAL k$
1560 RETURN
1580 GO SUB 1600
1590 GO TO 1500
1600 LET a$=INKEY$
1610 IF a$="q" THEN GO TO 1900
1620 IF a$<>"" THEN GO TO 1600
1630 RETURN
1800 PRINT AT 18,0;"Different choice.             "
1810 BEEP 0.1,-12
1820 PRINT AT 19,0;"Rounds completed: ";done
1830 STOP
1900 PRINT AT 18,0;"Finished. RUN to try again.     "
1910 PRINT AT 21,0;"                               "
1920 STOP

Extend after success, with an ending in reach

Start from an empty order once per game. Before the first round, append one choice. After each completed round, append another—unless the challenge is already complete.

Replace 280, 290, 1170 and 1180. Delete 1190. Add 287, 980, 990 and 1850–1870:

280 LET s$=""
287 LET cap=16
290 GO TO 980
980 LET s$=s$+STR$ (INT (RND*4)+1)
990 PRINT AT 19,0;"Rounds completed: ";done
1170 IF done=cap THEN GO TO 1850
1180 GO TO 980
1850 PRINT AT 18,0;"Challenge complete.           "
1860 PRINT AT 19,0;"Rounds completed: ";done
1870 STOP

The double quotes at 280 contain no spaces: this is the empty string. Line 285 still sets done=0, and cap=16 names the number of rounds needed to finish. These three values are initialised before line 290 jumps to 980.

Line 980 joins one newly chosen digit to the existing s$. It performs the append we tested with a literal in lesson 3, now using STR$ to obtain the new character. The first append changes an empty string into a one-item order, so playback never tries to traverse an empty sequence.

After the score display at 990, execution reaches WATCH at 1000. Successful comparison reaches done=done+1. If done=cap, line 1170 jumps to the success block. Otherwise line 1180 jumps back to 980, preserving the existing sequence and completed count.

It must not jump to 280. That would erase both before every new round, leaving the player repeating isolated one-item challenges forever.

Event Stored order, using an example choice sequence done
Initialise Empty 0
Append first item "3" 0
Repeat 3 correctly "3" 1
Append another item "31" 1
Repeat 3, 1 correctly "31" 2
Append another item "314" 2
Choose 3, then the wrong panel "314" 2

These example choices explain the state changes; your random choices will vary. The completed count advances only after the whole response loop ends. Getting several items right in a failed round does not complete that round.

Check the last round before making another one

The order of lines 1160–1180 matters. Increment the completed count, check the cap, then decide whether to append. After round 16 succeeds, done becomes 16 and the jump goes straight to Challenge complete.. No seventeenth item is created or played.

Sixteen is our chosen finishing point, not a limit of Spectrum strings or a claim about anyone’s memory. We could choose another positive whole-number cap. An empty or negative cap does not describe the challenge implemented here.

For a short boundary check, temporarily change 287 to LET cap=2. Start a new run, repeat the one-item round, then repeat both items of the next round. Expect Challenge complete. and Rounds completed: 2, with no third playback. Restore cap=16 afterwards. This makes the ending easier to examine without changing its control flow.

A player completes three rounds and fails the fourth. What should the score say?

Show the explanation

Rounds completed: 3. The fourth order has four items, but its length is not the number of completed rounds. Our done variable remains 3 because the mismatch jumps away before line 1160 can increment it.

Try that failure case, and a wrong first-round choice. The latter must show 0. If the score is one too high, check where the increment lives. If every round has one item, check the destination at 1180. If two successive rounds begin differently, check that line 980 appends to s$ instead of replacing it.

Longer orders cost more time too

A successful round of length n plays n demonstration cues and accepts n responses, each with an echoed cue and a comparison. Going from one completed round to sixteen involves 1+2+…+16 demonstration cues: 136, plus 136 response echoes if every round succeeds. Each pause and repaint contributes to that growing duration.

That is a design reason to give the challenge an ending. Increasing the cap changes the amount of repeated work as well as the longest order. A shorter challenge with readable signals can be more inviting than a longer one with rushed signals. There is still no deadline while deciding what to press.

Appending strings also uses memory and may involve copying text. This representation suits a short sequence of one-character choices; it does not provide an unlimited list for free. A numeric array would be another way to store panel identifiers, especially if an item later needed more than one character, but the current string serves both playback and comparison without a second copy of the order.

Complete growing challenge
10 BORDER 0
20 PAPER 0
30 INK 7
40 CLS
50 PRINT "BRIGHT SPARK"
100 LET lit=0
110 FOR p=1 TO 4
120 GO SUB 500
130 NEXT p
240 PRINT AT 2,7;"1"
250 PRINT AT 2,23;"2"
260 PRINT AT 11,7;"3"
270 PRINT AT 11,23;"4"
275 PRINT AT 20,0;"1-4 choose. Hold q to quit."
280 LET s$=""
285 LET done=0
287 LET cap=16
290 GO TO 980
500 LET pr=3
510 LET pc=2
520 LET colour=2
530 LET inkcol=7
540 LET note=0
550 IF p=2 THEN LET pc=18
560 IF p=2 THEN LET colour=1
570 IF p=2 THEN LET note=4
580 IF p=3 THEN LET pr=12
590 IF p=3 THEN LET colour=4
600 IF p=3 THEN LET inkcol=0
610 IF p=3 THEN LET note=7
620 IF p=4 THEN LET pr=12
630 IF p=4 THEN LET pc=18
640 IF p=4 THEN LET colour=6
650 IF p=4 THEN LET inkcol=0
660 IF p=4 THEN LET note=12
670 PAPER colour
680 INK inkcol
690 BRIGHT lit
700 FOR r=pr TO pr+5
710 PRINT AT r,pc;"            "
720 NEXT r
770 IF lit=1 THEN PRINT AT pr+2,pc+5;"*"
780 PAPER 0
790 INK 7
800 BRIGHT 0
810 RETURN
900 LET lit=1
910 GO SUB 500
920 BEEP 0.15,note
930 LET lit=0
940 GO SUB 500
950 PAUSE 10
960 RETURN
980 LET s$=s$+STR$ (INT (RND*4)+1)
990 PRINT AT 19,0;"Rounds completed: ";done
1000 PRINT AT 18,0;"WATCH                         "
1010 FOR i=1 TO LEN s$
1020 IF INKEY$="q" THEN GO TO 1900
1030 LET p=VAL s$(i)
1040 GO SUB 900
1050 NEXT i
1060 IF INKEY$="q" THEN GO TO 1900
1070 PRINT AT 18,0;"Release the keys.              "
1080 GO SUB 1600
1090 PRINT AT 18,0;"YOUR TURN                     "
1100 FOR i=1 TO LEN s$
1110 GO SUB 1500
1120 GO SUB 900
1130 GO SUB 1600
1140 IF k$<>s$(i) THEN GO TO 1800
1150 NEXT i
1160 LET done=done+1
1170 IF done=cap THEN GO TO 1850
1180 GO TO 980
1500 LET k$=INKEY$
1510 IF k$="" THEN GO TO 1500
1520 IF k$="q" THEN GO TO 1900
1530 IF k$<"1" THEN GO TO 1580
1540 IF k$>"4" THEN GO TO 1580
1550 LET p=VAL k$
1560 RETURN
1580 GO SUB 1600
1590 GO TO 1500
1600 LET a$=INKEY$
1610 IF a$="q" THEN GO TO 1900
1620 IF a$<>"" THEN GO TO 1600
1630 RETURN
1800 PRINT AT 18,0;"Different choice.             "
1810 BEEP 0.1,-12
1820 PRINT AT 19,0;"Rounds completed: ";done
1830 STOP
1850 PRINT AT 18,0;"Challenge complete.           "
1860 PRINT AT 19,0;"Rounds completed: ";done
1870 STOP
1900 PRINT AT 18,0;"Finished. RUN to try again.     "
1910 PRINT AT 21,0;"                               "
1920 STOP

Save as spark. The challenge now grows and ends, but playing again still means typing RUN. Next we’ll add a start screen, replay choices and a saved game we can reopen in a fresh emulator session.

Sources

Steven Vickers, edited by Robin Bradbeer, ZX Spectrum BASIC Programming, second edition (Sinclair Research, 1983), chapter 9 (INT and STR$), chapter 11, pp. 73–75 (RND, ranges and pseudo-random sequences), and chapter 8 (strings). The 16-round cap and completed-round score are rules chosen for this game.