Search code examples
javascriptrecursionmaze

Recursive function (maze solver) - can't find a bug;(((


I am studying javascript and all is pretty easy to me except for some things like recursive functions. I do understand the way they work but while working with an example, I realized I can't capture the bug that prevents it from functioning...

I have an array (map) below (0 is a closed cell, 1 means path is open) and the recursive function I am trying to use to "find" path out of this "maze" by going from its top left cell to the bottom-right one.. Basically just make the function to "find" this path of 1s. But it fails;(

var map = [
        [1,1,0,0],
        [0,1,1,0],
        [0,0,1,0],
        [0,0,1,1]
    ]

function findpath(x,y) {
    if (x<0 || x>3 || y<0 || y>3) return false; //if it is outside of map
    if (x==3 && y==3) return true; // if it is the goal (exit point)
    if (map[y][x]==0) return false; //it is not open
    map[y][x]=9; //here marking x,y position as part of solution path outlined by "9"
    if (findpath(x,y-1) == true) return true;
    if (findpath(x+1,y) == true) return true;
    if (findpath(x,y+1) == true) return true;
    if (findpath(x-1,y) == true) return true;
    map[y][x]=8; //unmark x,y as part of solution path outlined by "8"
    return false;
    };
findpath(0,0);

Solution

  • Quick answer:

    Its locking in a loop because the order of the checks.

    Start from 0:0 then try 0:1. Then from 0:1 --"Ummm... 0:0 looks promising. Let's go there". So go back to 0:0... so it locks... Try leaving backtracking last :

    if(findpath(x+1,y)) return true;    
    if(findpath(x,y+1)) return true;    
    if(findpath(x,y-1)) return true;
    if(findpath(x-1,y)) return true;
    

    This get you out of the lock just by swapping the issue around. If you start from 3:3 trying to reach 0:0 you'll be locked again. Whats missing its a way to mark visited squares.

    I think you are trying to implement an a* algorithm

    UPDATE:

    Here is your idea working. Just added the backtracking checks you almost implemented.

    <html>
        <head>
        </head>
        <body>
            <script>
                var map = [
                [1,1,0,0],
                [0,1,1,0],
                [1,1,1,0],
                [1,0,1,1]
            ]
            
        var goalx = 0;
        var goaly = 3;
        
        console.log();
        
        function findpath(x,y) {
            
            
            // illegal move check
            if (x < 0 || x > (map[0].length -1) || y < 0 || y > (map.length - 1)) return false; //if it is outside of map
            if (map[y][x]==0) return false; //it is not open
            
            // end move check
            if (x== goalx && y== goaly){
                console.log('Reached goal at: ' + x + ':' + y);
                return true; // if it is the goal (exit point)
            }
            
            if(map[y][x] == 9 || map[y][x] == 8)
                return false;
            
            console.log('Im here at: ' + x + ':' + y);
            
            map[y][x]=9; //here marking x,y position as part of solution path outlined by "9"
            
            if(findpath(x+1,y)) 
                return true;    
            if(findpath(x,y+1)) 
                return true;    
            if(findpath(x,y-1))
                return true;
            if(findpath(x-1,y)) 
                return true;                    
            
            map[y][x]=8; //unmark x,y as part of solution path outlined by "8"
            
            return false;
        };
        
        findpath(3, 3);
            </script>
        </body>
    </html>