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:
- Introduction & library builder (lines 1–28): splash screens, word entry loop, tape save.
- Game initialisation (lines 50–100): randomisation, score reset, repetition buffer setup, jump to game loop.
- Game loop (lines 120–745): gallows drawing, word selection, guessing, hangman body-part routines, win/lose handling.
- 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 Iexits withI=18, andW$(1 TO I-1)equalsW$(1 TO 17), which is correct — so this edge case is handled safely.
Content
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"
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.




