--- title: "Ohio Lottery" id: 55102 type: "computer_media" slug: "ohio-lottery" url: "http://localhost/computer_media/ohio-lottery/" markdown_url: "http://localhost/computer_media/ohio-lottery.md" published_at: "2024-06-16T14:42:07+00:00" modified_at: "2026-03-30T21:44:20+00:00" author: "David Anderson" featured_image: url: "http://localhost/wp-content/uploads/2019/02/20230809-041332.jpg" excerpt: "Pick your lucky numbers with this two-mode lottery generator that ensures unique draws and supports both screen copy and line printer output." category: - name: "Archived Media" slug: "archived-media" taxonomy: "category" url: "http://localhost/category/archived-media/" post_tag: - name: "Downloadable" slug: "downloadable" taxonomy: "post_tag" url: "http://localhost/tag/downloadable/" - name: "TS 2068" slug: "ts2068" taxonomy: "post_tag" url: "http://localhost/tag/ts2068/" model: - name: "Timex/Sinclair 2068" slug: "ts-2068" taxonomy: "model" url: "http://localhost/model/ts-2068/" indiv: - name: "Algis Gedris" slug: "algis-gedris" taxonomy: "indiv" url: "http://localhost/indiv/algis-gedris/" genre: - name: "Entertainment" slug: "entertainment" taxonomy: "genre" url: "http://localhost/type/entertainment/" media_contents: - id: 54965 title: "ISTUG Public Domain Library 5" type: "computer_media" url: "http://localhost/computer_media/istug-public-domain-library-5/" media_type: "Program" programmers: - name: "Algis Gedris" slug: "algis-gedris" taxonomy: "indiv" url: "http://localhost/indiv/algis-gedris/" mediadate: "1986" images: - url: "http://localhost/wp-content/uploads/2024/06/ohio-lottery.png" media_type_tags: "Entertainment" --- # Ohio Lottery 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: 1. **Menu (lines 10–170):** Displays a title screen and routes the user to either the Daily Lottery (`D`) or Ohio Lottery (`O`) mode. 2. **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. 3. **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,8` forces Caps Lock on, so user menu input is automatically uppercase, avoiding case-sensitivity issues in the `IF H$="O"` comparisons. - `POKE 23609,45` sets the scroll pause counter in the system variables, controlling how long the “scroll?” prompt is held. - `LET I=I` at 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 inline `PRINT ... ;` 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 of `A(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)` for `A(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. ## 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" ```