This program is a question-and-answer quiz creator and runner. It first prompts the user to enter a set of questions and answers (up to a user-defined count), stores them in string arrays, saves the quiz to tape with autostart, then runs the quiz by presenting each question in random order, offering a hint and a second attempt before revealing the answer, and displaying a final score out of double the question count. The hint mechanism (line 330) reveals only the first and last characters of the answer, replacing the middle with dashes from the string `b$`. A single-keypress routine at lines 460–480 uses a two-phase INKEY$ loop to debounce and capture exactly one key.
Program Structure
The program is split into two distinct phases separated by a SAVE … LINE 20 at line 670, which causes the saved file to autostart at line 20 (the quiz runner). Lines 500–670 form the data-entry phase; lines 10–480 form the quiz engine. Line 9998 provides a master save of the entire program itself.
- Initialization / entry (500–670): collects
mquestions, populatesc$(),a$(),l(), andy(), then saves the quiz. - Quiz setup (10–40): resets score, fills
y(n)=nas an index array for random selection without replacement, and displays all answers as a preview. - Main loop (60–140): randomly picks a remaining question, removes it from the pool, and drives the question/answer/hint cycle.
- Scoring output (160–170): prints final score and stops.
- Subroutines (400–480): “press ENTER” pause and single-keypress debounce.
Random Selection Without Replacement
Rather than shuffling, the program maintains a live index array y() of length x (initially m). At line 60 a random index z into y() is chosen; the corresponding question index q=y(z) is used, then z is removed by shifting all later elements down (lines 80–80) and decrementing x. This guarantees every question is asked exactly once.
Two-Attempt Scoring
The variable t starts at 2 and is decremented to 1 after a wrong first attempt. A correct answer scores t points (2 for first try, 1 for second), giving a maximum possible score of m*2 as shown in the final message at line 160.
Hint Generation
Line 330 constructs a masked version of the answer:
a$(q,1)— the first character of the answer (ZX Spectrum single-character slice syntax)b$(1 TO l(q)-2)— a run of dashes from the pre-built stringb$="---------------"(15 dashes), trimmed to the inner lengtha$(q,l(q))— the last character
This only works correctly when the answer is at least 2 characters long; a single-character answer would produce b$(1 TO -1), an empty slice, effectively showing just the one character twice with no dashes — a minor edge-case anomaly.
Key Arrays and Dimensions
| Variable | Dimension | Purpose |
|---|---|---|
c$(m,64) | m × 64 chars | Questions / clues |
a$(m,15) | m × 15 chars | Answers (max 15 chars) |
l(m) | m elements | Actual length of each answer |
y(m) | m elements | Remaining question index pool |
Because fixed-length string arrays pad with spaces, l(q) is stored at entry time (line 610) and used for the answer comparison slice a$(q)(TO l(q)) at line 110, avoiding false mismatches due to trailing spaces.
Single-Keypress Debounce Idiom
Lines 460–480 implement a clean two-phase key-wait. Line 460 loops while a key is already held (drain any prior keypress), then line 470 loops until a key is pressed, and line 480 captures INKEY$ into k$. This prevents the previous ENTER keypress from the INPUT statement accidentally triggering the “press ENTER to continue” check.
Answer Comparison
Line 110 compares i$ (raw INPUT) against a$(q)(TO l(q)). Because INPUT returns exactly what the user typed, this is a case-sensitive, exact-match comparison. There is no normalisation (e.g. trimming or uppercasing), so answers must be typed with the same capitalisation used at entry time.
Content
Image Gallery
Source Code
10 REM INITIALIZATION
15 REM ****run 500
20 LET s=0: LET x=m: LET b$="---------------": LET e$=" "
30 FOR n=1 TO m: LET y(n)=n: NEXT n
40 GO SUB 400: CLS : FOR n=1 TO m: PRINT AT 10,8;a$(n): PAUSE 50: CLS : NEXT n
50 REM MAIN PROGRAM
60 LET z=INT (RND*x+1): LET q=y(z)
70 LET x=x-1
80 FOR n=z TO x: LET y(n)=y(n+1): NEXT n
90 CLS : LET t=2
100 PRINT AT 3,0;c$(q): INPUT i$
110 IF i$<>a$(q)( TO l(q)) THEN GO TO 240
120 LET s=s+t: GO TO 210
130 GO SUB 410: CLS
140 IF x>0 THEN GO TO 60
150 REM FINAL SCORE
160 PRINT AT 5,0;"Your score was ";s;" out of ";m*2
170 STOP
200 REM PRAISE
210 PRINT AT 7,0;"Well done, ";i$;" was right.";AT 9,15;e$
220 GO TO 130
230 REM WRONG ANSWER
240 IF i$="" THEN GO TO 260
245 PRINT AT 7,0;i$;" was wrong.";e$;AT 9,0;e$
250 GO SUB 410
260 IF t=2 THEN GO TO 310
270 PRINT AT 7,0;"The right answer was:";e$;AT 9,15;a$(q)
280 GO TO 130
300 REM HINT/SECOND TRY
310 LET t=1
320 PRINT AT 7,0;"Here is a hint:";e$;AT 21,0;e$
330 PRINT AT 9,15;a$(q,1)+b$(1 TO l(q)-2)+a$(q,l(q))
340 GO TO 100
400 REM ENTER TO CONTINUE
410 PRINT AT 21,0;"Press ENTER to continue."
420 GO SUB 460
430 IF CODE k$=13 THEN RETURN
440 GO TO 420
450 REM SINGLE KEY INPUT
460 IF INKEY$<>"" THEN GO TO 460
470 IF INKEY$="" THEN GO TO 470
480 LET k$=INKEY$: RETURN
500 REM ENTER QUESTIONS/ANSWERS
510 PRINT "How many questions?": INPUT m
520 DIM c$(m,64): DIM a$(m,15): DIM l(m): DIM y(m)
530 FOR q=1 TO m
540 CLS : PRINT "Question ";q''
550 PRINT "Type in the question or clue.": INPUT c$(q)
560 PRINT 'c$(q)''"Type in the answer.": INPUT i$
570 PRINT 'i$;AT 20,0;"If satisfactory, type s."," To delete, type d."
580 GO SUB 460
590 IF k$="d" THEN GO TO 540
600 IF k$<>"s" THEN GO TO 580
610 LET l(q)=LEN i$: LET a$(q)=i$
620 NEXT q
650 REM SAVE AND RUN
660 CLS : INPUT "What is the program name?";p$
670 SAVE p$ LINE 20
9998 SAVE "QUEST&ANSW" LINE 1
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.