This program generates random lottery number suggestions for two Ohio lottery games: a configurable-digit daily lottery and a 6-number Ohio Lottery game (numbers 1–44). The daily lottery mode accepts a user-defined digit count and generates single digits (0–9) by repeatedly calling INT(RND*50) and rejecting values above 9. The Ohio Lottery mode uses a manual uniqueness check — comparing each new number against all previously drawn values using cascading IF statements rather than a loop — to ensure no duplicates among the six picks (range 1–44). The program supports ZX Spectrum printer output via LPRINT and screen copy via COPY, and uses POKE 23658,8 to enable Caps Lock and POKE 23609,45 to set a custom scroll delay.
Program Analysis
Program Structure
The program is divided into three logical sections:
- Menu (lines 10–170): Displays a title screen and routes the user to either the Daily Lottery (
D) or Ohio Lottery (O) mode. - Daily Lottery (lines 180–340): Accepts a user-defined number of digits
N, generates that many single-digit random numbers (0–9), and displays them in sequence with optional LPRINT support. - Ohio Lottery (lines 350–770): Generates 6 unique random numbers in the range 1–44, with duplicate checking handled by a cascade of explicit comparisons.
Random Number Generation
Both modes use INT(RND*50) as the base generator and then apply rejection sampling to constrain the range. In Daily mode (line 240), any value above 9 is discarded and regenerated. In Ohio mode (lines 420–430), values outside 1–44 are discarded. This is an unbiased approach within the chosen range, though using RND*50 with a tight acceptance window (only 9 values out of 50 accepted in Daily mode) is inefficient; INT(RND*10) would suffice.
Duplicate Elimination in Ohio Mode
Rather than using a loop to compare a new value against the array, the program uses a dispatch table (lines 440–490) to jump to a uniqueness-checking block specific to each value of I. Each block explicitly compares the new value against all previously assigned elements and re-rolls if a duplicate is found. This is verbose but straightforward.
| I value | Checks performed | Lines |
|---|---|---|
| 1 | None (first number, always unique) | 700 |
| 2 | A(2) ≠ A(1) | 500–510 |
| 3 | A(3) ≠ A(1), A(3) ≠ A(2) | 520–540 |
| 4 | A(4) ≠ A(1..3) | 550–580 |
| 5 | A(5) ≠ A(1..4) | 590–630 |
| 6 | A(6) ≠ A(1..5) | 640–690 |
Use of PI as an Array Index
A significant bug appears throughout the program: array element 3 is consistently accessed as A(PI) rather than A(3). Since PI evaluates to approximately 3.14159, the Spectrum’s BASIC interpreter truncates it to 3 when used as an integer index, so this accidentally works correctly. It is almost certainly a transcription or editing error where the digit 3 was mistakenly entered or interpreted as the PI keyword.
Notable BASIC Idioms and Techniques
POKE 23658,8forces Caps Lock on, so user menu input is automatically uppercase, avoiding case-sensitivity issues in theIF H$="O"comparisons.POKE 23609,45sets the scroll pause counter in the system variables, controlling how long the “scroll?” prompt is held.LET I=Iat lines 220 and 400 is a no-op and serves no functional purpose — likely a vestigial debugging line or copy-paste artifact.- The
PRINT 'idiom (line 280 etc.) emits a newline before the next prompt, keeping the display tidy after inlinePRINT ... ;output. - Formatted number output in Ohio mode (lines 700–710) pads single-digit numbers with a leading space to maintain column alignment.
- Line 320’s LPRINT for 4-digit mode also uses
A(PI)instead ofA(3), consistent with the bug elsewhere.
Output and Peripheral Support
The program supports three output methods: on-screen display (default), ZX Spectrum COPY to a printer for a screen dump (Z key), and direct LPRINT formatted line output (L key). The LPRINT path in Ohio mode (line 760) re-enters the generation loop at line 380 after printing, restarting fresh rather than reprinting the existing set.
Bugs and Anomalies
A(PI)forA(3): Occurs at lines 320, 330, 520, 530, 570, 610, 660, and 760. Functionally harmless due to integer truncation, but incorrect.- Daily mode re-roll inefficiency: Using
INT(RND*50)with acceptance only for 0–9 means roughly 80% of random draws are discarded. - Line 340 STOP: Reached if
K$is neither empty,"Z", nor"L"in Daily mode, halting the program unexpectedly instead of returning to the menu. - Ohio mode COPY path (line 750): After COPY, jumps to line 350 which re-initializes border/paper/ink and resets the loop, rather than continuing to display more numbers.
Content
Source Code
10 REM O H I O L O T T E R Y PROGRAM WRITTEN BYALGIS E. GEDRIS355 ROYAL OAK BLVD.RICHMOND HEIGHTS, OH44143-1709PHONE- (216) 481-8205REVISION 1.0 1.1 BY PEH Software
20 BORDER 1: PAPER 2: INK 7
30 CLS : POKE 23658,8
40 POKE 23609,45
50 PRINT INK 6'" ALGIS E. GEDRIS PRESENTS "
60 PRINT '" L O T T E R Y N U M B E R S "
70 PRINT 'TAB 10;" M E N U "
80 PRINT ''TAB 7;"OHIO LOTTERY ... O"
90 PRINT 'TAB 7;"DAILY LOTTERY .. D"
100 PRINT ''" ENTER Z FOR COPY SCREEN... Z"
110 PRINT 'TAB 7;"L FOR LINE PRINT ... L"
120 PRINT 'TAB 7;"N RETURN TO MENU ... N"
130 PRINT '"MAY/1986"
140 INPUT H$
150 IF H$="O" THEN GO TO 350
160 IF H$="D" THEN GO TO 180
170 GO TO 20
180 CLS
190 INPUT "NUMBER OF DIGITS = ";N
200 DIM A(N)
210 FOR I=1 TO N
220 LET I=I
230 LET A(I)=INT (RND*50)
240 IF A(I)>9 THEN GO TO 230
250 PRINT A(I);" ";
260 NEXT I
270 INPUT ">ENTER< FOR MORE NUMBERS ";K$
280 IF K$="" THEN PRINT ': GO TO 210
290 IF K$="Z" THEN COPY : PRINT ': GO TO 210
300 IF K$="L" THEN GO TO 320
310 RUN
320 IF N=4 THEN LPRINT A(1);" ";A(2);" ";A(PI);" ";A(4): PRINT ': GO TO 210
330 IF N=3 THEN LPRINT A(1);" ";A(2);" ";A(PI): PRINT ': GO TO 210
340 STOP
350 CLS
360 BORDER 2: PAPER 6: INK 0
370 CLS
380 DIM A(6)
390 FOR I=1 TO 6
400 LET I=I
410 LET A(I)=INT (RND*50)
420 IF A(I)>44 THEN GO TO 410
430 IF A(I)<1 THEN GO TO 410
440 IF I=1 THEN GO TO 700
450 IF I=2 THEN GO TO 500
460 IF I=3 THEN GO TO 520
470 IF I=4 THEN GO TO 550
480 IF I=5 THEN GO TO 590
490 IF I=6 THEN GO TO 640
500 IF A(2)=A(1) THEN GO TO 410
510 GO TO 700
520 IF A(PI)=A(1) THEN GO TO 410
530 IF A(PI)=A(2) THEN GO TO 410
540 GO TO 700
550 IF A(4)=A(1) THEN GO TO 410
560 IF A(4)=A(2) THEN GO TO 410
570 IF A(4)=A(PI) THEN GO TO 410
580 GO TO 700
590 IF A(5)=A(1) THEN GO TO 410
600 IF A(5)=A(2) THEN GO TO 410
610 IF A(5)=A(PI) THEN GO TO 410
620 IF A(5)=A(4) THEN GO TO 410
630 GO TO 700
640 IF A(6)=A(1) THEN GO TO 410
650 IF A(6)=A(2) THEN GO TO 410
660 IF A(6)=A(PI) THEN GO TO 410
670 IF A(6)=A(4) THEN GO TO 410
680 IF A(6)=A(5) THEN GO TO 410
690 GO TO 700
700 IF A(I)<10 THEN PRINT " ";A(I);" ";: GO TO 720
710 PRINT A(I);" ";
720 NEXT I
730 INPUT ">ENTER< FOR MORE NUMBERS ";K$
740 IF K$="" THEN PRINT ': GO TO 390
750 IF K$="Z" THEN COPY : GO TO 350
760 IF K$="L" THEN LPRINT A(1);" ";A(2);" ";A(PI);" ";A(4);" ";A(5);" ";A(6): PRINT ': GO TO 380
770 RUN
780 SAVE "OH LOTTERY" LINE 1
790 BEEP 1,10: VERIFY "OH LOTTERY"
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
