--- title: "Mystery" id: 57527 type: "computer_media" slug: "mystery" url: "http://localhost/computer_media/mystery/" markdown_url: "http://localhost/computer_media/mystery.md" published_at: "2024-10-05T21:29:31+00:00" modified_at: "2026-03-30T21:17:25+00:00" author: "David Anderson" featured_image: url: "http://localhost/wp-content/uploads/2024/10/282_Myst.png" excerpt: "A binary number-guessing trick that uses six cards and a cleverly shared FOR-loop subroutine to deduce any number from 1 to 63." 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 1000" slug: "ts1000" taxonomy: "post_tag" url: "http://localhost/tag/ts1000/" model: - name: "Timex/Sinclair 1000" slug: "ts-1000" taxonomy: "model" url: "http://localhost/model/ts-1000/" genre: - name: "Game" slug: "game" taxonomy: "genre" url: "http://localhost/type/game/" media_contents: - id: 56737 title: "Timex Sinclair Public Domain Library Tape 1006" type: "computer_media" url: "http://localhost/computer_media/timex-sinclair-public-domain-library-tape-1006/" media_type: "Program" mediadate: "198x" images: - url: "http://localhost/wp-content/uploads/2024/10/282_Myst.png" media_type_tags: "Game, Software" --- # Mystery This program implements a classic six-card binary number-guessing trick, where the computer deduces a chosen number between 1 and 63. Each of the six cards displays a subset of numbers corresponding to a specific bit position in binary representation; the user presses Y or N for each card, and the program accumulates the answer using powers of 2. The title screen uses inverse-video characters for the “PRESS ANY KEY” prompts at lines 80 and 320. The subroutine structure is unusual: GOSUB 500 handles the first card’s Y/N input via a FOR loop, while GOSUB 550 re-enters that same loop mid-execution by jumping to the NEXT E statement, a deliberate shared-loop technique. The final calculation at line 260 sums B(X)*2^X across all six cards, then divides by 2 at line 290 to correct for the off-by-one in the exponent, correctly recovering the chosen number. *** ## Program Analysis ### Program Structure The program is divided into distinct phases: title/instructions (lines 5–90), card display and input collection (lines 100–230), result calculation and display (lines 240–350), and two subroutines (lines 500–570). A `RUN` at line 350 restarts the program for replay. Lines 580–590 appear to be a saved-program header artifact and are never reached during normal execution. 1. Lines 5–90: Initialisation, title box, instructions, and wait for keypress 2. Lines 100–230: Six card screens shown in sequence, each calling a subroutine 3. Lines 240–290: Binary accumulation and result reveal 4. Lines 300–350: Pause, replay prompt, restart via `RUN` 5. Lines 500–540: Subroutine — FOR loop body collecting Y/N for each card 6. Lines 550–570: Subroutine entry point for cards 2–6, jumping into the middle of the FOR loop ### The Shared FOR-Loop Subroutine Technique The most notable structural feature is the split subroutine. `GOSUB 500` (line 130) initiates a `FOR E=1 TO 6` loop and reads the first card’s response. Subsequent cards (lines 150–230) each call `GOSUB 550`, which enters at the `NEXT E` statement, advancing the same loop variable and reading subsequent cards before returning. This deliberately reuses the FOR loop stack frame across multiple `GOSUB`/`RETURN` pairs — an unusual but functional technique that saves repeating the input-reading logic. ### Input Handling Y/N input at line 510–530 uses a busy-wait on `INKEY$`, accepting only `"Y"` or `"N"`. Line 530 stores `VAL A$` into the array `B(E)`. Since `VAL "Y"` and `VAL "N"` both evaluate to 0 in Sinclair BASIC, this is a bug — both answers will store 0, making the trick non-functional. The programmer likely intended to store 1 for “Y” and 0 for “N”, perhaps using a conditional assignment. Line 535 provides a key-debounce loop to drain any held key before continuing. ### Binary Calculation and Off-by-One Correction Lines 250–270 accumulate the result as `F = F + B(X) * 2^X` for X = 1 to 6. Because the exponent starts at 1 rather than 0, the accumulated value is exactly double the intended result. Line 290 corrects this by printing `F/2`. The cards themselves correspond to bit positions 0–5 of a 6-bit number (covering 1–63), which is consistent with dividing by 2 at output time. ### Key BASIC Idioms - `IF INKEY$="" THEN GOTO 90` — standard busy-wait for any keypress - `PRINT AT row,col;` — precise cursor positioning for card layout - Double-comma `,,` in `PRINT` statements skips two lines efficiently - `RUN` at line 350 resets all variables and restarts cleanly, avoiding the need for explicit re-initialisation - Inverse-video text (e.g., `%P%R%E%S%S%`) used for prominent prompts at lines 80 and 320 ### Card Display and Graphics Each card is framed by block-graphic border rows printed at lines 111’s `AT 6` and `AT 14` positions, using `\:′` and `\:.` corner/edge block characters to form a horizontal rule above and below the number grid. The numbers within each card correspond precisely to the correct binary bit-mask subsets for a 6-bit guessing trick (e.g., card 1 shows all odd numbers; card 2 shows numbers where bit 1 is set, etc.). ### Bugs and Anomalies | Line | Issue | Effect | | --- | --- | --- | | 530 | `LET B(E)=VAL A$` — `VAL "Y"` and `VAL "N"` both yield 0 | All six cards record 0; computed result is always 0, breaking the trick | | 300–310 | `FOR C=1 TO 20: NEXT C` is an empty delay loop | Negligible pause on fast hardware; an inadequate substitute for `PAUSE` | | 560–570 | `STOP` and `CLEAR` follow the subroutine and are unreachable in normal flow | No effect; likely leftover debugging lines | ### Variable Summary | Variable | Purpose | | --- | --- | | `F` | Accumulator for the binary sum | | `B(6)` | Array storing Y/N response (0 or 1) for each of the 6 cards | | `Y`, `N` | Declared at lines 20–30 but never used (likely vestigial) | | `E` | FOR loop variable shared across the split subroutine | | `A$` | Temporary storage for the keypress character | | `C` | Loop counter for the delay at line 300 | | `X` | Loop variable for the binary accumulation at line 250 | ## Source Code ``` 5 LET F=0 10 DIM B(6) 20 LET Y=1 30 LET N=0 35 PRINT " ????????????????????? " 37 PRINT " ? ? " 40 PRINT " ? MYSTERY ? MYSTERY ? " 42 PRINT " ? ? " 45 PRINT " ????????????????????? " 60 PRINT AT 8,0;" YOU CHOOSE A NUMBER BETWEEN 1 AND 63.",," THEN A SERIES OF 6 CARDS WILL BE SHOWN IN TURN,YOU ARE THEN REQUIRED TO TYPE EITHER YES OR NO (Y OR N) DEPENDING ON WHETHER YOUR NUMBER APPEARS OR NOT." 70 PRINT ,,,,"I WILL THEN TELL YOU YOUR NUMBER" 80 PRINT AT 21,0;" %P%R%E%S%S% %A%N%Y% %K%E%Y% %F%O%R% %F%I%R%S%T% %C%A%R%D " 90 IF INKEY$="" THEN GOTO 90 100 CLS 110 PRINT AT 0,0;"CARD ";1 111 PRINT AT 6,3;"\:'\''\''\''\''\''\''\''\''\''\''\''\''\''\''\''\''\''\''\''\''\''\''\''\':";AT 14,3;"\:.\..\..\..\..\..\..\..\..\..\..\..\..\..\..\..\..\..\..\..\..\..\..\..\.:" 120 PRINT AT 7,0;" 1 3 5 7 9 11 13 15 ",," 17 19 21 23 25 27 29 31 ",," 33 35 37 39 41 43 45 47 ",," 49 51 53 55 57 59 61 63 " 130 GOSUB 500 140 PRINT AT 0,5;2;AT 7,0;" 2 3 6 7 10 11 14 15 ",," 18 19 22 23 26 27 30 31 ",," 34 35 38 39 42 43 46 47 ",," 50 51 54 55 58 59 62 63 " 150 GOSUB 550 160 PRINT AT 0,5;3;AT 7,0;" 4 5 6 7 12 13 14 15 ",," 20 21 22 23 28 29 30 31 ",," 36 37 38 39 44 45 46 47 ",," 52 53 54 55 60 61 62 63 " 170 GOSUB 550 180 PRINT AT 0,5;4;AT 7,0;" 8 9 10 11 12 13 14 15 ",," 24 25 26 27 28 29 30 31 ",," 40 41 42 43 44 45 46 47 ",," 56 57 58 59 60 61 62 63 " 190 GOSUB 550 200 PRINT AT 0,5;5;AT 7,0;" 16 17 18 19 20 21 22 23 ",," 24 25 26 27 28 29 30 31 ",," 48 49 50 51 52 53 54 55 ",," 56 57 58 59 60 61 62 63 " 210 GOSUB 550 220 PRINT AT 0,5;6;AT 7,0;" 32 33 34 35 36 37 38 39 ",," 40 41 42 43 44 45 46 47 ",," 48 49 50 51 52 53 54 55 ",," 56 57 58 59 60 61 62 63 " 230 GOSUB 550 240 CLS 250 FOR X=1 TO 6 260 LET F=F+B(X)*2**(X) 265 PRINT AT 12,0;" NOW,LET ME THINK....." 267 IF X=4 THEN PRINT AT 16,0;" AH,I KNOW NOW." 270 NEXT X 280 CLS 290 PRINT AT 10,0;" YOUR NUMBER WAS ";F/2 300 FOR C=1 TO 20 310 NEXT C 320 PRINT AT 21,0;" %P%R%E%S%S% %A%N%Y% %K%E%Y% %F%O%R% %A%N%O%T%H%E%R% %G%O " 330 IF INKEY$="" THEN GOTO 330 340 CLS 350 RUN 500 FOR E=1 TO 6 510 LET A$=INKEY$ 520 IF A$<>"N" AND A$<>"Y" THEN GOTO 510 530 LET B(E)=VAL A$ 535 IF INKEY$<>"" THEN GOTO 535 540 RETURN 550 NEXT E 560 STOP 570 CLEAR 580 SAVE "1028%2" 590 RUN ```