snow
snow

Reputation: 1

Backtracking issues in procedurally-generated mazes

this is my first time posting here and my first attempt at programming in Lua, so I'm not incredibly advanced, but I do have experience in C# and JS. Recently I've been writing a small program in Lua 5.2 to procedurally generate mazes for a board game on Tabletop Simulator I'm working on for some friends and I. The algorithm is loosely based on the recursive backtracking algorithm but it only really uses the depth-first search style and the backtracking. The search actually seems to work fairly well, however when it attempts to backtrack the whole thing falls apart. Whenever a backtrack is initiated, it seems to always want to backtrack to the start regardless of what paths are available to take.

As of right now, I'm just trying to get it to work with the first direction it finds. However, it seems to never find somewhere to go when backtracking. The maze is 20x20 tiles and it has a 1-tile buffer around it in the tables to prevent array out-of-bounds errors when solving the maze. The following is most of the script, however some parts are removed to save on space and to simplify the program.

function backtrack(position, direction)
  local prev = position;
  local dir = direction;
  -- while no available directions from the previous tile, pop one from the history stack and check if any valid dirs
  while dir == nil do
    table.remove(history, 1);
    prev = history[1];
    -- logic for determining if a cell in the given direction is within the maze and unvisited
    -- valid[1] = north, valid[2] = east, valid[3] = south, valid[4] = west
    local valid = {
      (prev[2] < 21)and not(visited[prev[1]][prev[2] + 1]),
      (prev[1] < 21)and not(visited[prev[1] + 1][prev[2]]),
      (prev[2] > 1) and not(visited[prev[1]][prev[2] - 1]),
      (prev[1] > 1) and not(visited[prev[1] - 1][prev[2]])
    };
    for i=1, 4 do
      -- if valid dir found, stop looping and return said dir
      if valid[i] then 
        dir = i;
        return prev, dir;
      end;
    end
    if #history == 1 then return prev, dir end;
  end
end

function step(position)
  -- init the chosen dir / pass position through
  local dir = nil;
  local curr = position;
  -- function to validate which dirs to go. returns the dir to carve the maze
  dir = pickDir(curr);
  -- if no valid dirs, backtrack until an opening is found
  if dir == nil then curr, dir = backtrack(curr, dir) end;
  -- add current to history, carve the walls between the two cells in the chosen dir
  table.insert(history, 1, curr);
(... code to carve out walls ...)
  -- move and return the new position, marking new square as visited
  visited[curr[1]][curr[2]] = true;
  return curr;
end

If example screenshots or the rest of the code is needed to solve this problem, I can always update the post with that. I understand some of this could be easily optimized, but right now I'm just focusing on getting it working before I move on. Thanks!

Upvotes: 0

Views: 67

Answers (0)

Related Questions