'**
'** MAZEGEN by Terry Ritchie
'**
'** Creates random 20x16 braided mazes (or perfect mazes with modification)
'**
'** This code was created from pseudo-code obtained at MAZEWORKS.COM
'**
'** This code could be easily modified to create any size maze and cell size
'**
'** If you use this code in your program please credit me and MAZEWORKS.COM
'**
'** Code last modified 02/23/09
'**
'** This maze generating code was created to use in a MEGABUG (Tandy/Radio
'** Shack game from 1982) clone to teach introductory programming. The
'** original game used a 20x16 maze grid. This is why the maze generator has
'** been hard coded to only use a 16x20 grid. A little modification would
'** allow this code to generate any size maze with any size cell.
'**
LINE (81, 37)-(239, 163), 0, BF
'faster than CLS CreateRandomMaze
DrawMaze
SLEEP 1 '**rem this line out to see how fast it is!
'**
'** Creates a random 20x16 braided (looping) maze by first creating a perfect
'** maze (a maze with no loops) then visiting each dead end and randomly
'** opening them to create loops.
'**
'** vcells stores valid next maze cell moves in binary (bit) format
'** if all adjacent cell walls are turned on then that cell is saved in vcells
'** as follows:
'** bit 1 (2^0) = north cell has all walls on
'** bit 2 (2^1) = east cell has all walls on
'** bit 3 (2^2) = south cell has all walls on
'** bit 4 (2^3) = west cell has all walls on
'**
DIM stack
(totalcells
) AS stack
'** maze generation LIFO stack DIM cell
AS stack
'** current cell being created FOR cellx
= 0 TO 19 '** initialize maze grid maze(cellx, celly).walls = 15 '** turn all walls on
maze(cellx, celly).x = 80 + cellx * 8 '** x coordinate upper left cell
maze(cellx, celly).y = 36 + celly * 8 '** y coordinate upper left cell
cell.x
= INT(RND(1) * 19) '** random x location cell.y
= INT(RND(1) * 15) '** random y location visitedcells = 1 '** initialize counter
pointer = 0 '** initialize LIFO stack pointer
forward = false '** initialize movement indicator
WHILE visitedcells
< totalcells
'** continue until all cells made vcells = 0 '** initialize valid move check
IF cell.y
<> 0 THEN IF maze
(cell.x
, cell.y
- 1).walls
= 15 THEN vcells
= vcells
+ 1 IF cell.x
<> 19 THEN IF maze
(cell.x
+ 1, cell.y
).walls
= 15 THEN vcells
= vcells
+ 2 IF cell.y
<> 15 THEN IF maze
(cell.x
, cell.y
+ 1).walls
= 15 THEN vcells
= vcells
+ 4 IF cell.x
<> 0 THEN IF maze
(cell.x
- 1, cell.y
).walls
= 15 THEN vcells
= vcells
+ 8 IF vcells
<> 0 THEN '** at least 1 cell has all walls DO '** find a random move direction randomwall
= INT(RND(1) * 4) '** 0=North 1=East 2=South 3=West LOOP UNTIL vcells
AND 2 ^ randomwall
'** is random direction valid? stack(pointer).x = cell.x '** save current cell position in
stack(pointer).y = cell.y '** the stack
pointer = pointer + 1 '** increment stack pointer
visitedcells = visitedcells + 1 '** increment cell counter
forward = true '** forward movement indicated
CALL RemoveWall
(cell.x
, cell.y
, randomwall
) '** remove random wall SELECT CASE randomwall
'** which direction forward? cell.y = cell.y - 1 '** move north
cell.x = cell.x + 1 '** move east
cell.y = cell.y + 1 '** move south
cell.x = cell.x - 1 '** move west
ELSE '** no cells have all walls
'****** remark the lines below to create perfect mazes (no loops) ***********
'****** the code below creates braided mazes (contains loops) ***********
IF forward
THEN '** we hit a dead end! forward = false '** forward movement stops here
CASE 0 '** remove north wall IF cell.y
<> 0 THEN '** unless it's a border CALL RemoveWall
(cell.x
, cell.y
, randomwall
) CASE 1 '** remove east wall IF cell.x
<> 19 THEN '** unless it's a border CALL RemoveWall
(cell.x
, cell.y
, randomwall
) CASE 2 '** remove south wall IF cell.y
<> 15 THEN '** unless it's a border CALL RemoveWall
(cell.x
, cell.y
, randomwall
) CASE 3 '** remove west wall IF cell.x
<> 0 THEN '** unless it's a border CALL RemoveWall
(cell.x
, cell.y
, randomwall
)
'****** remark the lines above to create perfect mazes (no loops) ***********
'****** the code above creates braided mazes (contains loops) ***********
pointer = pointer - 1 '** decrement stack pointer
cell.x = stack(pointer).x '** go back to previous cell
cell.y = stack(pointer).y '** go back to previous cell
WEND '** exit when all cells visited
'****************************************************************************
'** draw cell to graphics screen *
'****************************************************************************
IF maze
(cellx
, celly
).walls
AND 1 THEN LINE (maze
(cellx
, celly
).x
, maze
(cellx
, celly
).y
)-(maze
(cellx
, celly
).x
+ 8, maze
(cellx
, celly
).y
), 1 IF maze
(cellx
, celly
).walls
AND 2 THEN LINE (maze
(cellx
, celly
).x
+ 8, maze
(cellx
, celly
).y
)-(maze
(cellx
, celly
).x
+ 8, maze
(cellx
, celly
).y
+ 8), 1 IF maze
(cellx
, celly
).walls
AND 4 THEN LINE (maze
(cellx
, celly
).x
, maze
(cellx
, celly
).y
+ 8)-(maze
(cellx
, celly
).x
+ 8, maze
(cellx
, celly
).y
+ 8), 1 IF maze
(cellx
, celly
).walls
AND 8 THEN LINE (maze
(cellx
, celly
).x
, maze
(cellx
, celly
).y
)-(maze
(cellx
, celly
).x
, maze
(cellx
, celly
).y
+ 8), 1
'****************************************************************************
'* Draws the entire maze to the graphics screen *
'****************************************************************************
FOR x
= 0 TO 19 '** cycle through all cells CALL DrawCell
(x
, y
) '** draw each cell to the screen LINE (79, 35)-(241, 165), 1, B
'** draw border around maze
'****************************************************************************
'* Removes the walls between to adjoining cells based on the direction of
'* movement. *
'****************************************************************************
CASE 0 '** remove north/south walls maze(cellx, celly).walls = maze(cellx, celly).walls - 1
maze(cellx, celly - 1).walls = maze(cellx, celly - 1).walls - 4
CASE 1 '** remove east/west walls maze(cellx, celly).walls = maze(cellx, celly).walls - 2
maze(cellx + 1, celly).walls = maze(cellx + 1, celly).walls - 8
CASE 2 '** remove south/north walls maze(cellx, celly).walls = maze(cellx, celly).walls - 4
maze(cellx, celly + 1).walls = maze(cellx, celly + 1).walls - 1
CASE 3 '** remove west/east walls maze(cellx, celly).walls = maze(cellx, celly).walls - 8
maze(cellx - 1, celly).walls = maze(cellx - 1, celly).walls - 2