Murgatroyds

Products: Murgatroyds
Date: 1981
Type: Cassette
Platform(s): TS 1000
Tags: Game

Murgatroyds is a top-down chase game in which the player navigates a character across a grid arena while being hunted by eight enemies called Murgatroyds, luring them into a minefield to destroy them. The arena is drawn using block graphics characters for walls, with mines represented by CHR$ 8 and enemies by CHR$ 139 (the inverse-video character used on this platform). Screen memory is read directly via PEEK of the display file address obtained from system variable at address 16396/16397, allowing the program to detect tile contents (wall, mine, player, or enemy) without maintaining a separate map array. The player inputs compass bearings (e.g., “NW”, “SOUTHEAST”) to move, and a one-time “PANIC” jump teleports them to a random open cell. Difficulty increases across waves by reducing the number of mines (F1 decreases by 5 each wave), making later waves progressively harder.


Program Analysis

Program Structure

The program is organized into a clear linear flow with a few major sections:

  1. Lines 5–50: REMs, initialization of string arrays.
  2. Lines 60–160: Player name input, sanitization, and extraction of first initial.
  3. Lines 170–470: Instructions prompt and display.
  4. Lines 480–776: Game board initialization — draw arena, place mines, place Murgatroyds, place player.
  5. Lines 780–1360: Main game loop: player input, movement, enemy AI, mine collision, scoring.
  6. Lines 1370–1430: PANIC jump handler.
  7. Lines 1440–1560: Death handling.
  8. Lines 1520–1550: Victory handling.
  9. Lines 1560–1700: Replay prompt.
  10. Lines 1710–1890: Next-wave setup and animation.
  11. Lines 1900–1950: Exit/credits screen.
  12. Lines 2000–2010: SAVE line with auto-run.

Arena Drawing and Display File Inspection

The arena is rendered entirely with PRINT AT statements using block graphic characters. Lines 552–600 fill the screen with solid blocks first, then overwrite with the border frame (top: ▛▀…▀▜, sides: ▌…▐, bottom: ▙▄…▄▟) and dots for open space. Mines are printed as CHR$ 8 (a cursor-left character that renders as a block on this platform).

A key technique is the use of PEEK to read the display file directly, avoiding the need for a separate map array. Line 500 retrieves the display file base address from system variables at 16396 and 16397: LET D9=PEEK 16396+256*PEEK 16397. Cell contents are then read as PEEK (D9+1+P(I)+(L(I)*33)), using the formula where each screen row is 33 bytes wide (32 characters plus one attribute byte on this platform). This allows collision detection simply by checking the character code at the target cell.

Player Name Handling

The player name is stored in T$ (14 characters). Line 82 checks whether the first character is CHR$ 139 (an inverse-space, which can result from pressing a function key or entering blank input in certain ways) and ejects the player. Line 88 catches an all-spaces name and substitutes “NAMELESS ONE”. Lines 90–130 scan backwards through the name to find the last non-space character and append a “?” immediately after it — a neat way to add a suffix without knowing the name length in advance. The first letter of the name, stored in N$, is used as the player’s on-screen token.

Enemy AI

Eight Murgatroyds are tracked with row array L(8) and column array P(8). Each turn, for each live enemy, the program computes the delta to the player (L9, P9). Two movement modes are used:

  • Simple mode (lines 1090–1120): Moves independently in row and column toward the player, chosen when RND*3 < 1 (roughly 1/3 of the time).
  • Dominant-axis mode (lines 1140–1170): Moves only along whichever axis has the larger distance, chosen the remaining 2/3 of the time.

Line 1330 contains the “rogue Murgatroyd” mechanic mentioned in the instructions: IF INT(RND*8)=4 AND C1>1 THEN LET I=I-1. This causes a random enemy to take a second move in the same turn, making it unpredictable and more dangerous.

Enemies that hit a mine (D8=8) are killed: their position is marked with “*” (an explosion indicator), the mine cell is cleared, score increases by 10, and L(I) is set to 0 to flag the enemy as dead. Dead enemies are skipped at line 1030 (IF L(I)=0 THEN GOTO 1330). Enemies that encounter another Murgatroyd (D8=139) at lines 1230–1260 are blocked and stay put for that move.

Movement Input Parsing

Player movement is parsed from the 9-character string D$ using substring checks. The horizontal component checks D$(1 TO 2) for “NW”, “SW”, “NE”, “SE” and D$(1) for “W” or “E”. The vertical component checks D$(1) for “N” or “S”. Full-word forms like “NORTHWEST” and “SOUTHEAST” are also accepted. This means diagonal moves correctly update both row and column variables L2 and P2 from their initial values of L1 and P1.

Scoring and Difficulty

Score (S1) decreases by 1 per move when many mines remain (F1 > 15) and the score is positive, but increases by 1 per move when mines are sparse (F1 <= 15). Killing a Murgatroyd with a mine adds 10 points. Between waves, F1 is decremented by 5 (line 1710), reducing the number of mines placed in the next wave and making each successive wave harder. The PANIC teleport can only be used once per game (C3 counter), though line 1780 offers the player a fresh panic if they had used it in a wave they won.

Wave Transition Animation

Lines 1790–1880 animate a scrolling text display of Murgatroyd figures (represented as ["] patterns) and the player’s initial moving across the screen using a FOR loop over TAB positions, giving a simple marching effect before the next wave begins.

Notable Anomalies

  • Line 1440 prints a dot at the player’s old position before death is determined, meaning the player’s marker is erased even if the game ends. This is cosmetically minor but technically a sequencing quirk.
  • Line 1480 prints a Murgatroyd character at the enemy’s new position and line 1490 clears its old position — this is the “caught by Murgatroyd” sequence, but the enemy display update happens before the death message, which is correct.
  • The PRINT AT statement at line 1340 appends CHR$ 128 after the score — this is a space character (128 is a block graphic space on this platform) used to clear any leftover digit from a previously higher score value.
  • Line 85 (GOTO 60) is unreachable because line 84 is a STOP.

Content

Appears On

Related Products

Roam around the screen, trying to lure the Murgatroyds into traps. 16K.

Related Articles

Related Content

Image Gallery

Source Code

   5 REM     MURGATROYDS - ZX81  VERSION - OCCUPIES <7K BYTES.
   7 REM CGM01 COPYRIGHT COLLINS COMPUTING 1981.
   8 RAND 
  10 DIM G$(2)
  20 DIM T$(14)
  30 DIM N$(1)
  40 DIM D$(9)
  50 LET F1=25
  60 PRINT "WHAT""S YOUR NAME?"
  70 PRINT 
  80 INPUT T$
  82 IF T$(1)<>CHR$ 139 THEN GOTO 88
  83 PRINT "YOU DON""T LOOK  RELIABLE  TO ME.GET OUT - LET SOMEONE ELSE PLAY."
  84 STOP
  85 GOTO 60
  88 IF T$="              " THEN LET T$="NAMELESS ONE"
  90 FOR I=13 TO 1 STEP -1
 100 IF T$(I)=" " THEN GOTO 130
 110 LET T$(I+1)="?"
 120 LET I=1
 130 NEXT I
 140 LET N$=T$(1)
 150 IF N$<"A" OR N$>"Z" THEN LET N$="X"
 160 PRINT 
 170 PRINT "WOULD  YOU  LIKE  ME  TO  GIVE  YOU INSTRUCTIONS, ";T$
 180 INPUT D$
 190 CLS
 200 IF D$(1)="N" THEN GOTO 460
 210 PRINT "OK, YOUR  POSITION WILL BE SHOWN"
 220 PRINT "BY  A  LETTER """;N$;""" ON  THE  PLAN."
 230 PRINT "THE MURGATROYDS  ARE  CLOSING IN"
 240 PRINT "BUT YOU  CAN  LURE THEM TO THEIR"
 250 PRINT "DEATHS IN THE  MINEFIELD  (MINES"
 260 PRINT "ARE MARKED """;CHR$ 8;""").  BE CAREFUL  TO"
 270 PRINT "AVOID THE ELECTRIFIED  PERIMETER"
 300 PRINT "FENCE.  YOU  MOVE  BY GIVING THE"
 310 PRINT "COMPASS BEARING OF THE DIRECTION"
 320 PRINT "YOU WANT TO MOVE IN (EG. ""NW"" OR"
 330 PRINT """SOUTH"")."
 340 PRINT 
 350 PRINT "IF THERE  IS NO WAY OUT, YOU CAN"
 360 PRINT  "SAY  ""PANIC"" (OR ""P"")  TO  MAKE"
 370 PRINT "A  RANDOM (BUT  VERY  DANGEROUS)"
 380 PRINT "JUMP."
 382 PRINT 
 384 PRINT "AND WATCH  OUT  FOR  THE  ROGUE"
 386 PRINT "MURGATROYD  WHO  CHEATS."
 390 PRINT 
 400 PRINT "SAY ""GO"" WHEN YOU ARE"
 410 PRINT "READY  TO  START."
 420 INPUT G$
 430 CLS
 440 IF G$<>"GO" THEN GOTO 400
 450 GOTO 480
 460 PRINT "OK, SMARTYPANTS, HERE WE GO."
 470 PAUSE 99
 480 DIM P(8)
 490 DIM L(8)
 500 LET D9=PEEK 16396+256*PEEK 16397
 510 LET M1=0
 520 LET C1=8
 530 LET F1=25
 540 LET S1=0
 550 LET C3=0
 552 FOR I=0 TO 19
 554 PRINT AT I,0;"████████████████████████████████"
 556 NEXT I
 560 PRINT AT 0,0;"▛▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▜"
 570 FOR I=1 TO 18
 580 PRINT AT I,0;"▌.......................▐"
 590 NEXT I
 600 PRINT AT 19,0;"▙▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▟"
 610 FOR I=1 TO F1
 620 PRINT AT INT ((RND*17)+2),INT ((RND*22)+2);CHR$ 8
 630 NEXT I
 640 FOR I=1 TO 8
 650 LET L(I)=INT ((RND*17)+2)
 660 LET P(I)=INT ((RND*22)+2)
 670 LET D8=PEEK (D9+1+P(I)+(L(I)*33))
 680 IF CHR$ D8<>"." THEN GOTO 650
 710 PRINT AT L(I),P(I);CHR$ 139
 720 NEXT I
 730 LET L1=INT ((RND*17)+2)
 740 LET P1=INT ((RND*22)+2)
 750 LET L2=L1
 760 LET P2=P1
 772 LET D8=PEEK (D9+1+P1+(L1*33))
 774 IF CHR$ D8<>"." THEN GOTO 730
 776 PRINT AT L1,P1;N$
 780 PRINT AT 6,26;"SCORE"
 790 PRINT AT 9,28;S1
 800 PRINT AT 21,0;"MAKE YOUR MOVE"
 810 INPUT D$
 820 PRINT AT 20,0;"                                "
 830 PRINT AT 21,0;"                                "
 840 LET M1=M1+1
 850 IF F1>15 AND S1>0 THEN LET S1=S1-1
 860 IF F1<=15 THEN LET S1=S1+1
 870 IF D$(1 TO 2)="NW" OR D$="NORTHWEST" THEN LET P2=P1-1
 880 IF D$(1)="W" THEN LET P2=P1-1
 890 IF D$(1 TO 2)="SW" OR D$="SOUTHWEST" THEN LET P2=P1-1
 900 IF D$(1 TO 2)="NE" OR D$="NORTHEAST" THEN LET P2=P1+1
 910 IF D$(1)="E" THEN LET P2=P1+1
 920 IF D$(1 TO 2)="SE" OR D$="SOUTHEAST" THEN LET P2=P1+1
 930 IF D$(1)="N" THEN LET L2=L1-1
 940 IF D$(1)="S" THEN LET L2=L1+1
 950 IF D$(1)="P" THEN GOTO 1370
 960 LET D8=PEEK (D9+1+P2+(L2*33))
 970 IF CHR$ (D8)<>"." AND CHR$ (D8)<>N$ THEN GOTO 1440
 980 PRINT AT L1,P1;"."
 990 LET L1=L2
 1000 LET P1=P2
 1010 PRINT AT L2,P2;N$
 1020 FOR I=1 TO 8
 1030 IF L(I)=0 THEN GOTO 1330
 1040 LET L8=L(I)
 1050 LET P8=P(I)
 1060 LET L9=L1-L(I)
 1070 LET P9=P1-P(I)
 1080 IF RND*3>=1 THEN GOTO 1140
 1090 IF P9<0 THEN LET P(I)=P(I)-1
 1100 IF P9>0 THEN LET P(I)=P(I)+1
 1110 IF L9>0 THEN LET L(I)=L(I)+1
 1120 IF L9<0 THEN LET L(I)=L(I)-1
 1130 GOTO 1180
 1140 IF ABS (P9)>=ABS (L9) AND P9<0 THEN LET P(I)=P(I)-1
 1150 IF ABS (P9)>=ABS (L9) AND P9>0 THEN LET P(I)=P(I)+1
 1160 IF ABS (L9)>=ABS (P9) AND L9<0 THEN LET L(I)=L(I)-1
 1170 IF ABS (L9)>=ABS (P9) AND L9>0 THEN LET L(I)=L(I)+1
 1180 LET D8=PEEK (D9+1+P(I)+(L(I)*33))
 1190 IF D8=8 THEN PRINT AT L(I),P(I);"*"
 1200 IF D8=8 THEN PRINT AT L8,P8;"."
 1210 IF D8=8 THEN LET S1=S1+10
 1220 IF CHR$ (D8)=N$ THEN GOTO 1480
 1230 IF D8<>139 THEN GOTO 1270
 1240 LET L(I)=L8
 1250 LET P(I)=P8
 1260 GOTO 1330
 1270 IF D8=27 THEN PRINT AT L8,P8;"."
 1280 IF D8=27 THEN PRINT AT L(I),P(I);CHR$ 139
 1290 IF D8<>8 THEN GOTO 1330
 1300 LET C1=C1-1
 1310 PRINT AT L(I),P(I);"."
 1320 LET L(I)=0
 1330 IF INT (RND*8)=4 AND C1>1 THEN LET I=I-1
 1335 NEXT I
 1340 PRINT AT 9,28;S1;CHR$ 128
 1350 IF C1=0 THEN GOTO 1520
 1360 GOTO 800
 1370 LET C3=C3+1
 1380 IF C3=1 THEN GOTO 1420
 1390 PRINT AT 20,0;"SORRY, YOU CAN ONLY PANIC ONCE."
 1400 LET M1=M1-1
 1410 GOTO 800
 1420 PRINT AT L1,P1;"."
 1422 LET L1=INT ((RND*17)+2)
 1424 LET P1=INT ((RND*22)+2)
 1425 LET L2=L1
 1426 LET P2=P1
 1428 PRINT AT L1,P1;N$
 1430 GOTO 1020
 1440 PRINT AT L1,P1;"."
 1450 IF D8=139 THEN GOTO 1500
 1460 PRINT AT 20,0;"YOU HAVE BEEN KILLED - BAD LUCK."
 1470 GOTO 1560
 1480 PRINT AT L(I),P(I);CHR$ 139
 1490 PRINT AT L8,P8;"."
 1500 PRINT AT 20,0;"PITY - A MURGATROYD GOT YOU."
 1510 GOTO 1560
 1520 PRINT AT 20,0;"GOOD - THE MURGATROYDS ARE DEAD."
 1530 PRINT AT 4,26;"FINAL"
 1540 PRINT AT 21,0;"THAT TOOK YOU ";M1;" MOVES."
 1550 GOTO 1710
 1560 PRINT AT 21,0;"YOU LASTED ";M1;" MOVES."
 1570 PRINT AT 4,1;"                       "
 1580 PRINT AT 5,1;"     HOW    ABOUT      "
 1590 PRINT AT 6,1;"                       "
 1600 PRINT AT 7,1;"   ANOTHER   GAME ?    "
 1610 PRINT AT 8,1;"                       "
 1620 INPUT D$
 1630 IF D$(1)="N" THEN GOTO 1900
 1640 IF D$(1)="Y" THEN GOTO 1690
 1650 PRINT AT 5,1;"   DO   YOU   WANT     "
 1660 PRINT AT 6,1;"   ANOTHER   GAME ?    "
 1670 PRINT AT 7,1;"   YES    OR    NO     "
 1680 GOTO 1620
 1690 CLS
 1700 GOTO 510
 1710 LET F1=F1-5
 1720 LET C1=8
 1740 PAUSE 200
 1750 CLS
 1760 PRINT "THE  NEXT  WAVE OF  MURGATROYDS" 
 1770 PRINT "WILL NOT BE SO EASILY DEALT WITH"
 1780 IF C3>1 THEN PRINT "- BUT  YOU  CAN  PANIC  AGAIN."
 1785 LET C3=0
 1790 FOR F=0 TO 20
 1800 PRINT AT 7,0+F;" ["]   ["] ["]"
 1810 PRINT 
 1820 PRINT TAB 0+F;" ["]  ["] ["]"
 1830 PRINT 
 1840 PRINT TAB 0+F;" ["] ["]  ["]"
 1850 PRINT 
 1860 PRINT TAB 0+F;" ["]  ["]"
 1870 PRINT AT 10,9+F;" ";N$
 1880 NEXT F
 1890 GOTO 552
 1900 CLS
 1920 PRINT AT 5,8;"COPYRIGHT 1981"
 1930 PRINT AT 7,6;"COLLINS  COMPUTING"
 1950 STOP
 2000 SAVE "[M]"
 2010 GOTO 8

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

People

No people associated with this content.

Scroll to Top