--- title: "Super Monzxer" id: 57509 type: "computer_media" slug: "super-monzxer" url: "http://localhost/computer_media/super-monzxer/" markdown_url: "http://localhost/computer_media/super-monzxer.md" published_at: "2024-10-05T21:15:20+00:00" modified_at: "2026-04-03T07:58:26+00:00" author: "David Anderson" featured_image: url: "http://localhost/wp-content/uploads/2024/10/264_SM.png" excerpt: "A fully playable Wumpus-style cave hunt across five dungeon levels, complete with a pixel-art monster intro screen and procedurally generated room networks." category: - name: "Archived Media" slug: "archived-media" taxonomy: "category" url: "http://localhost/category/archived-media/" post_tag: - name: "Downloadable" slug: "downloadable" taxonomy: "post_tag" url: "http://localhost/tag/downloadable/" - name: "TS 1000" slug: "ts1000" taxonomy: "post_tag" url: "http://localhost/tag/ts1000/" model: - name: "Timex/Sinclair 1000" slug: "ts-1000" taxonomy: "model" url: "http://localhost/model/ts-1000/" genre: - name: "Game" slug: "game" taxonomy: "genre" url: "http://localhost/type/game/" media_contents: - id: 56737 title: "Timex Sinclair Public Domain Library Tape 1006" type: "computer_media" url: "http://localhost/computer_media/timex-sinclair-public-domain-library-tape-1006/" media_type: "Program" mediadate: "198x" images: - url: "http://localhost/wp-content/uploads/2024/10/264_SM.png" media_type_tags: "Game" --- MONZXER is a text-based cave exploration game in the tradition of Hunt the Wumpus, where the player navigates a procedurally generated dodecahedral-style cave network spread across five levels of 20 rooms each, hunting monsters called Monzxers while avoiding spiders, bats, and pits. The cave graph is constructed at lines 399–510 using a randomised adjacency array R(3,101), giving each room three tunnel connections, with hazard positions stored in separate arrays for enemies, spiders, bats, and pits. Player actions include moving between rooms or firing arrows at Monzxers (Z) or Spiders (D), with a limited supply of six arrows tracked by S1. The title screen uses nested PLOT/UNPLOT loops to draw a pixel-art monster graphic before entering SLOW mode for the game, and the SAVE command at line 3580 uses an inverse-video character in the filename as an auto-run flag. *** ## Program Analysis ### Program Structure The program divides into several distinct phases: 1. **Title/Graphics (lines 1–393):** Draws a pixel-art Monzxer sprite using `PLOT`/`UNPLOT` loops, prints the title, enters `SLOW` mode, then pauses. 2. **Cave Generation (lines 398–510):** Allocates and populates the room adjacency array `R(3,101)` with bidirectional tunnel connections across 100 rooms. 3. **Game Initialisation (lines 525–960):** Places hazards (Monzxers in `W`, spiders in `S`, bats in `B`, pits in `P`), builds encounter hint arrays `T`, `C`, `Q`, and the Monzxer adjacency index `X`. 4. **Main Game Loop (lines 1000–2290):** Describes the current room, reports hazard warnings, handles movement and shooting. 5. **End Sequences (lines 2990–3170):** Win/lose screens, play-again prompt, optional re-use of tunnel set. 6. **Spider-death Subroutine (lines 3500–3560):** Prints an ASCII-art dead spider. ### Cave Graph Construction Lines 399–510 build a bidirectional adjacency structure in `R(3,101)`. Each room (index 1–100) gets three neighbours. The algorithm iterates rooms in groups of five within four bands of 20 (via `L=0 TO 80 STEP 20`), randomly picking a target room `G` and checking that the reverse link slot is free before writing both directions. The check at line 437 prevents duplicate edges within the same group-of-five, and line 445 prevents assigning the same back-link twice. This is a constrained random graph rather than a true dodecahedron, but it produces a connected-enough cave for gameplay. ### Level System One hundred rooms are logically divided into five levels of 20 rooms each. `YL` (lines 1010–1015) is derived from `YR` by integer division. Room numbers are always displayed relative to the level base (`YR-(YL-1)*20`), so the player sees rooms 1–20 on every level. Tunnels stored in `R` use absolute room numbers, and `(YL-1)*20` offsets are applied when printing tunnel destinations (line 1560) and when accepting movement input (line 1720). Falling into a pit on levels 1–4 drops the player to the next level down by adding 20 to `YR` (line 1500); on level 5 it is instantly fatal (line 1520). ### Hazard Arrays | Array | Size | Contents | | --- | --- | --- | | `W(3)` | 3 | Monzxer locations (absolute room numbers) | | `S(10)` | 10 | Spider room indices (into `R`) | | `B(10)` | 10 | Bat room indices | | `P(10)` | 10 | Pit room indices | | `T(30)` | 30 | Rooms adjacent to spiders (cobweb hint) | | `C(30)` | 30 | Rooms adjacent to bats | | `Q(30)` | 30 | Rooms adjacent to pits (draft hint) | | `X(36)` | 36 | Rooms near Monzxers (smell hint, two hops) | The `X` array (lines 870–960) is built in two passes: first the three rooms directly adjacent to each Monzxer, then the nine rooms one step further out, giving a two-hop smell radius. Monzxers that have been killed are marked with room number 101 (an out-of-range sentinel) rather than being removed from the arrays. ### Shooting Mechanic When the player chooses to shoot (line 1630), they input a path of up to 5 rooms (stored in `A(2)`–`A(6)`; `A(1)` is the current room). At each step (lines 2140–2160), if the nominated room is not a valid tunnel from the previous room, the arrow is redirected to a random neighbour (lines 2165–2170). The arrow kills whichever target type matches the mode (`S$="Z"` for Monzxer, `S$="D"` for Spider). Shooting yourself (arrow path loops back to `YR`) triggers instant death at line 2240. The arrow supply `S1` starts at 6 and decrements each shot; reaching zero ends the game. ### Key BASIC Idioms and Techniques - The `PAUSE 900` / `INKEY$` pattern at lines 1600–1640 and 2012–2017 implements key-wait loops without halting execution, consistent with ZX81/TS1000 practice. - `SLOW` / `FAST` mode switching at lines 395, 398, 1005, and 3135–3165 controls display stability around intensive operations. - Line 3060 branches to non-existent line 3020, which causes the interpreter to resume at line 3030 — a deliberate technique to re-enter the INKEY$ poll loop. - The variable name `END` is used as a flag (lines 5, 396, 3160) to signal whether the end-game graphic loop should stop — it is not a reserved keyword in this dialect. - The title graphic is re-entered via `GOTO 70` at line 3170 after a loss, creating an attract-mode loop without redrawing the full screen. ### ASCII / Block-Graphic Art The in-game spider and dead-spider images (lines 1423–1428 and 3500–3560) use block graphic characters and standard punctuation to render multi-row ASCII art directly in `PRINT AT` statements. The dead spider subroutine at line 3500 is shared between the shooting-a-spider path (line 2036) and the spider-kill-on-move path (line 2217). ### Bugs and Anomalies - **Line 2020 / 2030:**`NEXT I` at line 2020 is only reached if the spider check loop completes without a match (no spider in current room at shoot time), but the `GOTO 2060` at line 2030 is unreachable because lines 2011–2017 loop indefinitely waiting for a valid keypress before falling through — the spider-check loop body overwrites the flow with an unconditional wait starting at line 2011. - **Line 2195:** The spider-arrow check reads `IF YR=S(I)` rather than `IF A(I)=S(J)` or similar, comparing the player’s room against a spider-room index rather than comparing the arrow’s current path node, likely a logic error that makes the spider-arrow kill nearly non-functional. - **Line 1295:** After killing a Monzxer in the player’s room, the code sets `W(I)=101` and then does `GOTO 870` (re-initialise hazard display arrays), but `I` is the outer loop variable from line 1240; this is valid as long as `I≤3`, which the guard at line 1295 enforces. - **Line 1026:** If `YR>99` after level adjustment, `YR` is set to `INT(RND*100)-1`, which can produce 0 or negative values — an edge-case bug for very high room numbers. ## Source Code ``` 1 REM "MONZXER" 2 RAND 5 LET END=0 50 PRINT AT 10,20;"SUPER" 60 PRINT AT 12,18;"MONZXER" 70 FOR I=3 TO 37 80 FOR J=11 TO 19 87 UNPLOT 9,16 90 PLOT J,I 100 NEXT J 110 NEXT I 120 FOR I=16 TO 24 130 FOR J=8 TO 22 140 PLOT J,I 150 NEXT J 160 NEXT I 170 FOR I=22 TO 32 180 PLOT 6,I 190 PLOT 24,I 200 NEXT I 210 PLOT 5,22 220 PLOT 7,22 225 PLOT 7,21 230 PLOT 23,22 235 PLOT 25,22 240 PLOT 23,24 245 PLOT 25,21 250 PLOT 9,35 255 PLOT 10,35 265 PLOT 10,36 270 PLOT 20,36 275 PLOT 20,35 280 PLOT 21,35 285 FOR I=14 TO 16 290 FOR J=3 TO 16 295 UNPLOT I,J 300 NEXT J 305 NEXT I 307 PLOT 23,33 312 PLOT 7,33 315 PLOT 7,32 320 FOR I=5 TO 25 325 IF I=14 THEN LET I=17 330 PLOT I,3 335 NEXT I 338 FOR I=6 TO 24 340 IF I=14 THEN LET I=17 342 PLOT I,4 345 NEXT I 350 PRINT AT 21,3;""" """ 352 PRINT AT 21,9;""" """ 355 PRINT AT 7,5;"Q" 357 PRINT AT 7,9;"Q" 360 PRINT AT 9,5;" " 365 PRINT AT 5,22;" ----/" 370 PRINT AT 4,28;"/" 375 PRINT AT 3,29;"/" 380 PRINT AT 2,30;"/" 382 UNPLOT 8,17 385 UNPLOT 8,16 387 UNPLOT 9,16 390 UNPLOT 21,16 392 UNPLOT 22,16 393 UNPLOT 22,17 395 SLOW 396 IF END=1 THEN STOP 397 PAUSE 600 398 FAST 399 DIM R(3,101) 400 DIM A(6) 401 FOR I=1 TO 3 402 FOR J=1 TO 101 403 LET R(I,J)=INT (RND*100)+1 404 NEXT J 405 NEXT I 406 LET SW=0 407 LET DM=0 408 FOR L=0 TO 80 STEP 20 410 FOR I=1 TO 20 415 LET K=L+I 420 FOR J=1 TO 3 422 LET J1=J 425 IF J10 THEN GOTO 495 435 LET G=INT (RND*5)+J1*5+L+1 436 FOR M=1 TO 5 437 IF R(J,L+M+INT ((I-1)/5)*5)=G THEN GOTO 435 438 NEXT M 440 FOR H=1 TO 3 445 IF R(H,G)=K THEN GOTO 435 450 IF R(H,G)=0 THEN GOTO 465 455 NEXT H 460 GOTO 435 465 LET R(J,K)=G 490 LET R(H,G)=K 495 NEXT J 500 NEXT I 510 NEXT L 525 LET YR=INT (RND*20)+1 535 LET S1=6 610 DIM X(36) 620 DIM T(30) 630 DIM C(30) 640 DIM Q(30) 650 DIM W(3) 660 DIM S(10) 670 DIM B(10) 680 DIM P(10) 690 LET DM=0 695 LET SW=0 700 LET SR=INT (RND*100)+1 710 FOR I=1 TO 3 720 LET W(I)=INT (RND*100)+1 725 IF W(I)=YR THEN GOTO 720 730 NEXT I 740 FOR I=1 TO 9 STEP 2 745 FOR J=0 TO 1 750 LET S(I+J)=(INT (RND*20)+1)+20*INT (I/2) 760 LET B(I+J)=(INT (RND*20)+1)+20*INT (I/2) 770 LET P(I+J)=(INT (RND*20)+1)+20*INT (I/2) 780 NEXT J 790 NEXT I 800 FOR I=0 TO 9 810 FOR J=1 TO 3 820 LET T(I*3+J)=R(J,S(I+1)) 830 LET C(I*3+J)=R(J,B(I+1)) 840 LET Q(I*3+J)=R(J,P(I+1)) 850 NEXT J 860 NEXT I 870 FOR I=0 TO 2 880 FOR J=1 TO 3 890 LET X(I*3+J)=R(J,W(I+1)) 900 FOR L=1 TO 3 910 LET GG=((J-1)*3)+(I*9)+L+9 920 LET X(GG)=R(L,X(I*3+J)) 930 NEXT L 950 NEXT J 960 NEXT I 1000 CLS 1005 SLOW 1010 LET YL=INT ((YR-1)/20)+1 1015 IF YL>5 THEN LET YL=1 1020 PRINT "YOU ARE ON LEVEL ";YL 1024 LET YR=YR-(YL-1)*20 1026 IF YR>99 THEN LET YR=INT (RND*100)-1 1030 PRINT "YOU ARE IN ROOM ";YR 1032 IF YR=SR THEN PRINT "THERE IS A SWORD IN THE ROOM" 1037 IF YR=SR THEN LET SW=1 1040 FOR I=1 TO 30 1050 IF YR=T(I) THEN GOTO 1080 1060 NEXT I 1070 GOTO 1090 1080 PRINT "I SEE COBWEBS" 1090 FOR I=1 TO 36 1100 IF YR=X(I) THEN GOTO 1130 1110 NEXT I 1120 GOTO 1140 1130 PRINT "I SMELL A MONZXER" 1140 FOR I=1 TO 30 1150 IF YR=Q(I) THEN GOTO 1180 1160 NEXT I 1170 GOTO 1190 1180 PRINT "I FEEL A DRAFT" 1190 FOR I=1 TO 30 1200 IF YR=C(I) THEN GOTO 1230 1210 NEXT I 1220 GOTO 1240 1230 PRINT "BATS NEARBY" 1240 FOR I=1 TO 3 1250 IF YR=W(I) THEN GOTO 1280 1260 NEXT I 1270 GOTO 1300 1280 PRINT "THERE IS A MONZXER IN YOUR ROOM" 1281 IF SW=1 THEN GOTO 1285 1282 PRINT "AND IT ATE YOU,DUMMY" 1284 GOTO 3000 1285 PRINT "BUT YOU KILLED IT WITH YOUR SWORD" 1290 PAUSE 300 1292 LET DM=DM+1 1294 IF DM=3 THEN GOTO 2990 1295 IF I>3 THEN LET I=1 1297 LET W(I)=101 1298 GOTO 870 1300 FOR I=1 TO 10 1310 IF YR=B(I) THEN GOTO 1340 1320 NEXT I 1330 GOTO 1380 1340 CLS 1350 LET YR=(INT (RND*20)+1)+(YL-1)*20 1360 PRINT "BATS TOOK YOU TO ROOM ";YR-(YL-1)*20 1370 GOTO 1010 1380 FOR I=1 TO 10 1390 IF YR=S(I) THEN GOTO 1420 1400 NEXT I 1410 GOTO 1430 1420 PRINT "THERE IS A SPIDER IN YOUR ROOM AND HE IS HUNGRY" 1423 PRINT AT 9,10;"/..!!!!!!../ % % " 1424 PRINT AT 10,9;"% %Q''''''%Q% % % % % % % " 1425 PRINT AT 11,9;"% % :....:% % @@% % % % % % % % /" 1427 PRINT AT 12,17;"IL IL IL" 1428 PRINT AT 14,7;"YUM YUM EATEM UP" 1429 PAUSE 100 1430 FOR I=1 TO 10 1440 IF YR=P(I) THEN GOTO 1470 1450 NEXT I 1460 GOTO 1540 1470 IF YL=5 THEN GOTO 1520 1480 CLS 1490 PRINT "TSK, TSK, YOU FELL IN A PIT" 1500 LET YR=YR+20 1505 IF YL>=2 THEN GOTO 1540 1510 GOTO 1010 1520 PRINT "YOU FELL INTO A BOTTOMLESS PIT YOU TURKEY" 1530 GOTO 3000 1540 PRINT "TUNNELS TO ROOMS "; 1550 FOR I=1 TO 3 1560 PRINT " ";ABS (R(I,YR)-(YL-1)*20); 1570 NEXT I 1580 PRINT 1590 PRINT "YOU MUST MOVE OR SHOOT" 1600 PAUSE 900 1610 LET K$=INKEY$ 1620 IF K$="M" THEN GOTO 1650 1630 IF K$="S" THEN GOTO 2000 1640 GOTO 1600 1650 FOR I=1 TO 10 1652 IF YR=S(I) THEN GOTO 1657 1654 NEXT I 1656 GOTO 1659 1657 PRINT "THE SPIDER IS MUNCHING ON YOU" 1658 GOTO 3000 1659 PRINT "WHICH ROOM?" 1660 INPUT YR1 1670 FOR I=1 TO 3 1680 IF YR1=ABS (R(I,YR)-(YL-1)*20) THEN GOTO 1720 1690 NEXT I 1700 PRINT "NO TUNNEL TO THIS ROOM...SIGNED, MONZXER" 1710 GOTO 1650 1720 LET YR=YR1+(YL-1)*20 1730 GOTO 1000 2000 LET S1=S1-1 2005 FOR I=1 TO 10 2010 IF YR=S(I) THEN GOTO 2035 2011 IF K$="S" THEN PRINT "MONZXER=Z OR SPIDER=D" 2012 PAUSE 900 2014 LET S$=INKEY$ 2015 IF S$="Z" THEN GOTO 2060 2016 IF S$="D" THEN GOTO 2060 2017 GOTO 2012 2020 NEXT I 2030 GOTO 2060 2035 CLS 2036 GOSUB 3500 2037 PRINT AT 18,5;"YOU KILLED THE SPIDER..." 2038 PRINT "%H%U%R%R%A%Y% %H%U%R%R%A%Y" 2040 PAUSE 300 2043 IF I>10 THEN LET I=1 2045 LET S(I)=101 2050 GOTO 800 2060 CLS 2070 PRINT "MAKE A LIST OF 5 ROOMS FOR THE ARROWS FLIGHT" 2080 FOR I=2 TO 6 2090 INPUT A(I) 2100 PRINT A(I) 2105 LET A(I)=A(I)+(YL-1)*20 2110 NEXT I 2120 LET A(1)=YR 2130 FOR I=2 TO 6 2140 FOR J=1 TO 3 2150 IF A(I)=R(J,A(I-1)) THEN GOTO 2180 2160 NEXT J 2165 LET J=INT (RND*3)+1 2170 LET A(I)=R(J,A(I-1)) 2180 FOR J=1 TO 3 2190 IF A(I)=W(J) AND S$="Z" THEN GOTO 2220 2195 IF YR=S(I) AND S$="D" THEN GOTO 2215 2200 NEXT J 2210 GOTO 2230 2215 PRINT "YOU SLEW A SPIDER" 2217 GOSUB 3500 2218 GOTO 2040 2220 PRINT "YOU SLEW A MONZXER" 2221 IF J>3 THEN LET J=1 2222 LET W(J)=101 2223 PAUSE 300 2224 LET DM=DM+1 2225 IF DM=3 THEN GOTO 2990 2226 IF S1=0 THEN GOTO 2283 2228 GOTO 870 2230 IF NOT A(I)=YR THEN GOTO 2260 2240 PRINT "YOU SHOT YOURSELF" 2250 GOTO 3000 2260 NEXT I 2265 IF S$="D" THEN GOTO 2275 2270 PRINT "YOU MISSED THE MONZXER" 2273 GOTO 2280 2275 PRINT "YOU MISSED THE SPIDER" 2280 PAUSE 300 2283 IF S1=0 THEN PRINT "YOU ARE OUT OF ARROWS" 2285 IF S1=0 THEN GOTO 3000 2290 GOTO 1000 2990 PRINT "NO MORE MONZXERS YOU WIN ...SHUCKS" 3000 PAUSE 600 3005 CLS 3010 PRINT AT 10,10;"PLAY AGAIN?" 3030 LET K$=INKEY$ 3040 IF K$="Y" THEN GOTO 3070 3050 IF K$="N" THEN GOTO 3130 3060 GOTO 3020 3070 PRINT AT 10,6;"SAME TUNNEL SET?" 3090 LET K$=INKEY$ 3100 IF K$="Y" THEN GOTO 525 3110 IF K$="N" THEN GOTO 398 3112 GOTO 3090 3130 CLS 3135 FAST 3140 PRINT AT 10,20;"HAR HAR" 3150 PRINT AT 12,18;"YOU LOSE" 3160 LET END=1 3165 FAST 3170 GOTO 70 3500 PRINT AT 10,9;"TT TT TT" 3510 PRINT AT 11,8;"/% % % % % % % % @@% % :'''':% % " 3520 PRINT AT 12,5;">>===%=%=%>% % % % % %Q......%Q% " 3530 PRINT AT 13,11;"% % % % % /;;;;;;''/" 3540 PRINT AT 14,12;"% % % " 3542 PRINT AT 9,20;"? ?" 3544 PRINT AT 7,24;"?" 3546 PRINT AT 5,27;"?" 3550 PRINT AT 16,22;"YA GOT ME" 3560 RETURN 3570 CLEAR 3580 SAVE "1026%4" 3590 RUN ```