This program is an anagram-guessing game in which the player must identify a scrambled word or phrase by entering letters and their correct positions. It randomly selects one of ten words or phrases from a DATA list, shuffles the characters using a Fisher-Yates-style swap loop, then presents the anagram inside a decorative block-graphic border. A thermometer graphic on the left side, drawn with CIRCLE, PLOT, and DRAW commands, rises by one unit for each incorrect guess; the player has ten wrong attempts before the “cauldron” overflows. The score counter starts at 100 and decrements by 10 per mistake, and a FLASH warning appears when only one guess remains. Input validation at line 140 ensures the position entered is an integer within the valid word length range.
Program Analysis
Program Structure
The program is organized into a clear sequence of phases:
- Initialization (lines 5–10): Sets display attributes and the word count
n=10. - Word selection (lines 20–30): Restores the DATA pointer and reads a random entry from the list.
- Setup (lines 40–60): Calculates word length, allocates string arrays, initializes the progress string
p$with dashes, and shuffles the word intox$. - Screen drawing (lines 70–115): Renders the thermometer, borders, anagram display box, and guess box using block graphics.
- Game loop (lines 120–210): Accepts letter/position input, validates it, updates state, and branches on win or loss.
- End sequence (lines 220–230): Offers replay or clean exit.
Word Selection and Shuffling
Line 20 uses RESTORE followed by a FOR loop that reads INT(1 + n*RND) entries, landing on a random word — a standard Sinclair BASIC idiom for random DATA access without arrays. The shuffle at line 60 implements a variant of the Fisher-Yates algorithm: for each position i, a random index r is chosen from the full range 1..l and the characters at i and r are swapped via the temporary variable z$. Note that this is the naïve (biased) version of Fisher-Yates since r is drawn from the entire array rather than from i..l, but it produces a sufficiently random result for gameplay.
Thermometer Graphic
The thermometer on the left side of the screen is constructed entirely with Spectrum graphics primitives. Line 80 draws the circular bulb using CIRCLE 20,24,r in a loop with radii 1–12. Line 90 uses PLOT and DRAW to outline the tube. The scale labels are printed at lines 95 with the expression 210-10*i, producing values 200, 190, … 110, 100. Each wrong answer executes DRAW INK 7;0,8 at line 190, extending the filled column upward by 8 pixels, giving exactly 10 steps before overflow.
Scoring and Penalty Logic
| Variable | Initial Value | Change per Wrong Guess | Trigger |
|---|---|---|---|
t | 100 | +10 | Reaches 200 → game over |
c | 0 | +1 (correct only) | Reaches l → win |
At t=190 (one guess remaining), line 200 prints a FLASH 1 warning and pauses for 200 frames (~4 seconds). At t=200, line 190 triggers the failure sequence: a BEEP sweep from −25 to +25 semitones and a full-screen inverse fill achieved by printing 704 INVERSE 1 spaces (704 = 22 rows × 32 columns).
Input Handling and Validation
Line 130 uses a two-part INPUT statement collecting both a letter l$ and a numeric position p in a single prompt. Line 140 validates p with three conditions: it must be an integer (p=INT p), at least 1, and no greater than both l (the word length) and LEN w$ (redundant but defensive). Invalid entries loop back via GO TO 140. Correct placement is checked at line 150 by directly indexing w$(p) against the entered letter l$.
Notable Bugs and Anomalies
- Case sensitivity: The comparison
w$(p)<>l$is case-sensitive. Since the words in DATA are uppercase, the player must enter uppercase letters; no normalization is performed. - Variable name collision: The loop variable at line 95 uses lowercase
i, but line 110 switches to uppercaseIfor itsFORloop, then references lowercaseiinside the same loop body (PRINT AT i,12). On the Spectrum, variable names are case-insensitive for numeric variables in most contexts, but this inconsistency could cause confusion when reading the listing. - Score counter direction:
tstarts at 100 and increments toward 200 on wrong guesses, while the on-screen scale labels descend from 200 to 100. This means the thermometer visually rises as the score numerically increases, which is the intended behavior but is counter-intuitive from a “score” perspective. - “INFEDELITY”: The DATA list contains
"INFEDELITY", which is a misspelling of “INFIDELITY”. - “OPTHALMOLOGY”: Similarly,
"OPTHALMOLOGY"is a misspelling of “OPHTHALMOLOGY”. - Replay uses RUN: Line 220 uses
RUN(rather thanGO TO 10) to restart, which correctly re-initializes all variables but also re-executes the attribute setup at line 5.
Content
Source Code
5 PAPER 0: BORDER 0: INK 9: CLS
10 LET n=10
20 RESTORE : FOR i=1 TO INT (1+n*RND): READ w$: NEXT i
30 DATA "RIO DE JANEIRO","INFEDELITY","IMMORTALITY","ANACHRONISM","OPTHALMOLOGY", "ADMINISTRATION","ASTROPHYSICS","PSYCHIATRY","PLANETARIUM","INDECISION"
40 LET l=LEN w$: DIM p$(l): DIM x$(l): FOR i=1 TO l: LET p$(i)="-": NEXT i
50 LET c=0: LET t=100: LET x$=w$
60 FOR i=1 TO l: LET r=INT (1+l*RND): LET z$=x$(i): LET x$(i)=x$(r): LET x$(r)=z$: NEXT i
70 CLS : PAPER 0: BORDER 0: INK 7
80 FOR r=1 TO 12: CIRCLE 20,24,r: NEXT r
90 PLOT 18,26: DRAW 0,149: DRAW 4,0: DRAW 0,-149: PLOT 20,24: DRAW 0,58
95 INK 7: FOR i=1 TO 11: PRINT AT i,3;"- ";210-10*i: NEXT i
100 INK 7: PRINT AT 1,15;"AWFUL ANAGRAM";AT 3,12;"\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::";AT 7,12;"\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::": FOR i=4 TO 6: PRINT AT i,12;"\::";AT i,30;"\::": NEXT i: PRINT AT 5,14;x$
110 INK 6: PRINT AT 10,15;"YOUR ATTEMPT";AT 12,12;"\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::";AT 16,12;"\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::": FOR I=13 TO 15: PRINT AT i,12;"\::";AT i,30;"\::": NEXT i: PRINT AT 14,14;p$
115 PRINT INK 6;AT 15,14;"123456789012345"
120 INK 7: PRINT AT 18,12;" ";AT 19,12;" "
130 INPUT "Enter letter: ";l$;",position:";p
140 IF p<>INT p OR p<1 OR p>l OR p>LEN w$ THEN INPUT (p;" is invalid. Reenter position:");p: GO TO 140
150 IF w$(p)<>l$ THEN GO TO 190
160 LET c=c+1: LET p$(p)=l$: PRINT AT 14,14; INK 6;p$
170 IF c=l THEN PRINT AT 16,12;"YOU ARE FREE!": GO TO 220
180 GO TO 120
190 LET t=t+10: DRAW INK 7;0,8: IF t=200 THEN PRINT AT 18,12;"You've failed - the";AT 19,12;"cauldron shakes...": FOR i=-25 TO 25: BEEP 0.1,i: NEXT i: PRINT AT 0,0;: FOR i=1 TO 704: PRINT INVERSE 1;" ";: NEXT i: BORDER 0: GO TO 220
200 IF t=190 THEN PRINT AT 18,12; FLASH 1;"Cauldron is very hot": PAUSE 200
210 GO TO 120
220 INPUT "key 1 fo repeat, 0 to stop:"; LINE z$: IF z$="1" THEN RUN
225 BORDER 0: PAPER 0: INK 7: CLS
230 STOP
9997 STOP
9998 SAVE "ANAGRAMS" LINE 1
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
