This is a text-based cave-exploration adventure game for one player, who assembles a two-member party from five named companions before navigating through nine numbered caves to escape with treasure. Each cave presents a randomly determined encounter — including a ghost, sand troll, wild wolf, poisoned gas, mysterious bottles, chests of gems, treasure maps, or sacks of unknown contents — with outcomes driven by a 1–16 random number generator in subroutine 8000. The game tracks three party statistics (cash, strength, and magic power) and computes a final score as 10×CASH + 20×S + 30×P upon reaching cave 10. Cave interiors are rendered with a simple box diagram using ZX81-style block graphics, and the current exit direction is marked with an inverse-video asterisk inside the box.
Program Analysis
Program Structure
The program is divided into clearly separated functional blocks by line-number ranges:
- Lines 5–350: Initialisation, SLOW mode, and sanity-clamp guards on all state variables.
- Lines 1100–3240: Status display — party members, statistics, score, and a block-graphic cave map with directional marker.
- Lines 5100–5240: Main game loop — direction input, dispatch via computed GOSUB, delay loop, and return to line 300.
- Lines 5513–5900: Individual encounter subroutines, each returning with
RETURN. - Lines 7000–7999: Win sequence with congratulations, final score, and a decorative inverse-character border.
- Lines 8000–8020: Core random-number subroutine; returns a value 1–16 in
D. - Lines 8210–8557: Party-selection screen and five hire subroutines (one per companion).
- Lines 9500–9930: Variable initialisation, array setup, game entry, and SAVE with auto-run flag.
Computed GOSUB Dispatch
The encounter system at line 5230 uses a calculated target:
IF D>2 AND D<15 THEN GOSUB 5480+20*D
With D ranging from 3 to 14, this maps to subroutines at 5540, 5560, 5580, 5600, 5620, 5640, … , 5740. Lines below 3 trigger a chest encounter (line 5221 dispatches to 5513), and values above 14 trigger the sack encounter (line 5225 dispatches to 5780). This is a common ZX81/TS1000 BASIC technique for replacing ON…GOSUB with arithmetic.
Similarly, party hiring uses GOSUB 8500+10*G(W) at line 8390, dispatching to one of five subroutines (8510–8550) based on the player’s menu choice stored in array G(2).
State Variables
| Variable | Meaning |
|---|---|
CAVE | Current cave number (1–9); reaching 10 triggers the win state |
CASH | Treasure carried, in dollars |
S | Combined party strength |
P | Combined party magic power |
D | Current random roll (1–16), reused across encounters |
D$ | Current exit direction chosen (N/S/E/W) |
A$, B$ | Names of the two hired companions (may acquire prefixes like “WOUNDED ” or “BATTERED “) |
G(2) | Two-element integer array holding party hire choices |
K | Player’s sack choice (input but never used in outcome logic) |
Cave Map Rendering
Lines 3120–3240 draw a simple rectangular room using ZX81 block-graphic characters. The four walls are drawn with \:.., \'', \ :, and \.. escape sequences. Depending on D$, an inverse-video asterisk (%*) is printed on the north, south, east, or west wall segment to indicate the chosen exit direction. The cave number itself is rendered using CHR$(CAVE+156), exploiting the ZX81 character set where codes 157–165 map to the inverse digits 1–9.
Delay Loops
Several subroutines use busy-wait FOR…NEXT loops for pacing. Line 5236–5237 use 150 iterations as a universal “STAND BY” pause, while lines 5546–5547 and 5562–5564 use 125 iterations for dramatic effect before a random outcome is revealed. Line 5603 uses PAUSE 15*D, making the wait duration proportional to the random roll — a subtle tension-building device.
Bugs and Anomalies
- Lines 5565–5572 numbering gap: Line 5566 follows 5565 with a conditional — but line 5565 itself is only a
RETURN, so control never reaches 5566–5572 naturally. The treasure-map subroutine at 5560 effectively ends at 5565 before the outcome logic runs. This appears to be a cut-and-paste error where the outcome code was displaced from the subroutine it belongs to. - Variable
Kis unused: The player inputs their sack choice intoKat line 5786, butKis never referenced again; the outcome depends solely on the subsequent random roll. The input serves only as an in-universe dramatic beat. - Line 5568 unreachable: The condition
IF D<11at 5568 contradicts the immediately precedingIF D<11at 5567 (which already printed the “faded” message); both refer to the sameDfrom subroutine 8000. This double-branch is logically redundant but harmless. - CASH can go negative: The sand-troll encounter (lines 5586) subtracts
10*DfromCASHwithout a floor guard; CASH can become deeply negative, though the sanity clamp at line 320 only resets it to 0 at the top of the display loop. - Line 8200 vs 8210: Initialisation calls
GOSUB 8200at line 9890, but the party-selection subroutine starts at line 8210. Line 8200 does not exist, so execution falls through to 8210. This is a valid ZX81 BASIC behaviour (jump to next higher line) and functions correctly.
Scoring Formula
The score is computed identically at lines 3100 and 7090 as 10*CASH + 20*S + 30*P, weighting magic power most heavily and raw cash least. This incentivises hiring companions with high magic (e.g. Merlin with P=10) over pure fighters, since each magic point is worth three times a dollar of treasure in the final tally.
Content
Source Code
5 SLOW
10 RAND
100 GOSUB 9500
300 CLS
310 IF CAVE<1 THEN LET CAVE=1
320 IF CASH<1 THEN LET CASH=0
330 IF S<1 THEN LET S=0
340 IF P<1 THEN LET P=0
350 IF CAVE>9 THEN GOTO 7000
\n1100 PRINT "%Y%O%U% %A%R%E% %I%N% %C%A%V%E% %N%U%M%B%E%R%:";CHR$ (156+CAVE)
\n1120 IF CASH>0 THEN PRINT "YOUR PARTY IS CARRYING","$";CASH;" WORTH OF TREASURE"
\n1140 PRINT " ";A$;" AND ";B$
\n1145 PRINT TAB (8);"ARE WITH YOU"
\n1150 PRINT "YOUR TOTAL STRENGTH IS ";S
\n1160 PRINT "YOUR COMBINED %M%A%G%I%C% %P%O%W%E%R IS ";P
\n3100 PRINT ,"POINTS: ";10*CASH+20*S+30*P
\n3120 PRINT TAB (8);"\..\..\..\: \ :\..\..\.."
\n3130 IF D$="S" THEN PRINT TAB (8);"\: %* \ :"
\n3150 PRINT TAB (8);"\: ";CHR$ (CAVE+156);" \ :"
\n3170 IF D$="E" THEN PRINT TAB (8);"\'' %* \''\''"
\n3190 IF D$="W" THEN PRINT TAB (8);"\'' %* \''\''"
\n3200 IF D$<>"W" AND D$<>"E" THEN PRINT TAB (8);"\'' \''\''"
\n3210 PRINT TAB (8);"\.. \..\.."
\n3220 PRINT TAB (8);"\: \ :"
\n3230 IF D$="N" THEN PRINT TAB (8);"\: %* \ :"
\n3240 PRINT TAB (8);"\''\''\''\: \ :\''\''\''"
\n5100 PRINT " WHICH EXIT (N,S,E,W)?"
\n5120 INPUT D$
\n5125 IF D$="U" THEN STOP
\n5210 CLS
\n5220 GOSUB 8000
\n5221 IF D<3 THEN GOSUB 5513
\n5225 IF D>14 THEN GOSUB 5780
\n5230 IF D>2 AND D<15 THEN GOSUB 5480+20*D
\n5232 PRINT ,,,"%-%-%-%S%T%A%N%D% %B%Y%-%-%-"
\n5235 LET X=0
\n5236 FOR X=1 TO 150
\n5237 NEXT X
\n5240 GOTO 300
\n5513 PRINT "AHEAD OF YOU IS A CHEST"
\n5514 GOSUB 8000
\n5515 PRINT "IT CONTAINS ";D/2;" KG OF GEMS"
\n5516 PRINT "YOUR AVAILABLE STRENGTH IS ";S
\n5517 PRINT "(THE MOST YOU CAN TAKE IS ";INT (S/4);")"
\n5520 PRINT "HOW MUCH WILL YOU TAKE ?"
\n5521 INPUT DD
\n5522 IF DD>D/2 OR DD>INT (S/4) THEN GOTO 5521
\n5523 LET S=S-DD
\n5524 LET CASH=CASH+2.5*DD
\n5539 RETURN
\n5540 PRINT "YOU ARE FACE TO FACE WITH THE"
\n5542 PRINT " GHOST OF %L%O%N%G %J%O%H%N %S%I%L%V%E%R..."
\n5544 PRINT "WILL HE HARM YOU ?"
\n5545 LET X=0
\n5546 FOR X=1 TO 125
\n5547 NEXT X
\n5548 GOSUB 8000
\n5549 IF D>8 THEN PRINT "YES...HE STRIKES..."
\n5550 IF D>8 THEN PRINT "AND ";A$;" IS INJURED"
\n5551 IF D>8 THEN LET S=S-2
\n5552 IF D>16 THEN LET P=P-1
\n5553 IF D<9 THEN PRINT "NO, HE HAS TURNED AWAY","YOU MAY PROCEED"
\n5554 IF D>12 THEN LET CAVE=CAVE-1
\n5555 IF D<9 THEN LET CAVE=CAVE+1
\n5556 RETURN
\n5560 PRINT "%A%H%A%,%A% %T%R%E%A%S%U%R%E% %M%A%P%.%.%.%C%A%N% %Y%O%U","%R%E%A%D% %I%T%-%-%-%W%E% %S%H%A%L%L% %S%E%E"
\n5561 GOSUB 8000
\n5562 LET X=0
\n5563 FOR X=1 TO 125
\n5564 NEXT X
\n5565 RETURN
\n5566 IF D<11 THEN PRINT "%N%O%,% %I%T% %H%A%S% %F%A%D%E%D%.%.%."
\n5567 IF D<11 THEN LET S=S-INT (D/3)
\n5568 IF D<11 THEN PRINT "YES $$$$$$$$$ AND IT TELLS","YOU WHERE TO FIND $";10*D/2,"WORTH OF GOLD DUBLOONS"
\n5569 IF D>10 THEN LET CASH=CASH+10*D/2
\n5570 IF D>10 THEN LET CAVE=CAVE+1
\n5572 RETURN
\n5580 PRINT "%G%A%D%Z%O%O%K%S%.%.%.%A% %S%A%N%D% %T%R%O%L%L","HAS IT SPOTTED YOU ?"
\n5582 GOSUB 8000
\n5583 GOSUB 5562
\n5584 IF D<7 THEN PRINT "LUCKY...HE HAS TURNED AWAY"
\n5585 IF D>6 THEN PRINT "HORRORS, HE ATTACKS ";A$
\n5586 IF D>6 THEN LET CASH=CASH-10*D
\n5587 IF CASH>0 AND D>6 THEN PRINT "STEALING $";10*D;" WORTH OF EMERALDS"
\n5589 IF D<7 THEN LET CAVE=CAVE+1
\n5590 LET A$="BATTERED "+A$
\n5595 RETURN
\n5600 PRINT "YOU FIND A BOTTLE FASHIONED OF","CURIOUS, MISTY GLASS...WHAT IS","INSIDE IT ?"
\n5602 GOSUB 8000
\n5603 PAUSE 15*D
\n5604 IF D<7 THEN PRINT "IT HOLDS A %G%E%N%I%E WHO GIVES","YOU $";5*D;"AND INCREASES YOUR","STRENGTH BY ";D
\n5605 IF D<7 THEN LET CASH=CASH+5*D
\n5606 IF D<7 THEN LET S=S+D
\n5607 IF D>6 THEN PRINT "%I%T% %H%E%L%D% %N%O%T%H%I%N%G% %B%U%T% %S%T%A%L%E% %S%M%O%K%E"
\n5608 IF D<7 THEN LET CAVE=CAVE+1
\n5609 RETURN
\n5620 PRINT "A WILD WOLF HAS BEEN TRAPPED FOR YEARS IN THIS CAVE. IT IS","BREAKING FREE...YOUR PARTY RUNS FOR SAFETY %W%I%L%L% %Y%O%U% %M%A%K%E% %I%T% %?"
\n5622 GOSUB 8000
\n5623 GOSUB 5562
\n5624 IF D<12 THEN PRINT "YES, YOU MANAGE TO ESCAPE"
\n5625 IF D<12 THEN LET CAVE=CAVE+2
\n5626 IF D>11 THEN PRINT "HORRORS IT HAS CAUGHT","AND WOUNDED ";B$
\n5627 IF D>11 THEN LET B$="WOUNDED "+B$
\n5628 IF D>11 THEN LET S=INT (S/2)
\n5629 RETURN
\n5640 PRINT "THE CAVE IS FULL OF POISONED","GAS...FLEE FOR YOUR LIVES"
\n5641 GOSUB 8000
\n5642 LET CAVE=CAVE-1
\n5643 LET S=S-INT (D/5)
\n5650 RETURN
\n5780 PRINT "IN THE CAVE ARE ";
\n5782 GOSUB 8000
\n5784 PRINT D+1;" SACKS...";"WHICH ONE DO YOU DARE OPEN ?"
\n5786 INPUT K
\n5787 GOSUB 5562
\n5788 GOSUB 8000
\n5789 IF D>12 THEN GOTO 5800
\n5790 PRINT "%D%E%S%P%A%I%R%,% %J%U%S%T% %S%A%N%D"
\n5792 IF D<4 THEN PRINT ,"%A%N%D% %S%P%I%D%E%R%S"
\n5793 LET S=S-2
\n5797 RETURN
\n5800 PRINT "YOU ARE LUCKY"
\n5805 IF D>16 THEN PRINT "DIAMONDS AND RUBIES"
\n5806 IF D<17 THEN PRINT "%S%I%L%V%E%R%,% %G%O%L%D% %A%N%D% %G%E%M%S"
\n5810 GOSUB 8000
\n5812 LET CASH=CASH+7.5*D
\n5813 LET S=S+1
\n5814 LET P=P+1
\n5820 LET CAVE=CAVE+1
\n5900 RETURN
\n7000 PRINT " % %C%O%N%G%R%A%T%U%L%A%T%I%O%N%S% "
\n7010 PRINT
\n7020 PRINT "YOU, ";A$;" AND ";B$
\n7030 PRINT "MADE IT SAFELY OUT OF THE"
\n7040 PRINT TAB (8);"CAVE SYSTEM"
\n7050 PRINT
\n7060 PRINT "YOU HAVE $";CASH;" % %T%R%E%A%S%U%R%E% "
\n7070 PRINT
\n7080 PRINT
\n7090 PRINT " AND SCORED ";10*CASH+20*S+30*P;" POINTS"
\n7100 PRINT
\n7105 FOR A=1 TO 6
\n7110 PRINT "\..%$\..%$\..%$\..%$\..%$\..%$\..%$\..%$\..%$\..%$\..%$\..%$\..%$\..%$\..%$\..%$"
\n7130 NEXT A
\n7999 STOP
\n8000 REM RANDOM NUNBERS
\n8010 LET D=INT (RND*16)+1
\n8020 RETURN
\n8210 CLS
\n8220 GOSUB 8000
\n8230 LET CASH=39.5*D
\n8240 PRINT "% %T%I%M%E% %T%O% %P%I%C%K% %A% %P%A%R%T%Y% %T%O% %E%X%P%L%O%R%E% %T%H%E% %C%A%V%E%S% %W%I%T%H% %Y%O%U%.%.%."
\n8250 PRINT
\n8255 FOR W=1 TO 2
\n8256 IF W=2 THEN CLS
\n8260 PRINT "YOU HAVE $";CASH
\n8270 PRINT
\n8280 PRINT "YOU CAN HIRE ANY % %2% OF THESE:"
\n8290 PRINT
\n8300 PRINT "NAME $ COST STRENGTH POWER"
\n8310 PRINT
\n8320 PRINT "1: MORGAL 100 12 0"
\n8330 PRINT "2: MERLIN 47 2 10"
\n8340 PRINT "3: MUMBLE 83 6 6"
\n8350 PRINT "4: MACKTO 90 9 3"
\n8360 PRINT "5: MINMUK 64 3 9"
\n8370 PRINT
\n8380 PRINT "CHOICE ";W
\n8385 INPUT G(W)
\n8390 GOSUB 8500+10*G(W)
\n8410 NEXT W
\n8412 RETURN
\n8415 STOP
\n8510 LET CASH=CASH-100
\n8511 LET S=S+12
\n8512 IF W=1 THEN LET A$="MORGAL"
\n8513 IF W=2 THEN LET B$="MORGAL"
\n8519 RETURN
\n8520 IF W=1 THEN LET A$="MERLIN"
\n8521 LET CASH=CASH-47
\n8522 LET S=S+2
\n8523 LET P=P+10
\n8524 IF W=2 THEN LET B$="MERLIN"
\n8527 RETURN
\n8530 IF W=1 THEN LET A$="MUMBLE"
\n8531 LET CASH=CASH-83
\n8532 LET S=S+6
\n8533 LET P=P+6
\n8534 IF W=2 THEN LET B$="MUMBLE"
\n8535 RETURN
\n8540 IF W=1 THEN LET A$="MACKTO"
\n8541 LET CASH=CASH-90
\n8542 LET S=S+9
\n8543 LET P=P+3
\n8544 IF W=2 THEN LET B$="MACKTO"
\n8547 RETURN
\n8550 IF W=1 THEN LET A$="MINMUK"
\n8551 LET CASH=CASH-64
\n8552 LET S=S+3
\n8553 LET P=P+9
\n8554 IF W=2 THEN LET B$="MINMUK"
\n8557 RETURN
\n9490 STOP
\n9500 DIM G(2)
\n9540 LET D$=""
\n9560 LET P=0
\n9570 LET S=0
\n9610 LET CASH=0
\n9620 LET CAVE=1
\n9890 GOSUB 8200
\n9900 RETURN
\n9910 CLEAR
\n9920 SAVE "1028%7"
\n9930 RUN
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
