Search code examples
pythonscopeglobalrecursive-backtracking

Backtracking to find the maze exit. Why does my function always return True?


My code successfully makes its way through all the possible paths in the maze... but it always returns True, even though true only updates if certain conditions are met (having reached the edge of the maze). It seems I have misunderstanding of scope. This is my first time using the global keyword.

Here's some sample input/output. Above is the maze, the two numbers are (x, y) coordinates of current position in the maze. 'k' is the starting position, '#' is a wall.

# # ## #
# #k#  #
# # # ##
# # #  #
#     ##
########
3 2
3 3
3 4
3 5
4 5
5 5
5 4
6 4
5 3
5 2
6 2
6 1
2 5
1 5
1 4
1 3
1 2
1 1
3 1
True
found = False
def find_start(maze):
    start = None
    for i in range(len(maze)):
        print(maze[i])
        for j in range(len(maze[i])):
            if maze[i][j] == 'k':
                if start == None:
                    start = (i, j)
                else:
                    raise "There should be no multiple Kates"
    if not start:
        raise "There should be one Kate"
    return start

def has_exit(maze):
    visited = [[False for _ in range(len(maze[i]))] for i in range(len(maze))]
    y, x = find_start(maze)
    def backtrack(maze, x, y):
        visited[y][x] = True
        print(x, y)
        if x == 0 or x == (len(maze[y]) - 1) or y == 0 or y == (len(maze) - 1) or x > len(maze[y+1]) - 1 or x > len(maze[y-1]) - 1: # This last condition is the hard one.
            print('Found edge')
            global found
            found = True
            return
        if maze[y][x+1] == ' ' and not visited[y][x+1]:
            backtrack(maze, x+1, y)
        if maze[y][x-1] == ' ' and not visited[y][x-1]:
            backtrack(maze, x-1, y)
        if maze[y+1][x] == ' ' and not visited[y+1][x]:
            backtrack(maze, x, y+1)
        if maze[y-1][x] == ' ' and not visited[y-1][x]:
            backtrack(maze, x, y-1)
        
    backtrack(maze, x, y)
    if found:
        print(found)
        return True
    else:
        print(found)
        return False

Solution

  • The only place found is assigned a value is the first time through the code =False Then whenever the code hits backtrack it assigns it True. Importantly for your question, you never reset found, so as soon as set to True one time, it will never reset. Since you are recursing over all possible paths, you will hit an edge eventually, so found=True eventually for any run.

    I agree with the other suggestions about using return values from functions, but here you just need to reset your state appropriately for the recursive search.