Math Quiz v2.1

Developer(s): John Colonna
Date: 198x
Type: Program
Platform(s): TS 2068

This program is a four-operation arithmetic drill for up to 25 problems, covering addition, subtraction, multiplication, and division. The user selects an operation (1–4), and the program jumps directly to the corresponding routine using the expression `GO TO B*100`, a common Sinclair BASIC computed-jump idiom. Division problems are constructed by generating the divisor first and multiplying by a random integer to guarantee a whole-number answer. A custom UDG character (\a) is defined at startup via a DATA/POKE loop and used to render a division symbol (÷) in both the title screen and problem display. Scores are reported as a rounded percentage using `INT((C/A*100)+.5)`.


Program Analysis

Program Structure

The program is organized into clearly separated sections:

  1. Initialization (lines 15–85): Randomizes, calls the title-screen subroutine, collects the number of problems (A) and the desired operation (B), then dispatches via computed jump.
  2. Operation routines (lines 100–440): Each routine starts at a multiple of 100 (100 = addition, 200 = subtraction, 300 = multiplication, 400 = division) and shares the random-number subroutine at line 800 and the correct/incorrect feedback branches at lines 160 and 145.
  3. Scoring display (lines 505–550): Prints a decorative border, the percentage score, and a play-again prompt.
  4. Subroutines (lines 800–960): Line 800 generates two random integers 1–10; lines 850–960 define the UDG and display the title screen.

Computed GOTO Dispatch

Line 85 uses GO TO B*100 to jump directly to the routine for the chosen operation. Because B is constrained to 1–4 by line 80, this cleanly targets lines 100, 200, 300, or 400 without a chain of IF tests. This is a well-known Sinclair BASIC efficiency technique.

UDG Definition and Use

The subroutine starting at line 850 defines UDG \a (character 144) as a division symbol (÷) using eight bytes stored in a DATA statement and poked via POKE USR "\a"+a, b inside a FOR loop (lines 860–870). The data bytes 0,24,0,127,0,24,0,0 produce a dot-line-dot pattern. The UDG is then used on the title screen (lines 905–940) to spell out the division column header and in the division problem prompt at line 420.

Division Problem Generation

Lines 411–412 construct division problems that always yield a whole-number answer: the divisor F is picked first (1–10), then E is set to F times another random integer (1–10), ensuring E/F is an integer. This avoids the awkwardness of asking a student for a decimal answer.

Shared Feedback Branches

All four operation loops share the same correct/incorrect feedback code. A correct answer jumps to line 160 (plays a rising three-note beep, increments correct counter C), and an incorrect answer falls through or jumps to line 145 (plays a descending two-note beep, increments incorrect counter I). Both branches then continue to line 170 (NEXT J) or its equivalent in each loop.

Score Calculation

Line 520 computes the percentage as INT((C/A*100)+.5), which rounds to the nearest whole percent rather than truncating — a small but deliberate detail.

Bugs and Anomalies

  • Subtraction answer check (line 240): The condition IF G=E-F OR G=F-E THEN GO TO 160 accepts either sign of the difference as correct. This is partially intentional (the display at line 220–225 always shows the larger number first), but because the display swap only occurs when F>E, the problem shown and the accepted answer are not always in sync. When E>F, the problem is shown as E - F, yet F-E (a negative number) would also be accepted as correct.
  • Subtraction fallthrough (line 245): Line 245 uses OR rather than AND: IF G<>E-F OR G<>F-E THEN GO TO 145. Because at least one of the two conditions is always true for any value of G, this line unconditionally branches to 145 and is logically redundant given the preceding check at line 240. The AND operator was almost certainly intended.
  • Incorrect counter I unused: I is incremented at line 150 but never displayed in the score section — only C (correct answers) is used for the percentage.
  • Missing NEXT J for division loop: The division loop (lines 400–440) has no explicit NEXT J statement before falling through to line 505. Execution will naturally reach line 505 after the last iteration, but the loop variable J is never formally closed. On Sinclair BASIC this works in practice because reaching the end of the program body simply exits the loop implicitly via the jump to 505.

Variable Summary

VariablePurpose
ANumber of problems (1–25)
BOperation choice (1–4)
CCorrect answer count
IIncorrect answer count (unused in output)
JProblem loop counter
E, FRandom operands for each problem
GStudent’s input answer
HLoop variable for correct-answer beep
a, bUDG definition loop variables

Content

Appears On

One of a series of library tapes. Programs on these tapes were renamed to a number series. This tape contained

Related Products

Related Articles

Related Content

Image Gallery

Source Code

    5 REM  math   VERSION 2.1
   10 REM John Colonna SINCUS
   15 RANDOMIZE : GO SUB 850
   20 CLS : BORDER 6
   25 PRINT 
   30 PRINT "HOW MANY PROBLEMS ARE YOU GOING TO DO (1 TO 25)?";
   35 INPUT A
   40 IF A>25 OR A<1 THEN GO TO 35
   45 PRINT "  "; INVERSE 1;A
   50 LET C=0: LET I=0
   55 PRINT 
   60 PRINT "  "; PAPER 6;"ENTER 1 FOR ADDITION"
   65 PRINT "  "; PAPER 6;"ENTER 2 FOR SUBTRACTION"
   70 PRINT "  "; PAPER 6;"ENTER 3 FOR MULTIPLICATION"
   72 PRINT "  "; PAPER 6;"ENTER 4 FOR DIVISION"
   75 INPUT B
   80 IF B<1 OR B>4 THEN GO TO 75
   85 GO TO B*100
  100 FOR J=1 TO A
  105 PRINT 
  110 PRINT "   NUMBER "; INVERSE 1;J
  115 GO SUB 800
  120 PRINT "   ";E;" + ";F;" = ";
  125 INPUT G
  130 PRINT G;
  135 IF G=E+F THEN GO TO 160
  140 IF G<>E+F THEN GO TO 145
  145 PRINT ," INCORRECT": BEEP .5,0: BEEP .5,-5
  150 LET I=I+1
  155 GO TO 170
  160 PRINT ,"  CORRECT": FOR H=15 TO 17: BEEP .2,H: NEXT H
  165 LET C=C+1
  170 NEXT J
  175 GO TO 505
  200 FOR J=1 TO A
  205 PRINT 
  210 PRINT "   NUMBER "; INVERSE 1;J
  215 GO SUB 800
  220 IF F>E THEN PRINT "   ";F;" - ";E;" = ";: GO TO 230
  225 PRINT "   ";E;" - ";F;" = ";
  230 INPUT G
  235 PRINT G;
  240 IF G=E-F OR G=F-E THEN GO TO 160
  245 IF G<>E-F OR G<>F-E THEN GO TO 145
  300 FOR J=1 TO A
  305 PRINT 
  310 PRINT "   NUMBER "; INVERSE 1;J
  315 GO SUB 800
  320 PRINT "   ";E;" X ";F;" = ";
  325 INPUT G
  330 PRINT G;
  335 IF G=E*F THEN GO TO 160
  340 IF G<>E*F THEN GO TO 145
  400 FOR J=1 TO A
  405 PRINT 
  410 PRINT "   NUMBER "; INVERSE 1;J
  411 LET F=INT (RND*10)+1
  412 LET E=F*(INT (RND*10)+1)
  420 PRINT "   ";E;" \a ";F;" = ";
  425 INPUT G
  430 PRINT G;
  435 IF G=E/F THEN GO TO 160
  440 IF G<>E/F THEN GO TO 145
  505 PRINT : PRINT "\''\''\''\''\''\''\''\''\''\''\''\''\''\''\''\''\''\''\''\''\''\''\''\''\''\''\''\''\''\''\''\''": PRINT 
  510 PRINT "        YOUR SCORE IS"
  515 PRINT : PRINT 
  520 PRINT "         ";INT ((C/A*100)+.5);" PER CENT"
  525 PRINT 
  530 PRINT "\''\''\''\''\''\''\''\''\''\''\''\''\''\''\''\''\''\''\''\''\''\''\''\''\''\''\''\''\''\''\''\''"
  535 PRINT "DO YOU WANT TO PLAY AGAIN? (y/n)"
  540 PRINT 
  545 IF INKEY$="y" OR INKEY$="Y" THEN GO TO 20
  550 GO TO 545
  800 LET E=INT (RND*10)+1
  805 LET F=INT (RND*10)+1
  810 RETURN 
  850 REM udg
  860 DATA 0,24,0,127,0,24,0,0
  870 FOR a=0 TO 7: READ b: POKE USR "\a"+a,b: NEXT a
  900 CLS 
  905 PRINT AT 6,3;"+   +    -    xxxxx  \a   \a   "   
  910 PRINT TAB 3;"++ ++   - -     x    \a   \a"
  920 PRINT TAB 3;"+ + +  -----    x    \a\a\a\a\a"
  930 PRINT TAB 3;"+   +  -   -    x    \a   \a"
  940 PRINT TAB 3;"+   +  -   -    x    \a   \a"
  950 PRINT : PRINT : PRINT : PRINT : PRINT TAB 3; FLASH 1;"Press any key to continue."
  955 PAUSE 0
  960 RETURN 
 9998 STOP 
 9999 SAVE "Math" LINE 1: BEEP 1,32

Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.

Scroll to Top