PICO-8: Maze Algorithm Tutorial
Keys
Z - move to the next step
X - switch on/off auto or reset the maze.
Code
Below is a heavily-commented implementation of the actual algorithm used in the tutorial above. It's called the Growing Tree Maze Algorithm if you'd like to learn more about it.
Note: If you'd like to implement this code, you need to draw a wall in sprite #001 and a floor in sprite #002.
function _init()
w,h=13,13 --must be odd numbers!
gen() --make a maze!
end
function _update()
if (btnp(5)) gen() --reset
end
function _draw()
cls()
--center the maze and draw it
center_x=(128-(w+2)*8)/2
map(0,0,center_x,0)
print("press \151 to reset",30,122,5)
end
function gen()
m={} --empty maze of all walls
for i=1,w do --go across
m[i]={}
for j=1,h do --go down
m[i][j]=true --true=wall
end
end
c={} --cells we're tracking
--start in a random spot
add_c(rndbi(0,(w-1)/2)*2+1,rndbi(1,(h-1)/2)*2+1)
m[c[1].x][c[1].y]=false
carve()
set_map_tiles()
end
function carve()
--easy math to calculate
--neighboring cells and
--cells opposite the one
--we're working with
dx,dy,op={-2,2,0,0},{0,0,-2,2},{2,-2,2,-2}
--if the cell list isn't empty
while (#c>0) do
cc=c[#c] --get the last cell
--get a random list of dirs
rd=get_rnd_dirs()
--check each direction
for d in all(rd) do
--get the cell in that dir
nx,ny=cc.x+dx[d],cc.y+dy[d]
--if that cell is uncarved
--and not an edge wall
if (nx>=1 and nx<=w and ny>=1 and ny<=h and m[nx][ny]) then
--carve a path in that dir
m[cc.x+(dx[d]/2)][cc.y+(dy[d]/2)]=false
m[nx][ny]=false
--new cell goes on the list
add_c(nx,ny)
--if we found and carved a
--new path, we're good. no
--need to check other dirs
break
end
--if we checked that dir
--and couldn't use that dir,
--take the dir off the list
--and check the next dir
del(rd,d)
end
--if we checked all dirs and
--couldn't find an open path
--to carve, we're done with
--that cell
if (#rd<1) then
del(c,cc)
end
end
end
--add a cell to the list of
--cells we're working with
function add_c(x,y)
local new_c={}
new_c.x=x
new_c.y=y
add(c,new_c)
end
--get a random \139\145\148\131 list
function get_rnd_dirs()
local dirs={1,2,3,4}
local rnd_dirs={}
for i=1,4 do
local rnd_dir=rndbi(1,#dirs)
add(rnd_dirs,dirs[rnd_dir])
del(dirs,dirs[rnd_dir])
end
return rnd_dirs
end
function set_map_tiles()
--maze border
for i=0,w+1 do --top/bottom
mset(i,0,1)
mset(i,h+1,1)
end
for j=1,h do --left/right
mset(0,j,1)
mset(w+1,j,1)
end
--maze tiles
for i=1,w do for j=1,h do
if (m[i][j]) then
mset(i,j,1)
else
mset(i,j,2)
end
--simpler version using a
--ternary operator:
--mset(i,j,m[i][j] and 1 or 2)
end end
end
--random integer (h inclusive)
function rndbi(l,h)
return flr(rnd(h+1-l))+l
end| Status | Released |
| Category | Other |
| Platforms | HTML5 |
| Rating | Rated 5.0 out of 5 stars (4 total ratings) |
| Author | MBoffin (Dylan Bennett) |
| Genre | Educational |
| Made with | PICO-8 |
| Tags | PICO-8 |

Comments
Log in with itch.io to leave a comment.
Very cool algorithm, I really like the implementation here. Nice work!
I kept wondering where you decided what piece to choose(a straight, crossing, etc), i even coded it myself to figure it out. And then, when i looked at it again, it hit me. You don't! They just exist because they are not walls! I kept trying to guess which piece goes where :D
Just what I was looking for. Thanks a lot :)
This documented code is not appreciated enough. Massive thanks.