Here's a simple maze generating program.
Algorithm:
Set a current cell
Set the count of cells visited to 1
while not all the cells have been visited,
if all adjacent cells have been visited
backtrack
else
pick a random adjacent cell
delete the wall between the two cells
make the next cell the current cell
increase the Visited counter
endif
endwhile
Hope it helps someone. I used it to generate a random maze for a map for Wesnoth. The players start in the corners and have to find each other to kill them. It should be quite fun. The attached pic is the actual level.
REM Project: maze2
REM Created: 9/30/2008 10:20:33 PM
REM
REM ***** Main Source File *****
REm
global C `Declare C for the number of Cells
Global D `Declare D for the on deimension of the sprite grid
`I guess these don't have to be Globals, I just was going to use functions
C = 10 `How many cells
D = 3*c+1 `Convert to D
`Make an image for the sprites
cls
box 0,0,10,10,RGB(255,0,0),RGB(0,255,0),RGB(0,0,255),RGB(0,255,255)
get image 1,0,0,10,10
`This type is for backtracking, just a simple point
type pt
x
y
endtype
dim Back(C^2) as pt `the array for backtracking
for x = 1 to D
for y = 1 to D
Sprite (x-1)*d + y,x*10,y*10,1 `Draw a DxD grid of image 1
next y
next x
x = (c/2 - 1) * 3 + 2 `Set initial point to mid of grid - this was because I wanted players to start in
y = x `the four corners and try and find eachother to attack. You'd probably wnat to use a corner
hide sprite (x-1)*d + y `Empty the first 2x2 cell (the point is the top left of the cell)
hide sprite (x)*d + y `The program can tell what cells have been visited
hide sprite (x-1)*d + y +1 `based on whether or not the sprites in that cell are visible
hide sprite (x)*d + y +1
V = 1 `We have visited one cell, this counter will tell us when to stop the program
Back(V).x = x `set the backtrack point to the current point.
Back(V).y = y
B=0 `Don't backtrack yet
while V < C^2 `Repeat the algorithm until all cells have been visited. (There are C^2 cells)
Temp = rnd(3)*90 `Choose a random direction to go
for i = 1 to 4
Dx = 3*cos(temp) `set dx and dy to that direction
Dy = 3*sin(temp) `(3 is used because the next cell is 3 sprites away)(
if x+dx > 1 and y+dy > 1 and x+dx < D and y+dy < D `make sure that that direction is in the map
if sprite visible((x+dx-1)*d + y+dy) = 0 then temp = temp + 90 `already gone that way, so go somewhere else
else
temp = temp + 90 `can't go off the map, so go somewhere else
endif
next
remstart
now dx and dy will take us to an unvisited sprite if it can
however, if all the adjacent cells have been visited, then
the next sprite could be off the edge or already visited.
you must check this to see if you have to backtrack.
remend
if x+dx > 1 and y+dy > 1 and x+dx < D and y+dy < D `Is it in the grid?
if sprite visible((x+dx-1)*d + y+dy) = 0 `Has it been visited?
Gosub _BackTrack `YES! That means all adjacent cells have been visited, so backtrack
else
`You can now move to a new cell
`First, delete the wall between the current cell and the next cell
if dx > 0
hide sprite (x+1)*d + y
hide sprite (x+1)*d + y+1
endif
if dx < 0
hide sprite (x-2)*d + y
hide sprite (x-2)*d + y+1
endif
if dy > 0
hide sprite (x-1)*d + y+2
hide sprite (x)*d + y+2
endif
if dy < 0
hide sprite (x-1)*d + y-1
hide sprite (x)*d + y-1
endif
`Move to the next cell
x = x + dx
y = y + dy
`Empty the next cell
hide sprite (x-1)*d + y
hide sprite (x)*d + y
hide sprite (x-1)*d + y +1
hide sprite (x)*d + y +1
`Increase the counter of cells visited
V = V + 1
`Add the new cell into the backtrack array
Back(V).x = x
Back(V).y = y
`reset the backtrack count because you obviously don't need to backtrack more
B=0
endif
else
`Opps! The new cell is off the grid, so all adjacent cells have been visited, so backtrack
GoSub _BackTrack
endif
sprite 1001, 10*x+5,10*y+5,1 `Not needed, just graphically shows the current cell
sync `again, lets you see what's going on; would not be in a real application
endwhile
`Maze is completely generated!
wait key
end
`the backtrack sub routine
_BackTrack:
b=b+1 `back track one more cell from the current cell, essentially moves
`backwards through the backtrack array.
x = back(V-b).x `Set the current point to the previously visited cell.
y = back(V-b).y
return
http://forum.thegamecreators.com/xt/xt_apollo_pic.php?i=1234759