This two-player word game presents scrambled five-letter words and challenges each player to reconstruct the original word by typing letters one at a time. The program stores a dictionary of 200 five-letter words as a single concatenated string in lines 780–830, accessing each word with the slice expression `A$(5*Q-4 TO 5*Q)`. A countdown timer starting at 61 ticks down via subroutine calls on each INKEY$ polling loop, with points awarded equal to the remaining time value, rewarding faster answers. The scrambling routine at lines 320–370 destructively marks used character positions with “0” to avoid reuse, building the anagram display left to right. Ten rounds per player are tracked by a single shared counter `S`, with odd values belonging to player 1 and even values to player 2.
Program Analysis
Program Structure
The program is divided into clearly identifiable functional blocks:
- Lines 10–90: Title screen and instructions
- Lines 100–160: Initialisation (scores, player names)
- Lines 170–217: Turn management and random seeding delay loops
- Lines 220–370: Word selection and scrambling
- Lines 376–550: Letter-by-letter input loop with countdown
- Lines 560–715: Scoring, round display, and game flow
- Lines 720–725: Game-over handling
- Lines 730–744: Time-out handler
- Lines 750–770: Countdown timer subroutine
- Lines 780–850: Word dictionary data
- Lines 900–910: Border-drawing subroutine
- Lines 920–940: Save/run bootstrap
Word Dictionary
All words are stored as a single concatenated string across lines 780–830. Each word is exactly five characters, so word Q is retrieved with the slice A$(5*Q-4 TO 5*Q). The string is built in stages because a single BASIC line cannot hold all ~200 words. A random index Q is chosen at line 220 with INT(200*RND)+1. Note the dictionary contains some duplicates (e.g. “FRONT” appears in both lines 780 and 820, “SWEET” in lines 810 and 820, “FLOAT” in lines 810 and 820, “OTHER” in lines 780 and 820, “LOWER” in lines 780 and 820, “ORDER” in lines 780 and 820, “CARRY” in lines 780 and 820) — the instructions even acknowledge this: “some words may appear more than once.”
Scrambling Algorithm
The scrambling routine (lines 320–370) works destructively on a copy B$ of the chosen word:
- A random position
Rfrom 1–5 is chosen. - If
B$(R)is already"0"(previously used), the loop retries at line 330. - The character is appended to
C$with a trailing space, then the source position is set to"0". - The original unscrambled word is preserved in
D$for answer checking.
This is a straightforward pick-without-replacement shuffle. For words with repeated letters (e.g. “LEVEL”), the "0" sentinel approach still works correctly because each character position — not character value — is independently nulled.
Countdown Timer
The variable G is initialised to 61 at line 375. Every time an INKEY$ poll returns empty, the subroutine at line 750 is called, which decrements G by 1 and prints the updated value at position AT 2,27. When G reaches 0 or below, execution jumps to line 730 (time-out handler). Because G is also the points awarded on a correct answer, faster solutions yield higher scores — a neat dual-purpose variable.
Input Loop Design
Each of the five letters is handled by a separate, near-identical block (lines 390–550). Each block polls INKEY$ in a tight loop, calling the timer subroutine on each empty read. Letters are printed at fixed screen positions (AT 10,10 through AT 10,18 in steps of 2). There is no backspace facility by design, as stated in the instructions. The small FOR–NEXT loops (e.g. lines 435–436) serve as very brief delays after each keypress is registered.
| Letter | Variable | Screen position |
|---|---|---|
| 1st | V$ | AT 10,10 |
| 2nd | W$ | AT 10,12 |
| 3rd | X$ | AT 10,14 |
| 4th | Y$ | AT 10,16 |
| 5th | Z$ | AT 10,18 |
Two-Player Turn Tracking
A single shared counter S increments on every completed word (line 580 or 740). Odd values of S represent player 1’s words and even values player 2’s. The test IF S/2=INT(S/2) distinguishes even (player 2) from odd (player 1). After 20 total words (10 each) the game ends. Turn routing after player 2’s word jumps back to line 170 (player 1’s turn label) via line 715, while after player 1’s word it jumps to line 190 (player 2’s turn label) at line 645.
Random Seed Warm-Up
Lines 203–217 use nested FOR–NEXT loops with a fresh RAND call and RND-driven loop counts to consume an unpredictable number of RND iterations before selecting the word. This is a common technique to improve perceived randomness when the hardware RND seed is otherwise predictable at program start.
Notable Bugs and Anomalies
- Line 573 calls
GOSUB 900(border drawing) after a wrong answer, then line 574 prints AT 2,0 and falls through to line 380, which re-displays the scrambled word — this means a wrong-answer retry correctly redraws the border and word without re-scrambling, which is the intended behaviour. - The variable
Xis used as both the loop variable in the delay loops (lines 435–436, 465–466, 495–496, 525–526) and as the variable name for the third letter. This is not an error per se — the delay loops useFOR XandNEXT Xonly for timing and do not needXto retain its value — but it is a potential source of confusion. - Line 680 prints
PRINT AT 3,12;"ROUND ";INT(S/2)for player 2, while line 620 printsINT(S/2)+1for player 1. This means the round number display for player 2 is one behind; at S=2 (end of round 1), player 2 sees “ROUND 1” while player 1 saw “ROUND 1” too — this is actually consistent. At S=20, lines 673–675 skip the round display entirely. - The variable
Qis reused for both the word index (line 220) and the delay loop counter (lines 635–640, 700–705), which is safe only because the delay loop is not inside the word-selection section. - Line 572 calls
GOSUB 900before a retry, but line 202 also callsGOSUB 900at the start of each turn, so the border is correctly maintained throughout.
Subroutine at Line 900
This subroutine draws a simple rectangular border using inverse-video asterisks and spaces via three PRINT AT statements. The border occupies rows 9–11, columns 9–19, providing a visual frame for the timer display and input area. Inverse characters are rendered using the %* and % escape notation in the source.
Content
Source Code
10 PRINT AT 8,8;"%S%C%R%A%M%B%L%E%D %W%O%R%D%S";AT 10,3;"DO YOU NEED INSTRUCTIONS?"
20 IF INKEY$="" THEN GOTO 20
30 IF INKEY$="N" THEN GOTO 100
40 CLS
50 PRINT " THE OBJECT OF THIS GAME IS TO UNSCRAMBLE A 5 LETTER WORD AS SOON AS YOU CAN. THE QUICKER YOU CAN DO THIS, THE MORE POINTSWILL BE ADDED TO YOUR SCORE. YOUARE GIVEN 60 SECONDS FOR EACH WORD."
60 PRINT " A SAMPLE WOULD BE:::",,,"%C%R%A%H%M COULD BE %M%A%R%C%H OR %C%H%A%R%M",,,
70 PRINT " JUST TYPE IN THE LETTERS ONE AT A TIME. THE COMPUTER WILL BE ABLE TO TELL IF YOUR WORD IS CORRECT AFTER YOU PRESSED THE LAST LETTER.",," IF YOU MAKE A MISTAKE, FINISHTHE WORD - YOU CANNOT BACKSPACE."
80 PRINT " SOME WORDS MAY APPEAR MORE THAN ONCE AND CAN EVEN BE IN ORDER. TWO PLAYERS WILL HAVE 10 WORDS EACH. PRESS ANY KEY."
90 IF INKEY$="" THEN GOTO 90
100 CLS
102 LET S=0
104 LET P1=0
106 LET P2=0
110 PRINT "WHAT IS THE FIRST PLAYER,S NAME?"
120 INPUT F$
130 PRINT "WHAT IS THE 2ND PLAYER,S NAME?"
140 INPUT S$
160 CLS
170 PRINT F$;",S TURN"
180 GOTO 202
190 CLS
200 PRINT S$;",S TURN"
202 GOSUB 900
203 RAND
205 FOR I=1 TO INT (5*RND+6*RND)
210 FOR Q=1 TO INT (5*RND+6*RND+7*RND+8*RND)
215 NEXT Q
217 NEXT I
220 LET Q=INT (200*RND)+1
230 GOSUB 780
240 LET B$=A$(5*Q-4 TO 5*Q)
250 LET C$=""
260 LET D$=B$
320 FOR I=1 TO 5
330 LET R=INT (5*RND)+1
340 IF B$(R)="0" THEN GOTO 330
350 LET C$=C$+B$(R)+" "
360 LET B$(R)="0"
370 NEXT I
375 LET G=61
376 PRINT AT 2,0;"";
380 PRINT C$
390 LET V$=INKEY$
400 IF V$="" THEN GOSUB 750
410 IF V$="" THEN GOTO 390
430 PRINT AT 10,10;V$;" "
435 FOR X=1 TO 5
436 NEXT X
440 LET W$=INKEY$
450 IF W$="" THEN GOSUB 750
455 IF W$="" THEN GOTO 440
460 PRINT AT 10,12;W$;" "
465 FOR X=1 TO 5
466 NEXT X
470 LET X$=INKEY$
480 IF X$="" THEN GOSUB 750
485 IF X$="" THEN GOTO 470
490 PRINT AT 10,14;X$;" "
495 FOR X=1 TO 5
496 NEXT X
500 LET Y$=INKEY$
510 IF Y$="" THEN GOSUB 750
515 IF Y$="" THEN GOTO 500
520 PRINT AT 10,16;Y$;" "
525 FOR X=1 TO 10
526 NEXT X
530 LET Z$=INKEY$
540 IF Z$="" THEN GOSUB 750
545 IF Z$="" THEN GOTO 530
550 PRINT AT 10,18;Z$
560 IF D$=V$+W$+X$+Y$+Z$ THEN GOTO 580
570 CLS
572 GOSUB 900
573 PRINT AT 2,0;"";
575 GOTO 380
580 LET S=S+1
582 IF S/2=INT (S/2) THEN GOTO 650
590 LET P1=P1+G
600 PRINT AT 19,10;"CORRECT"
610 PRINT ,,"YOU SCORE ";G;" POINTS"
620 PRINT AT 3,12;"ROUND ";INT (S/2)+1
630 PRINT ,,F$;" ";P1,,S$;" ";P2
635 FOR Q=1 TO 100
640 NEXT Q
645 GOTO 190
650 LET P2=P2+G
660 PRINT AT 19,10;"CORRECT"
670 PRINT ,,"YOU SCORE ";G;" POINTS"
673 IF S=20 THEN PRINT AT 3,0;,,
675 IF S=20 THEN GOTO 690
680 PRINT AT 3,12;"ROUND ";INT (S/2)
690 PRINT ,,F$;" ";P1,,S$;" ";P2
700 FOR Q=1 TO 100
705 NEXT Q
710 IF S=20 THEN GOTO 720
713 CLS
715 GOTO 170
720 PRINT "GAME OVER"
725 STOP
730 PRINT AT 15,0;"OUT OF TIME - THE WORD WAS ";D$
740 LET S=S+1
742 IF S/2=INT (S/2) THEN GOTO 680
744 GOTO 620
750 LET G=G-1
754 PRINT AT 2,27;G;" "
760 IF G<=0 THEN GOTO 730
770 RETURN
780 LET A$="LEASEFIRSTMONTHMONEYTOUCHBRANDTRULYVALUERANGEMUSICLEVELMETERPOINTTOTALPANELAMPLESOUNDTHERETHREEENJOYBUILTSHORTCOULDCLEANPROOFFLOORINDEXPRICEBOARDCABLECLOCKTABLESMOKENOISELOWERBASICAUDIOFRONTWHILERATIOIMAGE"
790 LET A$=A$+"FRONTOTHERIDEALSTOREPOWERWOMENMAGICGLOBEMODELPRINTTOWERCOVEREIGHTGLIDEWATERTODAYPIZZAMETALSHELFDRIVECLASSGREATLIGHTSCALESTYLEBREADDRINKPHONESHAPEGREENGLASSSAUCEHEARTSLICEONIONSTEAMLARGESTACK"
800 LET A$=A$+"CREAMCRUSTSALADEXTRAORDERBACONBLACKOLIVESMALLSPEARSCREWSEVENDOUGHFLOATHEARDSOLIDHEAVYCRISPPUNCHSENSEPINCHSTANDEVERYSHOCKVINYLMAPLEWOVENGRAINSKATEFORCECOLORPIECEANGLEPITCHWORTHABOUTWEIGHCANDYCHECKHANDY"
810 LET A$=A$+"SWEEPPATCHWAGONTRUCKPOUNDTOWELPAPERQUIETSPACERADIOTHESECARRYALONGREADYWHEREALARMPAUSETIMERCLOTHSHACKSTICKERASEALBUMSTARTLAPELWHITEDELAYEJECTSLIDEIDEALMINUSGRAPHFLOATQUICKBLANKSWEETNYLON"
820 LET A$=A$+"COCAOCARGOSWEETRELAYPROBESLOPESLEEPCOUNTLOGICMOUNTDECALORDERTORCHSPADELABELROUNDWAFERCARRYLOWERTEACHAGAINMOTORMAJORLEARNORGANGRIPEEAGLEGAUGEMATCHAWARETRUNKCLAMPOTHERWOULDLIMITSWINGWRIST"
830 LET A$=A$+"LEASHPAYEERAVENFORTECREPEMANIATAWNY"
850 RETURN
900 PRINT AT 9,9;"%*%*%*%*%*%*%*%*%*%*%*";AT 10,9;"%*% % % % % % % % % %*";AT 11,9;"%*%*%*%*%*%*%*%*%*%*%*"
910 RETURN
920 CLEAR
930 SAVE "1031%1"
940 RUN
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
