Search code examples
javascriptalgorithmrecursionasync-awaitbacktracking

How to fix problem in visualizing the algorithm


I wanted to implement a question where we find paths in a maze from (0,0) cell to (m-1,n-1) cell with having some obstacles in between.
I have used recursive backtracking algorithm to solve the problem and I just wanted to make some kind of visualization where we can see how the path is been taken as we are travelling in the maze.
I saw that question here

Now I have implemented it using javascript and I am coloring the cells blue which we are visiting and then again removing the color if we backtrack but everything happens very fast as we can't see anything happening, so I tried using sleep() function to have some delay but I don't think I have used them properly as any random pattern is showing not the proper path it is taking.

If anyone could help me in resolving it then it will be a great help.
You can check my problem here

My algorithm for finding path is :

let getMazePath = async (maze, r, c, ans) => {
  if (
    r < 0 ||
    c < 0 ||
    r >= maze.length ||
    c >= maze[0].length ||
    maze[r][c] == 1 ||
    visited[r][c] == 1
  )
    return;

  if (r == maze.length - 1 && c == maze[0].length - 1) {
    document.getElementById("path-display").innerHTML =
      "Path is: '" + ans + "'";
    console.log("Path is: '" + ans + "'");
    return;
  }

  let currSq = document.getElementById(r + "_" + c);
  currSq.classList.add("visited-square");
  await sleep(1000);
  visited[r][c] = 1;

  getMazePath(maze, r - 1, c, ans + "t");
  getMazePath(maze, r, c - 1, ans + "l");
  getMazePath(maze, r + 1, c, ans + "d");
  getMazePath(maze, r, c + 1, ans + "r");

  visited[r][c] = 0;
  currSq.classList.remove("visited-square");
  await sleep(1000);
};

function sleep(ms){
  return new Promise((resolve) => {
    setTimeout(resolve, ms);
  })
}

Solution

  • You've forgotten to await the recursive calls.

    Fix it by prefixing getMazePath calls by await:

    await getMazePath(maze, r - 1, c, ans + "t");
    await getMazePath(maze, r, c - 1, ans + "l");
    await getMazePath(maze, r + 1, c, ans + "d");
    await getMazePath(maze, r, c + 1, ans + "r");
    

    See it live on CodePen


    You might also want to stop it, when it finds a path.

    To do that, return the answer, and check for it:

    let getMazePath = async (maze, r, c, ans) => {
      if (
        r < 0 ||
        c < 0 ||
        r >= maze.length ||
        c >= maze[0].length ||
        maze[r][c] == 1 ||
        visited[r][c] == 1
      )
        return; 
    
      if (r == maze.length - 1 && c == maze[0].length - 1) {
        document.getElementById("path-display").innerHTML =
          "Path is: '" + ans + "'";
        console.log("Path is: '" + ans + "'");
        return ans;
            // ^^^
      }
    
      let currSq = document.getElementById(r + "_" + c);
      currSq.classList.add("visited-square");
      await sleep(1000);
      visited[r][c] = 1;
    
      {
        const res = await getMazePath(maze, r - 1, c, ans + "t");
        if(res) return res
      }
      {
        const res = await getMazePath(maze, r, c - 1, ans + "l");
        if(res) return res
      }
      {
        const res = await getMazePath(maze, r + 1, c, ans + "d");
        if(res) return res
      }
      {
        const res = await getMazePath(maze, r, c + 1, ans + "r");
        if(res) return res
      }
      visited[r][c] = 0;
      currSq.classList.remove("visited-square");
      await sleep(1000);
    };
    

    See it live on CodePen