Awful Anagram

Date: 198x
Type: Program
Platform(s): TS 2068
Tags: Game

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:

  1. Initialization (lines 5–10): Sets display attributes and the word count n=10.
  2. Word selection (lines 20–30): Restores the DATA pointer and reads a random entry from the list.
  3. Setup (lines 40–60): Calculates word length, allocates string arrays, initializes the progress string p$ with dashes, and shuffles the word into x$.
  4. Screen drawing (lines 70–115): Renders the thermometer, borders, anagram display box, and guess box using block graphics.
  5. Game loop (lines 120–210): Accepts letter/position input, validates it, updates state, and branches on win or loss.
  6. 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

VariableInitial ValueChange per Wrong GuessTrigger
t100+10Reaches 200 → game over
c0+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 uppercase I for its FOR loop, then references lowercase i inside 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: t starts 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 than GO TO 10) to restart, which correctly re-initializes all variables but also re-executes the attribute setup at line 5.

Content

Related Products

Related Articles

Related Content

Image Gallery

Awful Anagram

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.

People

No people associated with this content.

Scroll to Top