--- title: "Awful Anagram" id: 55180 type: "computer_media" slug: "awful-anagram" url: "http://localhost/computer_media/awful-anagram/" markdown_url: "http://localhost/computer_media/awful-anagram.md" published_at: "2024-06-20T11:49:56+00:00" modified_at: "2026-03-30T21:41:01+00:00" author: "David Anderson" featured_image: url: "http://localhost/wp-content/uploads/2019/02/20230809-041332.jpg" excerpt: "Race to unscramble ten tricky words and phrases before a rising thermometer graphic reaches the top and the cauldron boils over." 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/" genre: - name: "Game" slug: "game" taxonomy: "genre" url: "http://localhost/type/game/" media_contents: - id: 55220 title: "Long Island Sinclair Timex (LIST) User Group Library Tape #7" type: "computer_media" url: "http://localhost/computer_media/long-island-sinclair-timex-list-user-group-library-tape-7/" media_type: "Program" download_url: "https://archive.org/download/timex-sinclair-software-archive/Awful%20Anagram%20%28198x%29%28TS2068%29%28US%29%28Program%29.zip" mediadate: "198x" images: - url: "http://localhost/wp-content/uploads/2024/06/Awful-Anagram.png" media_type_tags: "Game" --- # Awful Anagram 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 | 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 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. ## 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 ```