Catacombs is a maze exploration game in which the player navigates a procedurally generated dungeon map, collecting gold and food while fighting monsters. The map is built in FAST mode using a 22×32 string array that is then POKEd directly into the ZX81 display file, with rooms, corridors, and door markers (represented by block-graphic characters) placed algorithmically. Monster data—name and strength—is stored in memory at fixed offsets from address 17384, and the player’s position and collision detection are handled by machine code routines called via USR at addresses 17490, 18316, and 18325. Enemies include dragons, serpents, minotaurs, trolls, phoenixes, and warlocks, each with increasing base strength; the warlock encounter triggers a special scrolling tunnel-of-death mini-game. A trap mini-game requires the player to guess a randomly chosen character within five attempts or face death.
Program Analysis
Program Structure
The program is organized into distinct functional blocks, largely separated by line-number ranges:
- Lines 10–190: Main game loop — initializes variables, calls map setup, then continuously polls for keypresses, updates the score/strength, and dispatches to encounter routines.
- Lines 200–290: Beast-data reader — reads the current cell’s creature name and strength from memory into string
B$. - Lines 300–590: Combat system — handles attack animation, hit/miss resolution, strength adjustment, death, and the Phoenix resurrection special case.
- Lines 600–690: Mercy/bribery routine — allows a weakened player to give up half their gold to avoid death.
- Lines 700–790: Treasure pickup — gold (
[£]) and food ([F]) cells. - Lines 800–960: Trap mini-game — five guesses to match a random character.
- Lines 1000–1060: Title/intro screen, including a
SAVEcall at line 1020. - Lines 1400–1420: Delay-and-clear subroutine.
- Lines 1500–1530: Single-keypress input subroutine using
INKEY$. - Lines 1600–1690: Phantom encounter — trades 100 gold for a strength boost.
- Lines 1700–1790: Warlock tunnel-of-death mini-game.
- Lines 1980–1995: Exit cell handler — loops back to the map-generation subroutine for a new level.
- Lines 2000–2990: Map generation subroutine — builds rooms, corridors, and creature data in FAST mode, then POKEs the display file.
- Lines 3000–3070: Death screen with play-again prompt.
Machine Code Usage
Three USR calls drive the core engine; all are invoked via LET N=USR address with parameters communicated through POKEs to the system area around address 16598–16604:
| Address | Role | Parameters POKEd |
|---|---|---|
| 17490 | Initialise / draw player sprite on map | 16598 (C1-1), 16599 (L1-1), 16601–16604 |
| 18316 | Move player in response to keypress | 16600 (key code) |
| 18325 | Redraw / advance map state after event | — |
The machine code lives within the map data area (addresses 17384–17490 and beyond), which is consistent with the map being stored from address 16640 onward (the ZX81 display file / RAM area). The POKE 16601,128 calls reset a “cell-type” flag that the machine code sets when the player lands on a special cell; BASIC checks this flag at lines 150–180 to decide whether to call the encounter dispatcher.
Line 95 contains a guard: IF PEEK 16584<>172 THEN POKE ((PEEK 16396+256*PEEK 16397)+66),0. This patches a byte at a calculated address in the display file or system variables, likely disabling a system interrupt or scrolling behavior under certain ROM versions detected by the value at 16584.
Line 2795 contains a similar ROM-version guard: IF PEEK 16588<>170 THEN POKE 16389,68.
Map Generation
The dungeon is built in FAST mode inside a 22×32 single-character string array A$ declared at line 2025. Room placement (lines 2030–2240) randomly sizes and positions up to ten rectangles, checking that no cell in the proposed bounding box is already occupied before committing. Each room cell is filled with the block-graphic solid character; cells are probabilistically replaced with [£] (gold, ~3% chance) or [F] (food, ~4% chance). A counter E ensures exactly one special-encounter cell per room (for rooms 2–9), selecting a creature character by room index using a chained CHR$ (CODE "[X]"*(A=2)+...) expression.
Horizontal corridors (lines 2250–2480) and vertical corridors (lines 2490–2710) are then added, each capped at both ends with the [▒] door/passage marker character. The algorithm searches for two existing non-space cells in the same row (or column) with a gap between them, verifying that the adjacent rows (or columns) at the gap start are clear before drawing the passage.
Finally (lines 2740–2790), the completed A$ array is POKEd into the display file starting at 16640: each character is converted by (CODE A$(A,B)+64)*(A$(A,B)<>" "), mapping BASIC character codes to the ZX81’s internal character set (which is offset by 64 from ASCII-like codes) while leaving spaces as zero (blank).
Creature Data Storage
Monster records are stored directly in the map data area at fixed offsets from address 17384. Each record occupies 13 bytes: the first 8 bytes are the creature name (padded), followed by 3 bytes for the strength value as a decimal string. Lines 2810–2860 write these records for all seven monster types with randomly chosen base strengths biased upward by type (50, 75, 100, 200, 300, 400, 500 added respectively). At runtime, B$ is populated by reading 11 bytes from B+17389 where B is the cell value returned by the machine code (PEEK 16604), making each map cell’s creature identity self-contained in memory. Combat line 515–522 writes the updated strength back to the same memory location.
Combat Resolution
Combat at lines 400–540 uses a probabilistic outcome variable R built from RND adjusted by relative strength comparisons:
+0.1if player strength exceeds monster strength+0.2if player strength exceeds twice the monster strength-0.1if monster strength exceeds player strength-0.2if monster strength exceeds twice the player strength
R>0.5 means the monster is hurt; R<0.5 means the player is hurt. Damage is computed as INT((RND*40+5)+(RND*30)*(underdog condition)), multiplied by 0 or 1 depending on who was hit. The loop at line 530 continues until one side reaches zero strength.
The Phoenix at line 560–590 is a special case: on death it revives with a new random strength of 400–499, making it potentially a recurring threat.
Warlock Tunnel Mini-game
Lines 1730–1780 implement a scrolling obstacle course. A wall segment of [▒][▒][▒] characters moves horizontally at a random walk while the screen scrolls upward via SCROLL. The player’s * character is moved left/right with keys 5 and 8. Collision detection at line 1765 reads the byte at the address pointed to by PEEK 16398+256*PEEK 16399 (the system variable D-FILE pointer area, pointing to the line just below the player position) and checks for value 128 (the ZX81 internal code for the solid block character). If a collision is detected, the game jumps directly to the death screen at line 3000. The tunnel runs for 200 iterations of wall printing followed by 14 iterations without (giving a clear exit), after which surviving players see a congratulatory flash and the program restarts via RUN.
Trap Mini-game
Lines 800–960 generate a “magic number” as C$=CHR$(INT(RND*10)+28) — a character in the range of ZX81 internal codes 28–37, which correspond to the digit characters 0–9 when displayed. The player has five attempts, each collected via the single-keypress subroutine at 1500. Failure after five tries goes directly to line 3000 (death); success returns normally.
Key BASIC Idioms
- Boolean arithmetic for clamping:
LET S=S*(S>0)(line 105) clamps strength to zero without anIFstatement. - Computed character codes:
CHR$(CODE "[X]"*(A=2)+CODE "[D]"*(A=3)+...)at line 2200 selects a creature character by room index in a single expression. - String-slicing for number storage: Monster strength is stored and retrieved as a 3-character decimal string slice
B$(9 TO 11), avoiding a separate numeric variable. - FAST/SLOW mode framing: Map generation is wrapped in
FAST(line 2020) /SLOW(line 2960) to speed up the intensive array and POKE operations. - Retry-loop with guard counter: Variable
Hcounts placement attempts; if 100 attempts fail (lines 2072–2075, 2282–2285, 2522–2525), the current room or corridor is skipped, preventing infinite loops in dense maps.
Anomalies and Notes
- Line 440 uses
YOU,RE(comma instead of apostrophe) — this is a ZX81 display convention since the apostrophe character is not directly available. - Line 510 writes
STR$ Mback toB$(9 TO 11)butSTR$ MforM=0produces a single character"0", leaving two trailing characters of the previous strength value in memory. This could cause the creature to appear to have non-zero strength on a subsequent read if the cell were re-entered — however the cell’s record is zeroed at lines 551–552 after a kill, mitigating the issue. - The
GOTO 1995at line 1995 loops back to line 40 (GOSUB 2000), generating a new level rather than truly exiting, consistent with the game design. - The
DIM A$(3)at line 2800 intentionally re-uses the nameA$(previously declared asDIM A$(22,32,1)) to reclaim memory after the map has been POKEd into the display file — a deliberate memory-management technique.
Content
Image Gallery
Source Code
0 REM █[C][A][T][A][C][O][M][B][S]█ █[C][O][P][Y][R][I][G][H][T]█[7][/][9][/][8][1]█ █[J][.][K][.][G][R][E][Y][E]█
0 REM ##[L]PI7[M] █B LN """""""""""""" """""""""" """""""""""""" "" DIM """""" """""" "" POKE """""""""" """""""" FOR FOR """" """""""""""""" FOR """""""" """""" """""" FOR ATN """" """""""""""""" CLEAR"""""""" COS """""""""" "" """""""""" COS """""""""" """""""""" """""""""" """""""""" ██████ ATN """"""""COS ""█[*]█""""""""""""COS """""" SAVE "" ██████ """""""""" [▒] """""" """"""""ATN ██████ """""""""" █ """""" """""""""" [▒] [▒] [£]"""" ██████[▒]██████████[▒]█""ATN ██████ █"""" ██████ """""" [£]GOLD [F]OOD [X]EXIT [D]RAGON 81 ▐INKEY$ [S]ERPENT 167[X]PI[O]RC 143[+]INKEY$ [M]INATAUR261[L]PI[T]ROLL 387 [P]HOENIX 498 [W]ARLOCK 592 LN ▄#LN [3]#LN AND #) INKEY$ 5TAN #▘# ,, FOR ▞-VAL ▘4 ACS #C£7<"4 RUN AT ▌COS VAL </ GOSUB GOSUB [4] REM ##/ PAUSE 5CHR$ RND▞ #7Y GOSUB ###ACS 7ACS > GOSUB #5 INKEY$ ;,,6CHR$ RNDTAN Q[*]▘5 [B] GOSUB PI)4 ▞▀ACS [Q]7( CLS▞▝F;ACS [Q]( CLS▞▝FACS [Q]( CLS▞▝ GOSUB #ACS [Q]( IF TAN ) ▘ U**RND RETURN14▒▘ COPY COPY) STEP COPY/# RETURN24▒▘▘ ) STEP COPY/T RETURN34▒▘▘ )4 /H RETURN44▒▘ COPY COPY)4 /5 RETURN54▌▘ COPY COPY// RETURN64▌)4 /? RETURN74▌) STEP COPY/▞ RETURN8""▘▘ ECHR$ RND FAST;,,ACS #4, LPRINT FAST# RETURN C▌,,ACS #4:# RETURN C▛ GOSUB PI;ACS #4▝ LPRINT TAN 6CHR$ RNDU OR RND##M OR RNDVAL LN [3]#AT LPRINT #TAN ▘ ) U**RND RETURN#4▖) STEP COPYTAN RETURN#4▖)4 TAN RETURN#4▖▘ COPY COPYTAN RETURN#""▘▘ TAN U**RND RETURN#ABS TAN # RETURN# AND TAN #LN ##ECHR$ RND FAST,,;LN SIN #Y [T]C9[S]C6Y3[T]C1Y-[S]C/6CHR$ RNDU OR RND## RETURN 4▝Y█M OR RND#SGN >LN [3]#TAN LPRINT TAN FASTY3[9]#Y▀9[8]▞▀ACS 9*( CLS# LPRINT TAN 5 GOSUB #▞▛VAL #ACS RUN )" ; FAST5 INKEY$ ▘""▝ GOSUB [L]4▒ FOR . LPRINT #7#/▞ LPRINT Q 7Q 7AT (<=TAN 5 AND RNDY▀[A]#U OR RND RETURN COS RETURN[▒]4▀ACS LEN TAN ACS #C▖ACS EXP ACS ▚ RETURN█COS RETURN[F]4▀ACS PLOT TAN RETURN[£]4▀ACS NEWTAN RETURN[X]4▀ACS INPUT TAN ACS RETURNACS [R]M OR RND)$ 5 STEP #▞▛;[Y]C▝( IF ) GOSUB #[B] GOSUB ##M>=RNDTAN 5 SAVE #U>=RND RETURN#SQR #- ;#7#ECHR$ RND#[X]4▀#[W]COS LN SIN #STR$ LPRINT VAL SGN LN SIN # FAST#[V]C▞K▀7/▘FU AND RNDACS #4(##[T])4 C▒K▀;/▀[B] GOSUB ## RETURN[*]CPI RETURN█C3 RETURN""C.5 AND RNDACS #4▞ACS THEN LPRINT FAST/NOT 5 AND RNDACS #C▝ LPRINT TAN ACS CHR$ LPRINT /[>]SGN ,#ACS #ACS [R]C▝ACS RUN #,ACS #U<=RNDACS [R]C▝ACS RUN >#M<=RND/-SGN U OR RND RETURN[▒]COS #,M OR RNDU<=RNDACS [R]>#M<=RND FASTU>=RND#- 5 SAVE #;SGN #7#TAN 5 AND RNDACS #COS 5 FOR #▞▛)$ VAL ; FAST#7# FOR LN SIN #VAL SGN ECHR$ RNDLN SIN ##[V]C?K▖W7/▝XF PRINT LN ## LET / INPUT #▘4 [U]C(K▖,,W/▀ GOSUB PIX PRINT LN ## LET / GOSUB LPRINT AT FAST) SAVE #[B] GOSUB ##M>=RND LPRINT Y #7# FOR ACS #C▝YRNDACS COPYM<=RND5 AND RNDACS [:]TAN #ACS #C▌ACS [R] RETURN[▒]""SGN LET LPRINT AT ([£]TAN LN ▙#LN ▌####LN £#LN #####
10 RAND
20 LET S=150+INT (RND*100)
25 LET Q=0
30 LET G=0
40 GOSUB 2000
50 LET Q=1
55 POKE 16598,(C1-1)
60 LET B=128
65 POKE 16604,128
70 POKE 16603,128
75 POKE 16599,(L1-1)
80 LET N=USR 17490
85 POKE 16602,1
90 POKE 16601,128
95 IF PEEK 16584<>172 THEN POKE ((PEEK 16396+256*PEEK 16397)+66),0
100 LET S=S-1-5*(CODE INKEY$ >99)
105 LET S=S*(S>0)
110 PRINT AT 0,11;S;" "
115 IF S<=0 THEN GOTO 3000
120 LET R=INT (RND*999)
125 IF R<7 THEN GOSUB 240
130 LET N=CODE INKEY$
135 IF N=0 THEN GOTO 150
140 POKE 16600,N
145 LET N=USR 18316
150 LET C=PEEK 16601
155 IF C<>128 AND C<>136 THEN GOSUB 300
160 IF B<>PEEK 16604 THEN GOSUB 200
170 LET N=USR 18325
175 LET C=PEEK 16601
180 IF C<>128 AND C<>136 THEN GOSUB 300
190 GOTO 100
200 GOSUB 250
210 PRINT AT 1,0;B$(1 TO 8);",STRENGTH ";B$(9 TO 11);",NEARBY."
220 GOSUB 1400
230 RETURN
240 IF R=6 THEN GOSUB 800
245 IF R<5 AND G>100 AND S<200 THEN GOSUB 1600
247 RETURN
250 DIM B$(11)
260 LET B=PEEK 16604
270 LET Z=B+17389
275 FOR N=0 TO 10
280 LET B$(N+1)=CHR$ PEEK (Z+N)
285 NEXT N
290 RETURN
300 IF C=CODE "[£]" THEN GOTO 700
310 IF C=CODE "[F]" THEN GOTO 750
320 IF C=CODE "[X]" THEN GOTO 1980
330 FOR N=1 TO 10
340 PRINT AT 1,0;" *** AN ATTACK *** ";AT 1,0;"███████[*][*][*]█[A][N]█[A][T][T][A][C][K]█[*][*][*]████████"
350 NEXT N
360 GOSUB 250
370 LET M=VAL B$(9 TO 11)
380 GOTO 400
390 LET N=CODE INKEY$
392 IF N=0 THEN GOTO 400
394 POKE 16600,N
396 LET N=USR 18316
398 RETURN
400 PRINT AT 1,0;"A BLOW IS STRUCK, "
410 LET R=RND+.1*(S>M)+.2*(S/2>M)-.1*(M>S)-.2*(M/2>S)
420 IF R>.5 THEN PRINT AT 1,18;"ITS HURT."
430 IF R<.5 THEN PRINT AT 1,18;"YOU,RE HURT."
440 GOSUB 1400
450 LET S=S-INT ((RND*40+5)+(RND*30)*(S<M))*(R<.5)
460 LET M=M-INT ((RND*40+5)+(RND*30)*(S>M))*(R>.5)
470 LET S=S*(S>0)
475 LET M=M*(M>0)
480 PRINT AT 0,11;S;" "
490 IF M>0 THEN PRINT AT 1,0;"THE ";B$(1 TO 8);" HAS STRENGTH ";M
500 IF M=0 THEN PRINT AT 1,0;"THE ";B$(1 TO 8);" IS DEAD."
510 LET B$(9 TO 11)=STR$ M
515 POKE (Z+8),CODE B$(9)
520 POKE (Z+9),CODE B$(10)
522 POKE (Z+10),CODE B$(11)
525 GOSUB 1400
530 IF M>0 AND S>0 THEN GOTO 390
532 IF S<=0 THEN GOSUB 600
534 IF S<=0 THEN GOTO 3000
536 LET S=S+10+INT (RND*99)
538 PRINT AT 1,0;"YOUR STRENGTH HAS BEEN RAISED.";AT 0,11;S
540 GOSUB 1400
550 IF B$(1)="[P]" THEN GOTO 560
551 POKE (Z+11),0
552 POKE (Z+12),0
553 POKE 16601,128
554 POKE 16602,1
555 POKE 16603,128
556 POKE 16604,128
557 LET B=128
558 RETURN
560 PRINT AT 1,0;"THE [P]HOENIX RISES FROM THE ASHES"
565 LET B$(9 TO 11)=STR$ (INT (RND*100)+400)
570 POKE (Z+8),CODE B$(9)
575 POKE (Z+9),CODE B$(10)
580 POKE (Z+10),CODE B$(11)
585 GOSUB 1400
590 RETURN
600 LET R=RND
610 IF RND>.3 OR G<200 OR B$(1)="[P]" THEN RETURN
620 IF B$(1)="[W]" THEN GOTO 1700
630 PRINT AT 1,0;"THE ";B$(1 TO 8);" WILL GO AWAY IF YOUGIVE IT HALF YOUR GOLD? (Y/N)"
640 GOSUB 1500
650 PRINT AT 1,0;" "
660 IF P$<>"Y" THEN RETURN
670 LET G=G-INT (G/2)
675 LET S=S+10
680 PRINT AT 0,27;G;" "
690 RETURN
700 LET R=INT (RND*100)+1
710 LET G=G+R
720 PRINT AT 1,0;"YOU HAVE FOUND [£]GOLD VALUE ";R;AT 0,27;G
725 POKE 16601,128
727 LET N=USR 18325
730 GOSUB 1400
740 RETURN
750 LET R=INT (RND*50)+1
760 LET S=S+R
770 PRINT AT 1,0;"YOU HAVE FOUND [F]OOD VALUE ";R;AT 0,11;S
775 POKE 16601,128
777 LET N=USR 18325
780 GOSUB 1400
790 RETURN
800 RAND
805 LET C$=CHR$ (INT (RND*10)+28)
810 FOR N=1 TO 40
820 PRINT AT 1,0;" ** YOU,VE STEPPED IN A TRAP ** ";AT 1,0;"█[*][*]█[Y][O][U][,][V][E]█[S][T][E][P][P][E][D]█[I][N]█[A]█[T][R][A][P]█[*][*]█"
830 NEXT N
840 PRINT AT 1,0;"YOU HAVE ONLY 5 GOES TO FIND THEMAGIC NUMBER THAT WILL SAVE YOU."
850 GOSUB 1400
860 FOR N=1 TO 5
870 PRINT AT 1,0;"TRY ";N;", ?"
880 GOSUB 1500
890 IF P$=C$ THEN GOTO 940
900 PRINT AT 1,7;P$;" IS WRONG (";5-N;" GOES LEFT)"
910 GOSUB 1400
920 NEXT N
930 GOTO 3000
940 PRINT AT 1,7;P$;" IS RIGHT....YOU ESCAPE."
950 GOSUB 1400
960 RETURN
1000 CLEAR
1010 CLS
1020 SAVE "CATACOMB[S]"
1030 PRINT "███████[*][*][*]█[C][A][T][A][C][O][M][B][S]█[*][*][*]████████ COPYRIGHT J.K.GREYE SOFTWARE"
1031 PRINT AT 4,5;"EXPLORE THE CATACOMBS,";AT 5,9;"FIND THE GOLD,";AT 6,7;"FIGHT THE MONSTERS,";AT 7,1;"BUT TRY NOT TO STARVE TO DEATH."
1032 PRINT AT 10,7;"YOU ARE THE [*] AND"
1033 PRINT AT 11,6;"KEYS 1 TO 8 MOVE YOU,"
1034 PRINT " (TO TUNNEL USE 5-8 WITH SHIFT)."
1035 IF PEEK 16585<>183 THEN LET N=USR 16606
1036 PRINT AT 15,3;"THE REST, YOU WILL HAVE TO DISCOVER FOR YOURSELF."
1041 PRINT AT 20,7;" ANY KEY TO START ";AT 20,7;"█[A][N][Y]█[K][E][Y]█[T][O]█[S][T][A][R][T]█"
1045 IF INKEY$ <>"" THEN RUN
1050 GOTO 1041
1060 RUN
1400 FOR T=0 TO 30
1410 NEXT T
1420 PRINT AT 1,0;" "
1430 RETURN
1500 IF INKEY$ <>"" THEN GOTO 1500
1510 IF INKEY$ ="" THEN GOTO 1510
1520 LET P$=INKEY$
1530 RETURN
1600 RAND
1602 FOR N=1 TO 20
1605 PRINT AT 1,0;" *** A PHANTOM APPEARS *** ";AT 1,0;"███[*][*][*]█[A]█[P][H][A][N][T][O][M]█[A][P][P][E][A][R][S]█[*][*][*]████"
1610 NEXT N
1620 PRINT AT 1,0;"IF YOU GIVE IT 100 GOLD PIECESIT WILL RAISE YOUR STRENGTH, Y/N"
1630 GOSUB 1500
1640 PRINT AT 1,0;" "
1650 IF P$<>"Y" THEN RETURN
1660 LET G=G-100
1670 LET S=S+INT (RND*90)+10
1680 PRINT AT 0,11;S;AT 0,27;G;" "
1690 RETURN
1700 PRINT AT 1,0;"THE [W]ARLOCK TAKES ALL YOUR [£]GOLDAND CASTS A SPELL THAT THROWSYOU INTO THE █[T][U][N][N][E][L]█[O][F]█[D][E][A][T][H]█. "
1710 PRINT AT 4,0;"HIT THE WALLS AND YOU █[D][I][E]█. KEYS 5/8 CONTROL YOUR MOVEMENT. "
1720 FOR N=1 TO 50
1725 NEXT N
1730 LET X=14
1733 LET R=12
1735 FOR N=7 TO 21
1736 PRINT AT N,0;" █[▒][▒][▒]█ "
1737 NEXT N
1739 FOR N=1 TO 214
1740 IF N>200 THEN GOTO 1742
1741 PRINT AT 21,R;"█[▒][▒][▒]█"
1742 PRINT AT 7,X;"▒"
1745 SCROLL
1750 LET X=X+(X<31 AND INKEY$ ="8")-(X>0 AND INKEY$ ="5")
1755 PRINT AT 7,X;"[*]";AT 8,X;
1760 LET R=R+(R<27 AND RND>.5)-(R>0 AND RND<.5)
1765 IF PEEK (PEEK 16398+256*PEEK 16399)=128 THEN GOTO 3000
1767 NEXT N
1770 FOR N=1 TO 20
1774 PRINT AT 0,0;" *** YOU HAVE SURVIVED *** ";AT 0,0;"███[*][*][*]█[Y][O][U]█[H][A][V][E]█[S][U][R][V][I][V][E][D]█[*][*][*]████"
1778 NEXT N
1780 GOSUB 1400
1790 RUN
1980 PRINT AT 1,0;"YOU HAVE FOUND THE [X]EXIT."
1990 GOSUB 1400
1995 GOTO 40
2000 CLS
2005 PRINT AT 3,6;"█[*][*][*]█[S][E][T][T][I][N][G]█[U][P]█[*][*][*]█";AT 8,0;"YOUR █[Z][X][8][1]█ WILL SHORTLY GO INTOFAST MODE.";AT 12,8;"PLEASE WAIT UNTIL";AT 13,6;"THE DISPLAY REAPPEARS."
2010 IF Q=1 THEN PRINT AT 5,7;"█[*][*]█[N][E][W]█[L][E][V][E][L][.]█[*][*]█"
2015 GOSUB 1400
2020 FAST
2025 DIM A$(22,32,1)
2030 FOR A=1 TO 5+INT (RND*5)
2035 LET H=0
2040 LET R=INT (RND*6)+2
2050 LET R1=INT (RND*6)+2
2060 LET L=INT (RND*18)+2
2070 LET C=INT (RND*28)+2
2072 LET H=H+1
2075 IF H=100 AND A>2 THEN GOTO 2240
2080 IF L+R+1>22 OR C+R1+1>32 THEN GOTO 2040
2090 FOR B=L-1 TO L+R+1
2100 FOR D=C-1 TO C+R1+1
2110 IF A$(B,D)<>" " THEN GOTO 2040
2120 NEXT D
2130 NEXT B
2140 LET E=0
2150 FOR B=L TO L+R
2160 FOR D=C TO C+R1
2170 LET A$(B,D)="█"
2175 LET F=RND
2180 IF F>.97 THEN LET A$(B,D)="[£]"
2185 IF F<.04 THEN LET A$(B,D)="[F]"
2190 LET E=E+(E=0 AND (F>.95 OR A=2))+(E=1)
2200 IF E=1 AND A>1 THEN LET A$(B,D)=CHR$ (CODE "[X]"*(A=2)+CODE "[D]"*(A=3)+CODE "[S]"*(A=4)+CODE "[O]"*(A=5)+CODE "[M]"*(A=6)+CODE "[T]"*(A=7)+CODE "[P]"*(A=8)+CODE "[W]"*(A=9))
2210 IF A=1 THEN LET L1=L
2215 IF A=1 THEN LET C1=C
2220 NEXT D
2230 NEXT B
2240 NEXT A
2250 FOR A=1 TO 2+INT (RND*4)
2255 LET H=0
2260 LET L=INT (RND*19)+2
2270 LET B=0
2280 LET C=B
2282 LET H=H+1
2285 IF H=100 THEN GOTO 2480
2290 FOR N=INT (RND*15)+3 TO 30
2300 IF A$(L,N)<>" " THEN LET B=N
2310 IF A$(L,N)=" " AND B<>0 THEN LET C=N
2320 IF C<>0 THEN GOTO 2360
2340 NEXT N
2350 GOTO 2260
2360 LET D=0
2370 FOR N=C TO 30
2380 IF A$(L,N)<>" " THEN LET D=N-1
2390 IF D<>0 THEN GOTO 2420
2400 NEXT N
2410 GOTO 2260
2420 IF A$(L+1,C)<>" " OR A$(L-1,C)<>" " THEN GOTO 2260
2430 FOR N=C TO D
2440 LET A$(L,N)="█"
2450 NEXT N
2460 LET A$(L,C)="[▒]"
2470 LET A$(L,D)="[▒]"
2480 NEXT A
2490 FOR A=1 TO 2+INT (RND*4)
2495 LET H=0
2500 LET X=INT (RND*30)+2
2510 LET B=0
2520 LET C=B
2522 LET H=H+1
2525 IF H=100 THEN GOTO 2710
2530 FOR N=INT (RND*10)+2 TO 20
2540 IF A$(N,X)<>" " THEN LET B=N
2550 IF A$(N,X)=" " AND B<>0 THEN LET C=N
2560 IF C<>0 THEN GOTO 2590
2570 NEXT N
2580 GOTO 2500
2590 LET D=0
2600 FOR N=C TO 20
2610 IF A$(N,X)<>" " THEN LET D=N-1
2620 IF D<>0 THEN GOTO 2650
2630 NEXT N
2640 GOTO 2500
2650 IF A$(C,X+1)<>" " OR A$(C,X-1)<>" " THEN GOTO 2500
2660 FOR N=C TO D
2670 LET A$(N,X)="█"
2680 NEXT N
2690 LET A$(C,X)="[▒]"
2700 LET A$(D,X)="[▒]"
2710 NEXT A
2720 LET A=1
2730 LET B=1
2740 FOR N=16640 TO 17343
2750 POKE N,((CODE A$(A,B)+64)*(A$(A,B)<>" "))
2760 LET A=A+(B=32)
2770 LET B=B+1
2780 IF B=33 THEN LET B=1
2790 NEXT N
2795 IF PEEK 16588<>170 THEN POKE 16389,68
2800 DIM A$(3)
2810 FOR N=1 TO 7
2820 LET A$(1 TO 3)=STR$ (INT (RND*100)+50*(N=1)+75*(N=2)+100*(N=3)+200*(N=4)+300*(N=5)+400*(N=6)+500*(N=7))
2830 POKE (17384+N*13),CODE A$(1)
2840 POKE (17385+N*13),CODE A$(2)
2850 POKE (17386+N*13),CODE A$(3)
2860 NEXT N
2955 CLS
2960 SLOW
2962 IF Q=1 THEN PRINT AT 4,11;"NEW LEVEL"
2965 PRINT AT 11,6;"ANY KEY TO CONTINUE."
2970 PRINT AT 7,8;" *** READY *** ";AT 7,8;"█[*][*][*]█[R][E][A][D][Y]█[*][*][*]█"
2975 IF INKEY$ ="" THEN GOTO 2970
2980 CLS
2985 PRINT "█[S][T][R][E][N][G][T][H]█ ";S;TAB 20;"█[G][O][L][D]█ ";G
2990 RETURN
3000 FOR N=1 TO 25
3010 PRINT AT 1,0;" *** YOU,RE DEAD. *** ";AT 1,0;"██████[*][*][*]█[Y][O][U][,][R][E]█[D][E][A][D][.]█[*][*][*]██████"
3020 NEXT N
3030 PRINT AT 1,0;" LIKE TO TRY AGAIN? (Y/N) "
3040 GOSUB 1500
3050 IF P$<>"Y" AND P$<>"N" THEN GOTO 3040
3060 IF P$="Y" THEN RUN
3070 NEW
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.