I am building a Lua script that generates a maze using a version of the Recursive Backtracker implemented with a stack rather than recursion. Presently the maze is coming out braided and I can't seem to figure out where in my logic this is happening. The function below takes in x and y as a starting point for generating the maze which is a 2d structure (table of tables):
local function buildMazeInternal(x,y,maze)
local stack = {}
local directions = {'North','East','South','West'}
table.insert(stack,{x=x,y=y})
while #stack > 0 do
local index = 1
local nextX = x
local nextY = y
local braid = false
for i = #directions, 2, -1 do -- backwards
local r = calc:Roll(1,i) -- select a random number between 1 and i
directions[i], directions[r] = directions[r], directions[i] -- swap the randomly selected item to position i
end
while index <= #directions and nextX == x and nextY == y do
if directions[index] == 'North' and y > 1 and not maze[y-1][x].Visited then
maze[y][x].North = true
maze[y-1][x].South = true
nextY = y-1
elseif directions[index] == 'East' and x < width and not maze[y][x+1].Visited then
maze[y][x].East = true
maze[y][x+1].West = true
nextX = x+1
elseif directions[index] == 'South' and y < height and not maze[y+1][x].Visited then
maze[y][x].South = true
maze[y+1][x].North = true
nextY = y+1
elseif directions[index] == 'West' and x > 1 and not maze[y][x-1].Visited then
maze[y][x].West = true
maze[y][x-1].East = true
nextX = x-1
else
index = index + 1
end
end
if nextX ~= x or nextY ~= y then
x = nextX
y = nextY
maze[y][x].Visited = true
table.insert(stack,{x=x,y=y})
else
x = stack[#stack].x
y = stack[#stack].y
table.remove(stack)
end
end
end
I know I'm overlooking something but I can't seem to nail it down. Note that the calc:Roll(1,100)
method is a .net method in my app used to simulate rolling dice, in this case 1 * 100 sided die, it could be replaced with a call to math.Random(1,100)
for use outside of my application.
I found the answer after posting on Reddit. I wasn't setting the initial cell to visited allowing it to be passed through twice. The correction was to add maze[y][x].Visited = true
immediately before table.insert(stack,{x=x,y=y})
.