---
title: "Muncher II"
id: 57497
type: "computer_media"
slug: "muncher-ii"
url: "http://localhost/computer_media/muncher-ii/"
markdown_url: "http://localhost/computer_media/muncher-ii.md"
published_at: "2024-10-05T21:03:33+00:00"
modified_at: "2026-04-03T07:58:28+00:00"
author: "David Anderson"
featured_image:
url: "http://localhost/wp-content/uploads/2024/10/252_Mun2.png"
excerpt: "A Pac-Man clone that stores its entire maze in a string array and uses character-cell indexing for all collision detection."
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/"
indiv:
- name: "Jim Broaddus"
slug: "jim-broaddus"
taxonomy: "indiv"
url: "http://localhost/indiv/jim-broaddus/"
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"
programmers:
- name: "Jim Broaddus"
slug: "jim-broaddus"
taxonomy: "indiv"
url: "http://localhost/indiv/jim-broaddus/"
mediadate: "198x"
images:
- url: "http://localhost/wp-content/uploads/2024/10/252_Mun2.png"
media_type_tags: "Game"
---
Muncher II is a Pac-Man–style maze game written in BASIC by James S. Broaddus (1983) in which the player navigates a character through a 21×21 grid collecting dots, power pellets, and bonus items while evading two ghosts. The entire maze is stored as a two-dimensional string array B$(21,21), with each cell representing a wall (“% “), dot (“.”), power pellet (“*”), tunnel (“-“), or space, allowing collision detection by simple string indexing. Two ghosts are tracked by separate coordinate pairs (GX/GY and GX1/GY1) and move by comparing their position to the player’s coordinates, with a skill-level parameter A controlling how often random direction changes override pursuit. Eating a power pellet (line 2000) sets a counter C to −1 and a COUNT timer so that ghosts temporarily display in a vulnerable appearance and are worth bonus points if caught. The tunnel mechanic at the left and right walls is implemented by checking for the “-” character and wrapping the player’s X coordinate between columns 2 and 20.
***
## Program Analysis
### Program Structure
The program is organised into several distinct functional blocks reached by `GOTO` and `GOSUB`:
- **Lines 1–7:** Variable initialisation and skill-level selection subroutine (`GOSUB 7000`).
- **Lines 8–210:** Maze construction — each row of the 21×21 board is assigned to `B$(N)` as a literal string.
- **Lines 220–240:** Initial maze render loop.
- **Lines 250–600:** Main game loop covering player input, movement, scoring, ghost AI, and win/loss detection.
- **Lines 1000–1040:** Bonus item (“£”) spawning subroutine.
- **Lines 1500–1650:** Horizontal movement handlers with tunnel-wrap logic.
- **Lines 1700–1830:** Vertical movement handlers.
- **Lines 2000–2060:** Power-pellet consumption — activates vulnerable ghost mode.
- **Lines 3000–3110:** Ghost movement execution — each branch moves a ghost coordinate then jumps into the continuation of the ghost-update block.
- **Lines 4000–4020:** Stop-movement handler for unrecognised keys.
- **Lines 5000–5080:** Level-clear animation (sweeping line across row 10) and restart.
- **Lines 7000–7110:** Title screen and skill-level input.
- **Lines 8000–8110:** Ghost-catch scoring — awards points and resets ghost positions.
- **Lines 9000–9600:** Death/game-over sequence, high-score update, and `SAVE`.
### Maze Representation
The maze is held in a `DIM B$(21,21)` two-dimensional string array where each element is a two-character cell. Wall cells contain `"% "` (percent-space), dots are `"."` plus a space, power pellets are `"*"`, tunnel exits are `"-"`, and the bonus item is represented by `"£"`. Because BASIC’s DIM pads shorter strings, assigning a 42-character string to a 21-element row fills every two-character cell simultaneously. Collision detection is then performed by reading individual cells such as `B$(Y,X+1)` directly.
A practical consequence is that the program never builds a separate collision map — the display state *is* the game state. Eating a dot or pellet is effected by `LET B$(Y,X)=" "` at line 400, which simultaneously clears the map and prevents re-collection.
### Player Movement
Direction is encoded in two variables: `R` (horizontal delta, −1/0/1) and `E` (vertical delta, −1/0/1). Movement keys 5/6/7/8 route to subroutines at lines 1500–1830 that update `R`, `E`, and the avatar character `A$` (`">"`, `"<"`, `"A"`, `"V"`). Any other non-directional key jumps to line 4000 which zeroes both deltas, halting the player. The actual position update at lines 370–371 tests the destination cell before committing the move.
### Tunnel Mechanic
Row 12 of the maze contains `"-"` characters at columns 1 and 21, representing tunnel exits. The movement routines detect a `"-"` in the direction of travel and set `CHECK=0`, which causes lines 1530/1630 to teleport `X` to column 2 or 20 respectively before continuing normal movement processing.
### Ghost AI
Two ghosts share coordinate pairs (`GX`,`GY`) and (`GX1`,`GY1`). Each game-loop iteration compares the ghost coordinates to the player’s `Y`,`X` and attempts to step toward them if the destination cell is not a wall. The skill-level parameter `A` (range 0.2–0.6, lower = harder) is used as a probability threshold: `IF RND"-"` instead of `B$(Y+1,X)<>"-"`, making the downward-movement tunnel guard test the wrong row.
- Lines 3060 and 3070 incorrectly write `LET GY=GY1+C` (overwriting ghost 1’s Y with ghost 2’s Y plus C) instead of `LET GY1=GY1+C`. This is a variable-name bug causing ghost 1 to be displaced when ghost 2 moves right.
- The level-clear animation at lines 5010–5060 prints a sweeping pattern across row 10, using embedded `">"` and `"<"` characters to simulate a wiper effect before restarting at line 8.
- `A$` doubles as both the display character and a state indicator for direction — direction-sensitive scoring or behaviour could easily be added by testing `A$`.
- Line 8060 contains a logic error: `IF GY>=X OR GX1<>Y` should likely be `GY1>=X` to compare ghost 2’s column against the player, mirroring the ghost-1 check at line 8000.
## Source Code
```
1 LET S=0
2 LET HS=0
3 LET T=180
4 DIM B$(21,21)
5 LET COUNT=30
6 LET LIVES=3
7 GOSUB 7000
8 LET CHECK=1
9 LET E=0
10 LET R=1
11 LET B$(1)="% % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % "
20 LET B$(2)="% .........% .........% "
30 LET B$(3)="% .% % % .% % % .% .% % % .% % % .% "
40 LET B$(4)="% *% % % .% % % .% .% % % .% % % *% "
50 LET B$(5)="% .% % % .% % % .% .% % % .% % % .% "
60 LET B$(6)="% ...................% "
70 LET B$(7)="% .% % % .% .% % % % % .% .% % % .% "
80 LET B$(8)="% .....% ...% ...% .....% "
90 LET B$(9)="% % % % % .% .......% .% % % % % "
100 LET B$(10)="% % % % % .% .......% .% % % % % "
110 LET B$(11)="% % % % % .% .% ---% .% .% % % % % "
120 LET B$(12)="-.......% % .......-"
130 LET B$(13)="% % % % % .% .% ---% .% .% % % % % "
140 LET B$(14)="% % % % % .% .... ..% .% % % % % "
150 LET B$(15)="% % % % % .% .% % % % % .% .% % % % % "
160 LET B$(16)="% .........% .........% "
170 LET B$(17)="% *% % % .% % % .% .% % % .% % % *% "
180 LET B$(18)="% ...% ...........% ...% "
190 LET B$(19)="% % % .% .% % % % % % % % % .% .% % % "
200 LET B$(20)="% % % ...............% % % "
210 LET B$(21)="% % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % "
220 FOR N=1 TO 21
230 PRINT AT N,1;B$(N)
240 NEXT N
250 LET Y=14
255 LET E$=" "
260 LET X=12
265 LET D$=" "
270 LET A$=">"
275 LET C=1
280 LET GX=12
285 LET GY=12
290 LET GX1=12
295 LET GY1=11
300 PRINT AT GX,GY;"%""
310 PRINT AT GX1,GY1;"%""
320 PRINT AT Y,X;A$
325 PRINT AT 0,0;"LIVES:";LIVES;AT 0,19;"HI-SCORE:";HS
330 IF INT (RND*50)=0 THEN GOSUB 1000
335 PRINT AT Y,X;" "
340 IF INKEY$="8" OR (B$(Y,X+1)="-" AND R=1) THEN GOTO 1500
350 IF INKEY$="5" OR (B$(Y,X-1)="-" AND R=-1) THEN GOTO 1600
355 IF INKEY$<>"5" AND INKEY$<>"6" AND INKEY$<>"7" AND INKEY$<>"8" AND INKEY$<>"" THEN GOTO 4000
360 IF INKEY$="7" THEN GOSUB 1700
365 IF INKEY$="6" THEN GOSUB 1800
370 IF B$(Y,X+R)<>"-" AND B$(Y,X+R)<>"% " THEN LET X=X+R
371 IF B$(Y+E,X)<>"% " THEN LET Y=Y+E
375 IF B$(Y,X)="*" THEN GOSUB 2000
380 IF B$(Y,X)="." THEN LET S=S+1
390 IF B$(Y,X)="£" THEN LET S=S+10
395 IF B$(Y,X)="£" THEN LET T=T+10
400 LET B$(Y,X)=" "
405 PRINT AT 0,8;"SCORE:";S
410 PRINT AT Y,X;A$
415 IF S=T THEN GOTO 5000
420 PRINT AT GX,GY;D$;AT GX1,GY1;E$
425 IF RND"% " AND B$(GX,GY+C)<>"% " THEN GOTO 3000
436 IF RNDX AND B$(GX,GY-C)<>"% " AND B$(GX,GY-C)<>"-" THEN GOTO 3020
446 IF RND"% " THEN GOTO 3040
456 IF RNDY AND B$(GX-C,GY)<>"% " THEN LET GX=GX-C
465 IF RND"% " AND B$(GX1,GY1+C)<>"-" THEN GOTO 3060
474 IF RNDX AND B$(GX1,GY1-C)<>"% " AND B$(GX1,GY1-C)<>"-" THEN GOTO 3080
478 IF RND"% " THEN GOTO 3100
486 IF RNDY AND B$(GX1-C,GY1)<>"% " THEN LET GX1=GX1-C
500 LET COUNT=COUNT+1
510 IF COUNT>=30 THEN LET C=1
520 IF C=-1 THEN PRINT AT GX,GY;""""
525 IF C=1 THEN PRINT AT GX,GY;"%""
530 IF C=-1 THEN PRINT AT GX1,GY1;""""
535 IF C=1 THEN PRINT AT GX1,GY1;"%""
540 IF GX=Y AND GY=X THEN GOTO 9000
550 IF GX1=Y AND GY1=X THEN GOTO 9000
560 LET D$=B$(GX,GY)
570 LET E$=B$(GX1,GY1)
580 LET CHECK=1
600 GOTO 330
1000 IF B$(14,11)="£" THEN RETURN
1010 PRINT AT 14,11;"£"
1020 IF B$(14,11)="." THEN LET T=T-1
1030 LET B$(14,11)="£"
1040 RETURN
1500 PRINT AT Y,X;" "
1510 LET A$=">"
1520 IF B$(Y,X+1)="-" THEN LET CHECK=0
1530 IF CHECK=0 THEN LET X=2
1535 IF CHECK=0 THEN GOTO 375
1540 IF B$(Y,X+1)<>"% " THEN LET R=1
1545 IF B$(Y,X+1)<>"% " THEN LET E=0
1550 GOTO 370
1600 PRINT AT Y,X;" "
1610 LET A$="<"
1620 IF B$(Y,X-1)="-" THEN LET CHECK=0
1630 IF CHECK=0 THEN LET X=20
1635 IF CHECK=0 THEN GOTO 375
1640 IF B$(Y,X-1)<>"% " THEN LET R=-1
1645 IF B$(Y,X-1)<>"% " THEN LET E=0
1650 GOTO 370
1700 PRINT AT Y,X;" "
1710 IF B$(Y-1,X)<>"% " AND B$(Y-1,X)<>"-" THEN LET E=-1
1715 IF B$(Y-1,X)<>"% " AND B$(Y-1,X)<>"-" THEN LET R=0
1720 LET A$="A"
1730 RETURN
1800 PRINT AT Y,X;" "
1810 IF B$(Y+1,X)<>"% " AND B$(Y-1,X)<>"-" THEN LET E=1
1815 IF B$(Y+1,X)<>"% " AND B$(Y-1,X)<>"-" THEN LET R=0
1820 LET A$="V"
1830 RETURN
2000 LET S=S+10
2010 LET C=-1
2020 LET B$(Y,X)=" "
2030 PRINT AT Y,X;A$
2040 LET T=T+10
2050 LET COUNT=0
2060 RETURN
3000 LET GY=GY+C
3010 GOTO 470
3020 LET GY=GY-C
3030 GOTO 470
3040 LET GX=GX+C
3050 GOTO 470
3060 LET GY=GY1+C
3070 GOTO 500
3080 LET GY1=GY1-C
3090 GOTO 500
3100 LET GX1=GX1+C
3110 GOTO 500
4000 LET R=0
4010 LET E=0
4020 GOTO 360
5000 CLS
5005 PRINT AT 10,31;"*"
5010 FOR N=1 TO 27
5020 PRINT AT 10,N;" %" >"
5025 REM SHEET CLEARED
5030 NEXT N
5040 FOR N=27 TO 1 STEP -1
5050 PRINT AT 10,N;""" < "
5060 NEXT N
5070 LET T=T+180
5080 GOTO 8
7000 PRINT AT 0,12;"MUNCHER II";TAB 11;"''''''''''''''''''''"
7010 PRINT AT 9,0;"--------------------------------"
7020 PRINT AT 11,3;"SELECT SKILL LEVEL (1-5)"
7030 PRINT TAB 7;"(5 IS THE EASIEST)"
7040 PRINT AT 14,0;"--------------------------------"
7050 PRINT TAB 5;" JAMES S. BROADDUS 1983"
7060 LET A=CODE INKEY$-28
7070 IF A>5 OR A<1 THEN GOTO 7060
7080 LET A=A/10
7090 LET A=A+.1
7100 CLS
7110 RETURN
8000 IF GY<>X OR GX<>Y THEN GOTO 8060
8010 LET S=S+10
8020 LET T=T+10
8030 LET GY=12
8040 LET GX=12
8045 PRINT AT Y,X;A$
8050 GOTO 500
8060 IF GY>=X OR GX1<>Y THEN GOTO 500
8070 LET S=S+10
8080 LET T=T+10
8090 LET GY1=11
8100 LET GX1=12
8105 PRINT AT Y,X;A$
8110 GOTO 500
9000 IF COUNT<=30 THEN GOTO 8000
9005 LET LIVES=LIVES-1
9010 FOR N=1 TO 10
9015 PRINT AT Y,X;A$
9016 FOR Q=1 TO 2
9017 NEXT Q
9018 PRINT AT Y,X;CHR$ (CODE A$+128)
9019 NEXT N
9020 IF LIVES<=0 THEN GOTO 9500
9025 CLS
9030 GOTO 210
9500 IF HS