This program is a mental arithmetic quiz that tests addition, subtraction, multiplication, or division across three difficulty levels. The player selects one of four operations and a level (1–3), which controls the magnitude of operands via powers of ten (10**B). For division questions (operations 3 and 4), line 150 rescales the divisor to avoid trivially large denominators. The expression to evaluate is assembled as a string in B$ using STR$ and then evaluated with VAL to check the answer, allowing the ZX81’s expression evaluator to do the arithmetic. Scores are tracked across ten questions and displayed at the end before the program restarts with RUN.
Program Analysis
Program Structure
The program follows a straightforward linear flow with a single loop for the ten questions:
- Lines 10–50: Initialisation — randomise, set SLOW mode, zero the score counter
F, define the operator stringA$, and clear the screen. - Lines 60–90: User selects the arithmetic operation (1–4) and difficulty level (1–3).
- Lines 100–260: A
FOR … NEXTloop over 10 questions generates operands, displays the question, reads the answer, and scores it. - Lines 270–290: Final score display, then
RUNrestarts the whole program. - Lines 300–310:
SAVEand a secondRUN— the SAVE line is never reached during normal execution and serves as a program-storage command rather than part of gameplay.
Operand Generation
Lines 130–150 generate two random operands C and D. The expression INT(10**B*RND) produces an integer in the range 0 to 10B−1, so level 1 gives single-digit numbers, level 2 two-digit numbers, and level 3 three-digit numbers.
Line 150 applies a correction for multiplication and division (A>2): D=INT(D/(10**(B-1)))+1. This rescales D to a small non-zero value (1–10), preventing unwieldy divisors or very large products at higher levels, and guaranteeing the divisor is never zero.
String-Eval Arithmetic Trick
Line 160 builds the expression string B$ by concatenating STR$ C, the operator character A$(A) (a single character sliced from "+-*/"), and STR$ D. Line 200 then uses VAL B$ to evaluate this string as a numeric expression. This delegates all arithmetic to the BASIC interpreter’s own expression evaluator, neatly avoiding the need to write four separate calculation branches. The tolerance check ABS(VAL B$-D)>0.01 accommodates minor floating-point imprecision.
Variable Reuse
D is used for three distinct purposes across the program, which is a common ZX81 memory-saving idiom:
- Lines 140–150: The second operand in the generated question.
- Line 180: The player’s numeric answer (overwriting the operand).
- Lines 250, 280: A dummy string variable
D$used to pause for a keypress (unrelated to numericD).
After line 160 captures the expression in B$, the operand value of D is no longer needed, making the reuse safe.
Notable Techniques
- The operator lookup
A$(A)uses ZX81 substring indexing to extract a single character from"+-*/", acting as a compact operator table. SLOWat line 20 ensures display stability during computation — important for programs that do floating-point work on the ZX81.RAND(without an argument) seeds the random number generator from the system clock, giving different question sets each run.- The program loops back to the start via
RUN(line 290) rather thanGO TO 10, which fully reinitialises variables — intentionally resetting the score to zero for a fresh game.
Bugs and Anomalies
- At level 1 (
B=1), line 150 computesINT(D/(10**0))+1 = INT(D/1)+1 = D+1, so the divisor/multiplier is at least 1 but drawn from the same 0–9 range plus one (1–10). This is harmless but slightly inconsistent with the intent of keeping small operands at low levels. - For subtraction (
A=2), no check ensuresC≥D, so negative results are possible. TheVAL B$evaluation handles this correctly, but young users may find negative answers surprising. - Division results are not constrained to be whole numbers; the quiz accepts any decimal answer within 0.01 of the true value, which is appropriate given the operand generation strategy.
Line Reference Summary
| Lines | Purpose |
|---|---|
| 10–50 | Initialisation |
| 60–90 | Operation and level selection |
| 100–260 | 10-question quiz loop |
| 130–150 | Random operand generation with level scaling |
| 160–200 | Question display, answer input, and string-eval marking |
| 270–290 | Score display and restart |
Content
Source Code
1 REM "MATH"
10 RAND
20 SLOW
30 LET F=0
40 LET A$="+-*/"
50 CLS
60 PRINT "FUNCTION 1=+; 2=-; 3=*; 4=/"
70 INPUT A
80 PRINT ,,"LEVEL 1-3"
90 INPUT B
100 FOR N=1 TO 10
110 CLS
120 PRINT "QUESTION ";N,F;" CORRECT"
130 LET C=INT (10**B*RND)
140 LET D=INT (10**B*RND)
150 IF A>2 THEN LET D=INT (D/(10**(B-1)))+1
160 LET B$=STR$ C+""+A$(A)+""+STR$ D
170 PRINT ,,B$;"=";
180 INPUT D
190 PRINT D
200 IF ABS (VAL B$-D)>0.01 THEN GOTO 240
210 PRINT ,,"CORRECT PRESS N/L"
220 LET F=F+1
230 GOTO 250
240 PRINT ,,"WRONG PRESS N/L"
250 INPUT D$
260 NEXT N
270 PRINT ,,"SCORE ";F;" OUT OF 10"
280 INPUT D$
290 RUN
300 SAVE "1017%0"
310 RUN
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
