Maze

A 10-line TurboBASIC XL program for the Atari 8-bit computer
Written for 2014 NOMAM programming competition

Bill Kendrick, March 22, 2014

An entry for the NOMAM 2014 10-line TurboBASIC XL game competition.


Objective

You begin in the center of a randomly-generated maze, and must navigate to the top left corner as quickly as possible.

Gameplay

Befor the game starts, you'll be asked whether or not your trail through the maze should be exposed. Press [Y] for yes, or [N] for no. The screen will go blank for a few moments while the maze is generated.

When the game begins, you'll see the walls (brick) and floor (checkerboard) around your current location. Use the joystick to move around the maze.

Once you reach the top left corner, the full maze is displayed, and some sound effects and flashing colors are shown. Then, the time it took you to complete the maze (in HHMMSS format) will appear for a few moments, and the game will restart.


Development notes

My objective was to make a game similar to "Hidden Maze" that was published in Compute!'s First Book of Atari Games, which I had as a kid. It uses the depth-first method of carving a maze, which I brushed-up on by reading a Wikipedia article on the subject. I did not refer to "Hidden Maze" when writing this game.

Based on what I learned from Wikipedia, and from what I remembered from "Hidden Maze", I knew you could simulate the recursive nature of a depth-first algorithm by utilizing the map itself as a kind of stack. That is, you leave a 'breadcrumb' trail as you carve through the maze, pointing in the direction you came from. When you hit a dead-end, you simply backtrack until you find a spot where you have another option, or you've returned to your starting point (at which point, you're done).

I utilized the Atari's color indirection (color palette) to 'hide' the maze by setting its color to black, just like the background. I then took advantage of TurboBASIC XL's built-in bitwise "and" (&) and "or" (!) operators to alter the characters (tiles) that make up the maze to change their colors. (In large-text mode (GRAPHICS 1 and GRAPHICS 2), 64 symbols can be shown, in one of four colors, depending on the two highest bits of the byte.)

Hiding the wall in your old location, and exposing the wall in your new location, caused too much flicker. So I tried a few other ways of doing it until I settled on:

  1. expose the walls directly around your location ((x-1,y-1) to (x+1,y+1))
  2. hide the walls beyond that ((x-2,y-2) to (x+2,y-2), (x-2,y+2) to (x+2,y+2), and so on)
Attempts to use the modulus operator (MOD) or bitwise "and" proved too slow, and/or didn't work like I intended (because I was tired).

Finally, I squeezed the game by creating at first two small subroutines, then combining them into one, for hiding walls... utilizing variables for some two-digit values (_ for -1, and T for 20)... and so on. Then, after squeezing the code down some more, I added a game over routine, and utilized TurboBASIC XL's TIME$ to show you your 'score' — how long it took to solve the maze (the smaller, the better).

Line-by-line Breakdown of the Source Code

Setup

10 GRAPHICS 17:SC=DPEEK(88):FOR X=21 TO 37:POKE SC+X,3:NEXT X:FOR Y=2 TO 17:MOVE SC+20,SC+Y*20,20:NEXT Y:ZZ=SC+42:Z=ZZ:OPEN #1,4,0,"K:" 20 _=-1:T=20:DIM D(4):D(0)=_:D(1)=-T:D(2)=1:D(3)=T:RR=_:? #6;"MAZE! expose yn":REPEAT :GET #1,N:UNTIL N=78 OR N=89:POKE 708,0 25 POKE Z,0:G=1000:IF N=89:GG=128:ENDIF :POKE 559,0:CH=(PEEK(106)-16)*256:POKE 756,CH/256

Maze generator

30 REPEAT :A=0:OD=-1:FOR I=0 TO 3:A=A+(PEEK(Z+D(I)*2)=3):NEXT I:IF A=0 THEN RR=PEEK(Z)-128:POKE Z,0:POKE Z-D(RR),0:Z=Z-D(RR)*2 35 UNTIL A<>0+(Z=ZZ):IF Z<>ZZ OR RR=-1 THEN REPEAT :R=RAND(4):UNTIL PEEK(Z+D(R)*2)=3 AND R<>OD:FOR I=0 TO 1:Z=Z+D(R):POKE Z,128+R:NEXT I:GOTO 30

More set-up

40 Z=SC+210:MOVE ADR("........"),CH,8:MOVE ADR("........"),CH+24,8:POKE 710,8:POKE 559,34:TIME$= "000000"

Main Game Loop

50 FOR Y=_ TO 1:FOR X=_ TO 1:NZ=Z+Y*T+X:POKE NZ,PEEK(NZ)!64:NEXT X:NZ=Z-2+Y*T:GOSUB G:NZ=NZ+4:GOSUB G:NEXT Y:FOR X=-2 TO 2:NZ=Z-40+X:GOSUB G 60 NZ=NZ+80:GOSUB G:NEXT X:REPEAT :S=STICK(0):UNTIL S<15:NZ=Z+D((S=14)+(S=7)*2+(S=13)*3):IF PEEK(NZ)&63=0:Z=NZ:ENDIF :GOTO 50+1000*(Z=ZZ)

Subroutines

1000 POKE NZ,(PEEK(NZ)&191)!GG:RETURN 1050 FOR A=0 TO 15:FOR B=0 TO 15:SOUND 0,100+A*10,10,B:POKE 708,A*16+B:POKE 712,15-B:NEXT B:NEXT A:GRAPHICS 18:? #6;TIME$:PAUSE 120:RUN

Download


Bill Kendrick, 2014, nbs@sonic.net, New Breed Software
Other games I wrote for NOMAM 2014