Cave

This file is part of and Timex Sinclair Public Domain Library Tape 1006. Download the collection to get this file.
Date: 198x
Type: Program
Platform(s): TS 1000
Tags: Game

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

VariableMeaning
CAVECurrent cave number (1–9); reaching 10 triggers the win state
CASHTreasure carried, in dollars
SCombined party strength
PCombined party magic power
DCurrent 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
KPlayer’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 K is unused: The player inputs their sack choice into K at line 5786, but K is 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<11 at 5568 contradicts the immediately preceding IF D<11 at 5567 (which already printed the “faded” message); both refer to the same D from subroutine 8000. This double-branch is logically redundant but harmless.
  • CASH can go negative: The sand-troll encounter (lines 5586) subtracts 10*D from CASH without 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 8200 at 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

Appears On

Assembled by Tim Ward from many sources. Contains programs 10252 – 10293.

Related Products

Related Articles

Related Content

Image Gallery

Cave

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
 1100 PRINT "%Y%O%U% %A%R%E% %I%N% %C%A%V%E% %N%U%M%B%E%R%:";CHR$ (156+CAVE)
 1120 IF CASH>0 THEN PRINT "YOUR PARTY IS CARRYING","$";CASH;" WORTH OF TREASURE"
 1140 PRINT "   ";A$;" AND ";B$ 
 1145 PRINT TAB (8);"ARE WITH YOU"
 1150 PRINT "YOUR TOTAL STRENGTH IS ";S
 1160 PRINT "YOUR COMBINED %M%A%G%I%C% %P%O%W%E%R IS ";P
 3100 PRINT ,"POINTS: ";10*CASH+20*S+30*P
 3120 PRINT TAB (8);"......:   :......"
 3130 IF D$="S" THEN PRINT TAB (8);":    %*    :"
 3150 PRINT TAB (8);":    ";CHR$ (CAVE+156);"    :"
 3170 IF D$="E" THEN PRINT TAB (8);"'' %*     ''''"
 3190 IF D$="W" THEN PRINT TAB (8);"''     %* ''''"
 3200 IF D$<>"W" AND D$<>"E" THEN PRINT TAB (8);"''       ''''"
 3210 PRINT TAB (8);"..       ...."
 3220 PRINT TAB (8);":          :"
 3230 IF D$="N" THEN PRINT TAB (8);":    %*     :"
 3240 PRINT TAB (8);"'''''':   :''''''"
 5100 PRINT "  WHICH EXIT (N,S,E,W)?"
 5120 INPUT D$
 5125 IF D$="U" THEN STOP 
 5210 CLS 
 5220 GOSUB 8000
 5221 IF D<3 THEN GOSUB 5513
 5225 IF D>14 THEN GOSUB 5780
 5230 IF D>2 AND D<15 THEN GOSUB 5480+20*D
 5232 PRINT ,,,"%-%-%-%S%T%A%N%D% %B%Y%-%-%-"
 5235 LET X=0
 5236 FOR X=1 TO 150
 5237 NEXT X
 5240 GOTO 300
 5513 PRINT "AHEAD OF YOU IS A CHEST"
 5514 GOSUB 8000
 5515 PRINT "IT CONTAINS ";D/2;" KG OF GEMS"
 5516 PRINT "YOUR AVAILABLE STRENGTH IS ";S
 5517 PRINT "(THE MOST YOU CAN TAKE IS ";INT  (S/4);")"
 5520 PRINT "HOW MUCH WILL YOU TAKE ?"
 5521 INPUT DD
 5522 IF DD>D/2 OR DD>INT (S/4) THEN GOTO 5521
 5523 LET S=S-DD
 5524 LET CASH=CASH+2.5*DD
 5539 RETURN 
 5540 PRINT "YOU ARE FACE TO FACE WITH THE"
 5542 PRINT "  GHOST OF %L%O%N%G %J%O%H%N %S%I%L%V%E%R..."
 5544 PRINT "WILL HE HARM YOU ?"
 5545 LET X=0
 5546 FOR X=1 TO 125
 5547 NEXT X
 5548 GOSUB 8000
 5549 IF D>8 THEN PRINT "YES...HE STRIKES..."
 5550 IF D>8 THEN PRINT "AND ";A$;" IS INJURED"
 5551 IF D>8 THEN LET S=S-2
 5552 IF D>16 THEN LET P=P-1
 5553 IF D<9 THEN PRINT "NO, HE HAS TURNED AWAY","YOU MAY PROCEED"
 5554 IF D>12 THEN LET CAVE=CAVE-1
 5555 IF D<9 THEN LET CAVE=CAVE+1
 5556 RETURN 
 5560 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"
 5561 GOSUB 8000
 5562 LET X=0
 5563 FOR X=1 TO 125
 5564 NEXT X
 5565 RETURN 
 5566 IF D<11 THEN PRINT "%N%O%,% %I%T% %H%A%S% %F%A%D%E%D%.%.%."
 5567 IF D<11 THEN LET S=S-INT (D/3)
 5568 IF D<11 THEN PRINT "YES $$$$$$$$$ AND IT TELLS","YOU WHERE TO FIND $";10*D/2,"WORTH OF GOLD DUBLOONS"
 5569 IF D>10 THEN LET CASH=CASH+10*D/2
 5570 IF D>10 THEN LET CAVE=CAVE+1
 5572 RETURN 
 5580 PRINT "%G%A%D%Z%O%O%K%S%.%.%.%A% %S%A%N%D% %T%R%O%L%L","HAS IT SPOTTED YOU ?"
 5582 GOSUB 8000
 5583 GOSUB 5562
 5584 IF D<7 THEN PRINT "LUCKY...HE HAS TURNED AWAY"
 5585 IF D>6 THEN PRINT "HORRORS, HE ATTACKS ";A$
 5586 IF D>6 THEN LET CASH=CASH-10*D
 5587 IF CASH>0 AND D>6 THEN PRINT "STEALING $";10*D;" WORTH OF EMERALDS"
 5589 IF D<7 THEN LET CAVE=CAVE+1
 5590 LET A$="BATTERED "+A$
 5595 RETURN 
 5600 PRINT "YOU FIND A BOTTLE FASHIONED OF","CURIOUS, MISTY GLASS...WHAT IS","INSIDE IT ?"
 5602 GOSUB 8000
 5603 PAUSE 15*D
 5604 IF D<7 THEN PRINT "IT HOLDS A %G%E%N%I%E WHO GIVES","YOU $";5*D;"AND INCREASES YOUR","STRENGTH BY ";D
 5605 IF D<7 THEN LET CASH=CASH+5*D
 5606 IF D<7 THEN LET S=S+D
 5607 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"
 5608 IF D<7 THEN LET CAVE=CAVE+1
 5609 RETURN 
 5620 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% %?"
 5622 GOSUB 8000
 5623 GOSUB 5562
 5624 IF D<12 THEN PRINT "YES, YOU MANAGE TO ESCAPE"
 5625 IF D<12 THEN LET CAVE=CAVE+2
 5626 IF D>11 THEN PRINT "HORRORS IT HAS CAUGHT","AND WOUNDED ";B$
 5627 IF D>11 THEN LET B$="WOUNDED "+B$
 5628 IF D>11 THEN LET S=INT (S/2)
 5629 RETURN 
 5640 PRINT "THE CAVE IS FULL OF POISONED","GAS...FLEE FOR YOUR LIVES"
 5641 GOSUB 8000
 5642 LET CAVE=CAVE-1
 5643 LET S=S-INT (D/5)
 5650 RETURN 
 5780 PRINT "IN THE CAVE ARE ";
 5782 GOSUB 8000
 5784 PRINT D+1;" SACKS...";"WHICH ONE DO YOU DARE OPEN ?"
 5786 INPUT K
 5787 GOSUB 5562
 5788 GOSUB 8000
 5789 IF D>12 THEN GOTO 5800
 5790 PRINT "%D%E%S%P%A%I%R%,% %J%U%S%T% %S%A%N%D"
 5792 IF D<4 THEN PRINT ,"%A%N%D% %S%P%I%D%E%R%S"
 5793 LET S=S-2
 5797 RETURN 
 5800 PRINT "YOU ARE LUCKY"
 5805 IF D>16 THEN PRINT "DIAMONDS AND RUBIES"
 5806 IF D<17 THEN PRINT "%S%I%L%V%E%R%,% %G%O%L%D% %A%N%D% %G%E%M%S"
 5810 GOSUB 8000
 5812 LET CASH=CASH+7.5*D
 5813 LET S=S+1
 5814 LET P=P+1
 5820 LET CAVE=CAVE+1
 5900 RETURN 
 7000 PRINT "    % %C%O%N%G%R%A%T%U%L%A%T%I%O%N%S% "
 7010 PRINT 
 7020 PRINT "YOU, ";A$;" AND ";B$
 7030 PRINT "MADE IT SAFELY OUT OF THE"
 7040 PRINT TAB (8);"CAVE SYSTEM"
 7050 PRINT 
 7060 PRINT "YOU HAVE $";CASH;" % %T%R%E%A%S%U%R%E% "
 7070 PRINT 
 7080 PRINT 
 7090 PRINT "    AND SCORED ";10*CASH+20*S+30*P;" POINTS"
 7100 PRINT 
 7105 FOR A=1 TO 6
 7110 PRINT "..%$..%$..%$..%$..%$..%$..%$..%$..%$..%$..%$..%$..%$..%$..%$..%$"
 7130 NEXT A
 7999 STOP 
 8000 REM RANDOM NUNBERS
 8010 LET D=INT (RND*16)+1
 8020 RETURN 
 8210 CLS 
 8220 GOSUB 8000
 8230 LET CASH=39.5*D
 8240 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%.%.%."
 8250 PRINT 
 8255 FOR W=1 TO 2
 8256 IF W=2 THEN CLS 
 8260 PRINT "YOU HAVE $";CASH
 8270 PRINT 
 8280 PRINT "YOU CAN HIRE ANY % %2%  OF THESE:"
 8290 PRINT 
 8300 PRINT "NAME     $ COST STRENGTH  POWER"
 8310 PRINT 
 8320 PRINT "1: MORGAL  100   12        0"
 8330 PRINT "2: MERLIN   47    2       10"
 8340 PRINT "3: MUMBLE   83    6        6"
 8350 PRINT "4: MACKTO   90    9        3"
 8360 PRINT "5: MINMUK   64    3        9"
 8370 PRINT 
 8380 PRINT "CHOICE ";W
 8385 INPUT G(W)
 8390 GOSUB 8500+10*G(W)
 8410 NEXT W
 8412 RETURN 
 8415 STOP 
 8510 LET CASH=CASH-100
 8511 LET S=S+12
 8512 IF W=1 THEN LET A$="MORGAL"
 8513 IF W=2 THEN LET B$="MORGAL"
 8519 RETURN 
 8520 IF W=1 THEN LET A$="MERLIN"
 8521 LET CASH=CASH-47
 8522 LET S=S+2
 8523 LET P=P+10
 8524 IF W=2 THEN LET B$="MERLIN"
 8527 RETURN 
 8530 IF W=1 THEN LET A$="MUMBLE"
 8531 LET CASH=CASH-83
 8532 LET S=S+6
 8533 LET P=P+6
 8534 IF W=2 THEN LET B$="MUMBLE"
 8535 RETURN 
 8540 IF W=1 THEN LET A$="MACKTO"
 8541 LET CASH=CASH-90
 8542 LET S=S+9
 8543 LET P=P+3
 8544 IF W=2 THEN LET B$="MACKTO"
 8547 RETURN 
 8550 IF W=1 THEN LET A$="MINMUK"
 8551 LET CASH=CASH-64
 8552 LET S=S+3
 8553 LET P=P+9
 8554 IF W=2 THEN LET B$="MINMUK"
 8557 RETURN 
 9490 STOP 
 9500 DIM G(2)
 9540 LET D$=""
 9560 LET P=0
 9570 LET S=0
 9610 LET CASH=0
 9620 LET CAVE=1
 9890 GOSUB 8200
 9900 RETURN 
 9910 CLEAR 
 9920 SAVE "1028%7"
 9930 RUN 

Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.

People

No people associated with this content.

Scroll to Top