Micro Mouse

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

MICROMOUSE is a maze-navigation simulation in which a cursor character wanders through a randomly generated obstacle field, trying to reach a fixed goal at screen position (20,30). The maze is built using a combination of inverse-video block characters and block graphics printed at randomised AT positions during a setup loop (lines 30–60). The mouse’s movement logic tests eight compass directions by issuing a PRINT AT to the candidate cell, then reading the display RAM address stored in system variables G (16398) and H (16399) to determine whether that cell is blank (character code 0), implementing a collision-detection technique entirely through PEEK of the display file pointer. A move counter Q accumulates attempts, and on reaching the goal the score is displayed briefly before the maze is regenerated.


Program Analysis

Program Structure

The program divides into four logical phases:

  1. Initialisation (lines 1–6): Stores the display-file pointer address in G (16398) and H (16399).
  2. Maze generation (lines 10–68): Draws top and bottom border rows of inverse spaces, then randomises wall segments and block graphics across the interior in a FOR A=1 TO 20 loop. A second short loop (lines 61–68) animates the goal marker at (20,30) by flashing it.
  3. Movement engine (lines 70–390): Places the mouse at a random starting position, then repeatedly probes adjacent cells in up to eight directions using the display-RAM PEEK technique. A counter Q records total moves.
  4. Win condition & restart (lines 2000–2070): On reaching (20,30), prints the move count, pauses with a FOR/NEXT delay, redraws the border, and branches back to line 30 to regenerate the maze.

Display-RAM Collision Detection

The most technically interesting feature is the use of system variables at addresses 16398–16399, which together form the two-byte pointer to the current cursor position in the display file. The idiom used throughout is:

  • PRINT AT A+1,B; — moves the display cursor to a candidate cell without printing anything visible.
  • IF PEEK (PEEK G+256*PEEK H)=0 THEN LET T=1 — dereferences the cursor pointer to read the character code at that cell. A value of 0 means a space (empty), so the move is valid.

This avoids the need for any array-based map representation; the screen itself is the maze data structure. The technique exploits the ZX81/TS1000 system variable DF_CC (display file current character address), held at 16398–16399 in little-endian format, making PEEK G + 256*PEEK H the full 16-bit address.

Movement Logic

Eight candidate directions are attempted, selected partly randomly via Y=RND*7+1 and partly through a fallback chain. The direction codes and their target lines are:

Y valueDirectionLineDelta (row,col)
1 / defaultDown120(+1, 0)
2Up-right diagonal154(−1,+1)
3Down-right diagonal200(+1,+1)
4Up250(−1, 0)
5Left290(0,−1)
6Right169(0,+1)
7Up-left diagonal330(−1,−1)

If none of the tested directions is free, T remains 0 and the engine loops back to line 110 to retry with a new random direction. The previous position E,F is erased with a space at line 1000 before stamping the mouse character at the new position.

Key BASIC Idioms

  • RND scaling: RND*N+1 is used throughout for integer ranges, relying on ZX81 BASIC’s 0–0.9999… RND range truncated via multiplication without an explicit INT call — valid because PRINT AT accepts fractional row/column arguments by truncating internally.
  • Delay loop: FOR N=1 TO 3000: NEXT N at lines 2010–2020 provides a pause after the win message without using PAUSE.
  • Flicker animation: The goal marker at (20,30) is toggled between a space and %* (inverse asterisk) six times in lines 61–68 to draw attention to the target before the mouse is released.

Maze Generation Technique

The maze interior is built entirely from random PRINT AT statements placing inverse spaces (% ), block graphics (\##, \;;\!!), and short wall segments (% % ). There is no guarantee of solvability; the mouse may occasionally become fully trapped. The left and right borders are drawn per-row inside the setup loop (lines 42 and 50), while top and bottom solid borders are printed before the loop (lines 10 and 20).

Bugs and Anomalies

  • Line 106 tests IF RND>-2476, which is always true (RND is never negative). This means the random-direction branch at line 110 is never skipped, and the “straight down” default at line 120 is never taken as a direct fall-through from line 95. The conditional is effectively dead code.
  • Similarly, lines 152 (RND>-2), 165 (RND<-2), 195 (RND<-6), and 245 (RND<-1) use impossible RND values (always positive), making those fallback branches either always-taken or never-taken. The movement priorities are therefore fixed rather than truly probabilistic.
  • Line 2050 CLEAR and lines 2060–2070 are unreachable dead code following the GOTO 30 at line 2040.
  • The boundary check at line 154 tests B=30 (the goal column) rather than B=31, which could prevent rightward diagonal moves unnecessarily near the right edge.

Content

Appears On

Assembled by Tim Ward from many sources. Contains programs 10294-10335.

Related Products

Related Articles

Related Content

Image Gallery

Micro Mouse

Source Code

   1 REM **MICROMOUSE**
   5 LET G=16398
   6 LET H=G+1
  10 PRINT AT 0,0;"% % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % "
  20 PRINT AT 21,0;"% % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % "
  30 FOR A=1 TO 20
  35 PRINT AT 2+RND**18,1+RND**27;"  "
  36 PRINT AT 2+RND**18,1+RND**27;"  "
  37 PRINT AT 2+RND**18,1+RND**27;"  "
  42 PRINT AT A,0;"% "
  43 PRINT AT 3+RND**15,2+RND**22;"%  % "
  44 PRINT AT 2+RND**18,1+RND**27;"  "
  45 PRINT AT 2+RND**18,2+RND**24;"% "
  46 PRINT AT 3+RND**15,2+RND**27;"\##"
  47 PRINT AT 2+RND**15,2+RND**24;" \;;\!!"
  50 PRINT AT A,31;"% "
  57 PRINT AT 2+RND**16,2+RND**26;"  "
  60 NEXT A
  61 FOR Z=1 TO 13
  62 PRINT AT 20,30;" "
  63 PRINT AT 20,30;"%*"
  64 PRINT AT 20,30;"%*"
  65 PRINT AT 20,30;" "
  66 PRINT AT 20,30;"%*"
  67 PRINT AT 20,30;" "
  68 NEXT Z
  70 LET A=RND**6+1
  75 LET Q=0
  80 LET B=RND**15+1
  85 PRINT AT 20,30;" "
  90 LET E=A
  95 LET Q=Q+1
 100 LET F=B
 101 IF A=20 AND B=30 THEN GOTO 2000
 105 LET T=0
 106 IF RND>-2476 THEN GOTO 120
 110 LET Y=RND**7+1
 111 IF Y=1 THEN GOTO 120
 112 IF Y=6 THEN GOTO 169
 113 IF Y=3 THEN GOTO 200
 114 IF Y=4 THEN GOTO 250
 115 IF Y=5 THEN GOTO 290
 116 IF Y=2 THEN GOTO 154
 117 IF Y=7 THEN GOTO 330
 120 PRINT AT A+1,B;
 130 IF PEEK (PEEK G+256*PEEK H)=0 THEN LET T=1
 140 IF T=1 THEN LET A=A+1
 150 IF T=1 THEN GOTO 1000
 152 IF RND>-2 THEN GOTO 169
 154 IF A=0 OR B=30 THEN GOTO 169
 155 PRINT AT A-1,B+1;
 156 IF PEEK (PEEK G+256*PEEK H)=0 THEN LET T=1
 157 IF T=1 THEN LET B=B+1
 158 IF T=1 THEN LET A=A-1
 159 IF T=1 THEN GOTO 1000
 165 IF RND<-2 THEN GOTO 110
 169 PRINT AT A,B+1;
 170 IF PEEK (PEEK G+256*PEEK H)=0 THEN LET T=1
 180 IF T=1 THEN LET B=B+1
 190 IF T=1 THEN GOTO 1000
 195 IF RND<-6 THEN GOTO 290
 200 PRINT AT A+1,B+1;
 210 IF PEEK (PEEK G+256*PEEK H)=0 THEN LET T=1
 220 IF T=1 THEN LET A=A+1
 230 IF T=1 THEN LET B=B+1
 240 IF T=1 THEN GOTO 1000
 245 IF RND<-1 THEN GOTO 110
 250 PRINT AT A-1,B;
 260 IF PEEK (PEEK G+256*PEEK H)=0 THEN LET T=1
 270 IF T=1 AND A>0 THEN LET A=A-1
 280 IF T=1 THEN GOTO 1000
 290 PRINT AT A,B-1;
 300 IF PEEK (PEEK G+256*PEEK H)=0 THEN LET T=1
 310 IF T=1 AND B>0 THEN LET B=B-1
 320 IF T=1 THEN GOTO 1000
 330 IF B=0 OR A=0 THEN GOTO 110
 340 PRINT AT A-1,B-1;
 350 IF PEEK (PEEK G+256*PEEK H)=0 THEN LET T=1
 360 IF T=1 THEN LET A=A-1
 370 IF T=1 THEN LET B=B-1
 380 IF T=1 THEN GOTO 1000
 390 GOTO 110
\n1000 PRINT AT E,F;" "
\n1010 PRINT AT A,B;"%*"
\n1020 GOTO 90
\n2000 PRINT AT 0,15;"% ";Q;"% "
\n2010 FOR N=1 TO 3000
\n2020 NEXT N
\n2030 PRINT AT 0,15;"% % % % % % "
\n2040 GOTO 30
\n2050 CLEAR 
\n2060 SAVE "1032%4"
\n2070 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