Implementing a Recursive Backtracker in JavaScript?

Somya Agrawal :

I have a 2-D array filled with objects. I want to convert this array into a maze where some objects are walls (they have a isWall property that should be marked true) and some objects are passageways (isWall will be false).

I'm trying to use Recursive Backtracking (I'm using a stack as opposed to recursion) for this, but my Maze is showing up like this Picture of incorrect Maze

The black squares represent walls whereas the white squares represent passageways. The numbers inside the white squares are irrelevant (just weights I use for Djikstra).

Here is my implementation of Recursive Backtracking in JavaScript.

JavaScript
function isValid(r, c, grid) {
  if (r < 0 || c < 0) {
    return false;
  }
  if (r < grid.length && c < grid[r].length) {
    return true;
  }
  return false;
}

export default function recursiveBacktracker(grid, startNode, endNode) {

  // Fill Grid with walls
  for (let r = 0; r < grid.length; r++) {
    for (let c = 0; c < grid[r].length; c++) {
      grid[r][c].isWall = true;
    }
  }

  let visited = new Set();
  let stack = [startNode];
  let neighbors = [
    [2, 0],
    [-2, 0],
    [0, 2],
    [0, -2]
  ];
  while (stack.length > 0) {
    let cur = stack.pop();
    let r = cur[0],
      c = cur[1];
    console.log(r, c);
    visited.add(r + "." + c);
    grid[r][c].isWall = false;
    for (let n of neighbors) {
      let rr = r + n[0];
      let cc = c + n[1];
      if (isValid(rr, cc, grid) && !visited.has(rr + "." + cc)) {
        grid[r + n[0] / 2][c + n[0] / 2].isWall = false;
        stack.push([rr, cc]);
        break;
      }
    }
  }
  return grid;
}

I'd really appreciate some guidance on where my code is going wrong. Thank you!

Kenta Nomoto :

I believe the bug is likely because of your line

grid[r + n[0] / 2][c + n[0] / 2].isWall = false;

I think there is a typo, and what you would want is

grid[r + n[0] / 2][c + n[1] / 2].isWall = false; //simply change n[0] to n[1]

Now there is another logic error here on the if condition:

for (let n of neighbors) {
  let rr = r + n[0];
  let cc = c + n[1];
  if (isValid(rr, cc, grid) && !visited.has(rr + "." + cc)) {
    grid[r + n[0] / 2][c + n[0] / 2].isWall = false;
    stack.push([rr, cc]);
    break;
  }
}

The recursive backtracker algorithm requires to choose a random available neighbour, where what you did was to simply choose the first available neighbour you found. As you can see, the if condition checks if the cell is available, then immidiately performs an action if the cell was available.

I tried running the code and it simply became a strip of vertical lines. So try storing your available coordinates in a list, and pick a random coordinate from that new list. That seemed to fixed the error :)

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=174444&siteId=1