--- title: "Hangman" id: 56685 type: "computer_media" slug: "hangman" url: "http://localhost/computer_media/hangman/" markdown_url: "http://localhost/computer_media/hangman.md" published_at: "2024-09-22T23:31:42+00:00" modified_at: "2026-03-30T21:21:50+00:00" author: "David Anderson" featured_image: url: "http://localhost/wp-content/uploads/2024/09/Hangman.jpg" excerpt: "A tape-saveable word library powers this Hangman game, where a clever computed GO TO draws each body part as your guesses run out." 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: "Softsync" slug: "softsync" taxonomy: "post_tag" url: "http://localhost/tag/softsync/" - 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_type: "Cassette" download_url: "https://archive.org/download/timex-sinclair-software-archive/Hangman%20%281983%29%28Softsync%20T.J.%20Software%29%28TS1000%29%28US%29%28Cassette%29.zip" mediadate: "1983" producer_company: - id: 11319 title: "Softsync, Inc." type: "company" url: "http://localhost/company/softsync/" images: - url: "http://localhost/wp-content/uploads/2024/09/Hangman.jpg" - url: "http://localhost/wp-content/uploads/2024/09/Hangman1-scaled.jpg" - url: "http://localhost/wp-content/uploads/2024/09/Hangman2.jpg" - url: "http://localhost/wp-content/uploads/2024/09/Hangman3.jpg" - url: "http://localhost/wp-content/uploads/2024/09/Hangman4.jpg" related_products: - id: 12804 title: "Hangman" type: "product" url: "http://localhost/product/hangman/" media_type_tags: "Game" --- This program implements a two-part Hangman word game: a word-library builder and the game itself. The builder accepts up to 999 words of up to 17 characters each, stores them in a DIM B$ array, and saves the library to tape under a user-supplied name. During gameplay, a gallows and hangman figure are drawn using block graphics at fixed screen positions, with body parts added by computed GO TO at line 620 (GOTO (80+20*K)), which jumps to lines 120, 160, 200, 240, 280, and 320 for head, body, right arm, left arm, right leg, and left leg respectively. Words are chosen pseudo-randomly with a repetition-avoidance buffer V(R+1), where R is either 50 or INT(D/2) for small libraries. Scores for both the player and the computer are tracked across games within a single session. *** ## Program Analysis ### Program Structure The program divides into three logical phases: 1. **Introduction & library builder** (lines 1–28): splash screens, word entry loop, tape save. 2. **Game initialisation** (lines 50–100): randomisation, score reset, repetition buffer setup, jump to game loop. 3. **Game loop** (lines 120–745): gallows drawing, word selection, guessing, hangman body-part routines, win/lose handling. 4. **Tape save helper** (lines 800–820): waits for the recorder, saves the library, then prints reload instructions. ### Word Library and Storage The user specifies the library size `D` at line 12, and a `DIM B$(D,17)` at line 13 allocates a fixed-width string array of 17 characters per word. Words are entered one at a time in the loop at lines 15–18. After entry, the program trims each word at runtime (lines 389–399) by scanning for the first trailing space and slicing with `W$(1 TO I-1)`, then re-padding to 17 characters for consistent comparison. The repetition-avoidance buffer `V(R+1)` (line 95) holds the indices of recently used words. `R` is set to 50 by default (line 19) or `INT(D/2)` for libraries of fewer than 100 words (line 20), preventing the same word appearing too soon in a session. ### Computed GO TO for Hangman Drawing The most technically notable feature is the dispatch at line 620: `620 GOTO (80+20*K)` `K` is incremented by 2 on each wrong guess (line 600), so the targets are: | K value | Target line | Body part drawn | | --- | --- | --- | | 2 | 120 | Head | | 4 | 160 | Body | | 6 | 200 | Right arm | | 8 | 240 | Left arm | | 10 | 280 | Right leg | | 12 | 320 | Left leg / game over | Each drawing routine ends with `GOTO 500` (return to input prompt) except line 320 onwards, which falls to line 361 `GOTO 680` (you lose). This is an efficient alternative to a series of `IF K=n THEN GOSUB` statements and avoids the need for subroutines. ### Gallows and Block Graphics The gallows scaffold is drawn at lines 366–375 using ZX81 block graphic characters. The horizontal beam at line 368 uses `\''` (▀) characters, the vertical post at lines 370–372 uses `%` (a block fill), and the ground line at 373 spans the full width. The hangman’s head at line 120 uses a combination of `\:'`, `\':`, and `\''` to form a crude circular shape. The library name `C$` is centred on the gallows beam: line 60 computes `J=22-INT((LEN L$)/2)` and line 376 prints it at column `J`. ### Letter-Guessing Logic The guess display string `G$` (17 spaces initially) is updated as correct letters are found (line 540 `LET G$(I)=A$`). The underscore dashes are drawn as `\.` block graphics at line 430. A win is detected by comparing `G$=W$` at line 580, which works because both are padded to 17 characters. Wrong guesses are accumulated in `R$` (a 13-character string) at lines 610–615, printed at lines 617–618. The string stores a space before each dud letter for readability, which is why `K` advances by 2 per wrong answer and indexes into `R$` with `R$(K-1)` and `R$(K)`. Line 506 uses `INKEY$` after `PAUSE 750` rather than `INPUT`, giving the player 750 frames to press a key. If no key is pressed (space returned), line 510 jumps to line 600, treating it as a forfeit/wrong answer — an unusual design choice that could penalise slow typists. ### Asterisk Masking Lines 451–455 scan `W$` for asterisk characters (`"*"`) and replace them with spaces, also blanking the corresponding dash on screen. This provides a mechanism for words containing spaces or for the library creator to pre-mask certain positions, though the game does not document this feature to the player. ### Scoring `SP` (player wins) and `SC` (computer/machine wins) are initialised at line 85 and 85 respectively, and persist across rounds within a session. They are displayed at lines 695–696 after each round. Choosing `N` at the play-again prompt (line 740) jumps to line 1100, which does not exist — a deliberate end-of-program technique that halts execution cleanly. ### Tape Save Workflow Lines 800–820 implement the save sequence: `PAUSE 40000` (approximately 11 minutes of wait time — clearly intended to be interrupted earlier) followed by `SAVE L$` using the user-supplied library name. After saving, the program prints instructions to reload and start the game by typing `GOTO 50`, which skips the builder entirely and enters the game loop directly. ### Potential Anomalies - Line 330 is an exact duplicate of line 320 (`PRINT AT 12,4;"% "`), suggesting a copy-paste error in the left-leg drawing routine — the left leg appears to start one row higher than intended and re-prints the same cell. - The `PAUSE 750` / `INKEY$` input method at lines 502–506 gives a fixed time window per guess rather than waiting indefinitely, which may frustrate players thinking at the prompt. - Line 24 rejects library names longer than 17 characters by looping back to line 22, but the on-screen prompt is not re-cleared, causing it to overprint if the user submits a long name. - The word trimming loop at lines 389–391 has an off-by-one risk: if a word exactly fills all 17 characters with no trailing space, `NEXT I` exits with `I=18`, and `W$(1 TO I-1)` equals `W$(1 TO 17)`, which is correct — so this edge case is handled safely. ## Source Code ``` 1 SLOW 2 PRINT AT 11,2;"A T.J. SOFTWARE PRODUCTION" 3 PAUSE 200 4 CLS 5 PRINT AT 11,9;"COPYRIGHT 1982";AT 13,6;"ALL RIGHTS RESERVED" 6 PAUSE 200 7 CLS 11 PRINT "ENTER NO. OF WORDS IN LIBRARY" 12 INPUT D 13 DIM B$(D,17) 14 PRINT AT 0,0;"ENTER LIBRARY WORDS AS REQUESTED";AT 5,12;"WORD NO." 15 FOR I=1 TO D 16 PRINT AT 5,21;I 17 INPUT B$(I) 18 NEXT I 19 LET R=50 20 IF D<100 THEN LET R=INT (D/2) 21 CLS 22 PRINT AT 0,0;"LIBRARY COMPLETE, READY TO SAVE";AT 5,7;"ENTER LIBRARY NAME";AT 6,8;"(17 LETTERS MAX)" 23 INPUT L$ 24 IF LEN L$>17 THEN GOTO 22 25 LET C$=L$ 26 CLS 27 PRINT AT 10,7;"START YOUR RECORDER";AT 12,9;"THEN PRESS ENTER" 28 GOTO 800 29 CLS 50 RAND 60 LET J=22-INT ((LEN L$)/2) 80 LET SP=0 85 LET SC=0 90 LET Y=0 95 DIM V(R+1) 100 GOTO 365 120 PRINT AT 4,4;"\:'% \':" 130 PRINT AT 5,4;"% \''% " 140 PRINT AT 6,4;"\ '% \' " 150 GOTO 500 160 FOR I=7 TO 12 170 PRINT AT I,5;"% " 180 NEXT I 190 GOTO 500 200 PRINT AT 8,6;"% % % " 210 PRINT AT 9,8;"% " 220 PRINT AT 10,8;"% " 230 GOTO 500 240 PRINT AT 8,2;"% % % " 250 PRINT AT 9,2;"% " 260 PRINT AT 10,2;"% " 270 GOTO 500 280 PRINT AT 12,6;"% " 290 PRINT AT 13,7;"% " 300 PRINT AT 14,8;"% " 310 PRINT AT 15,8;"% " 315 GOTO 500 320 PRINT AT 12,4;"% " 330 PRINT AT 12,4;"% " 340 PRINT AT 13,3;"% " 350 PRINT AT 14,2;"% " 360 PRINT AT 15,2;"% " 361 GOTO 680 365 SLOW 366 CLS 367 PRINT AT 0,18;"HANGMAN" 368 PRINT AT 1,18;"\''\''\''\''\''\''\''" 369 PRINT AT 1,5;"% % % % % % % % " 370 FOR I=2 TO 16 371 PRINT AT I,12;"% " 372 NEXT I 373 PRINT AT 17,0;"% % % % % % % % % % % % % " 374 PRINT AT 2,5;"\: " 375 PRINT AT 3,5;"\: " 376 PRINT AT 3,J;C$ 380 LET I=INT ((RND*D)+1) 382 FOR T=1 TO R 383 IF I=V(T) THEN GOTO 380 384 NEXT T 385 LET Y=Y+1 386 IF Y=R+1 THEN LET Y=1 387 LET V(Y)=I 388 LET W$=B$(I) 389 FOR I=1 TO 17 390 IF W$(I)=" " THEN GOTO 392 391 NEXT I 392 LET W$=W$(1 TO I-1) 397 LET G$=" " 398 LET X=LEN W$ 399 LET W$=W$(1 TO X)+G$(X+1 TO 17) 400 PRINT AT 5,16;"HERE IS YOUR " 410 PRINT AT 6,20;"WORD:" 420 FOR I=15 TO 14+X 430 PRINT AT 10,I;"\. " 440 NEXT I 450 FOR I=1 TO X 451 IF W$(I)="*" THEN GOTO 454 452 NEXT I 453 GOTO 475 454 LET W$(I)=" " 455 PRINT AT 10,14+I;" " 475 LET R$=" " 490 LET K=0 500 PRINT AT 13,16;"ENTER A LETTER" 502 PAUSE 750 506 LET A$=INKEY$ 508 IF A$<>" " THEN GOTO 515 510 GOTO 600 515 LET Z=0 520 FOR I=1 TO X 530 IF A$<>W$(I) THEN GOTO 560 540 LET G$(I)=A$ 550 LET Z=1 560 NEXT I 570 PRINT AT 9,15;G$ 580 IF G$=W$ THEN GOTO 690 590 IF Z=1 THEN GOTO 500 600 LET K=K+2 610 LET R$(K-1)=" " 615 LET R$(K)=A$ 617 PRINT AT 20,1;"DUD LETTERS:" 618 PRINT AT 21,0;R$ 620 GOTO (80+20*K) 680 PRINT AT 15,19;"YOU LOSE" 681 LET SC=SC+1 682 PRINT AT 16,16;"THE ANSWER IS:" 684 PRINT AT 18,15;W$ 685 GOTO 695 690 PRINT AT 17,19;"YOU WIN" 691 LET SP=SP+1 695 PRINT AT 20,18;"SCORE: YOU ";SP 696 PRINT AT 21,25;"ME ";SC 700 PAUSE 400 710 CLS 720 PRINT AT 11,11;"PLAY AGAIN?" 725 PRINT AT 12,14;"(Y/N)" 730 INPUT A$ 735 CLS 740 IF A$="N" THEN GOTO 1100 745 GOTO 365 800 PAUSE 40000 805 CLS 810 SAVE L$ 820 PRINT AT 10,9;"TO START TYPE:";AT 12,12;"GOTO 50";AT 14,8;"THEN PRESS ENTER" ```