I think there are three changes:
1. two more variables to detect dead ends (two new lines)
old:
Your phone or window isn't wide enough to display the code box. If it's a phone, try rotating it to landscape mode.
- Code: Select all
local pos = {x = 0, y = 0, l = 0}
table.insert(moves, {x = pos_x, y = pos_y, l = pos_l})
new:
Your phone or window isn't wide enough to display the code box. If it's a phone, try rotating it to landscape mode.
- Code: Select all
local pos = {x = 0, y = 0, l = 0}
local forward = true
local dead_end = {}
table.insert(moves, {x = pos_x, y = pos_y, l = pos_l})
2. set generation direction "forward" (one new line)
old:
Your phone or window isn't wide enough to display the code box. If it's a phone, try rotating it to landscape mode.
- Code: Select all
if #possible_ways > 0 then
direction = possible_ways[math.random(# possible_ways)]
new:
Your phone or window isn't wide enough to display the code box. If it's a phone, try rotating it to landscape mode.
- Code: Select all
if #possible_ways > 0 then
forward = true
direction = possible_ways[math.random(# possible_ways)]
3. dectect dead ends and remove them if possible with 20% chance (math.random(5) == 1 -- 100% would be too easy again)
old:
Your phone or window isn't wide enough to display the code box. If it's a phone, try rotating it to landscape mode.
- Code: Select all
else
pos = table.remove(moves)
pos_x = pos.x
pos_y = pos.y
pos_l = pos.l
end
until pos_x == start_x and pos_y == start_y
-- create exit on opposite end of maze and make sure it is reachable
new:
Your phone or window isn't wide enough to display the code box. If it's a phone, try rotating it to landscape mode.
- Code: Select all
else -- there is no possible way forward
if forward then -- the last step was forward, now back, so we're in a dead end
-- mark dead end for possible braid
if not maze[pos_l][pos_x - 1][pos_y] then -- dead end to E, only way is W
table.insert(dead_end, {x = pos_x, y = pos_y, l = pos_l, dx = 1, dy = 0})
elseif not maze[pos_l][pos_x + 1][pos_y] then -- dead end to W, only way is E
table.insert(dead_end, {x = pos_x, y = pos_y, l = pos_l, dx = -1, dy = 0})
elseif not maze[pos_l][pos_x][pos_y - 1] then -- dead end to S, only way is N
table.insert(dead_end, {x = pos_x, y = pos_y, l = pos_l, dx = 0, dy = 1})
elseif not maze[pos_l][pos_x][pos_y + 1] then -- dead end to N, only way is S
table.insert(dead_end, {x = pos_x, y = pos_y, l = pos_l, dx = 0, dy = -1})
end
forward = false
end
pos = table.remove(moves)
pos_x = pos.x
pos_y = pos.y
pos_l = pos.l
end
until pos_x == start_x and pos_y == start_y
-- create partial braid maze, about 20%
for _, braid_pos in pairs(dead_end) do
-- print(braid_pos.x.."/"..braid_pos.y.."/"..braid_pos.l.." "..braid_pos.dx.."/"..braid_pos.dy)
x = braid_pos.x + braid_pos.dx * 2
y = braid_pos.y + braid_pos.dy * 2
if math.random(5) == 1 and x > 0 and x < maze_size_x - 1 and y > 0 and y < maze_size_y - 1 and not maze[braid_pos.l][x][y] then
-- remove wall if behind is corridor with 20% chance
maze[braid_pos.l][braid_pos.x + braid_pos.dx][braid_pos.y + braid_pos.dy] = false
-- print("removed "..braid_pos.l.."/"..braid_pos.x + braid_pos.dx.."/"..braid_pos.y + braid_pos.dy)
end
end
-- create exit on opposite end of maze and make sure it is reachable
Maybe it would be better to make it braid only for medium and large mazes. For small mazes it could open too many ways to the exit instead of confusing the player.