1

I'm coding a maze solving algorithm and I'm having trouble with the backtracking once you hit a "wall"

So far I have that my code checks some basic recursive cases such as if I've reached the end or if I have checked all points. I've also made it so that there's a list that keeps track of the solution "path" and adds and removes points accordingly. So every time it adds a point, it checks if its valid and checks the point, above, to the left, to the right, and below etc. If none are valid then this statement is executed

    else:
    path.pop()
    return solve_maze(maze,path,end) 

this removes the point and backtracks and checks the following conditions at the beginning of the function.

square = list(path[-1])

#Base Case

if end in path:
    return True

elif square == None:
    return False

elif maze[square[0]][square[1]] == "X":
    path.pop()
    return solve_maze(maze,path,end)

elif tuple(square) in path:
    path.pop()
    return solve_maze(maze,path,end)

However when I execute the last line, it just removes all the points in my path and i get an indexing error.

Any advice on how I can backtrack once I hit a dead end?

4
  • If you want to escape a maze you just need to choose a wall and follow it, you do not need recursion Commented Mar 28, 2020 at 23:13
  • the way were asked to do it is with recursion; once you hit a wall you must backtrack Commented Mar 28, 2020 at 23:21
  • can you provide the entire function, an example of input/output, and where your solution is failing? It is basically very difficult to help you with the details that you gave us Commented Mar 28, 2020 at 23:25
  • The common (googlable) name for this procedure is depth-first search. Commented Mar 31, 2020 at 2:38

1 Answer 1

5

Here is a heavily commented solution:

def backtrack(i,j):
   # if matrix[i][j] is visited, then do nothing
   # if it is a wall, then do not insert it in the path from the first place
   if visit[i][j] != 0 or matrix[i][j] == 'X':
      return
   # mark the index as visited as to not visit it again
   visit[i][j] = 1
   # add the index to the path
   path.append((i,j))
   # if it is the GOAL, then store this path somewhere, 
   # and pop the last index to traverse other paths that reaches the GOAL
   if matrix[i][j] == 'G':
      # any paths that reach the GOAL are appended here
      ans.append(list(path))
      path.pop()
      return
   # loop on the neighbors. if they are valid indices, do the same work again
   for k in range(3):
      nwi = i + row[k]
      nwj = j + col[k]
      if valid(nwi, nwj):
         backtrack(nwi, nwj)
   # after finishing this index, just pop because we do not need it any more
   path.pop()
   return

def valid(i,j):
   return (i >= 0 and i <=2) and (j >= 0 and j <= 2)

# just a dummy matrix to start with
matrix = [['.', '.', '.'], ['.', 'X', '.'], ['.', 'G', 'X']]
# an array that marks indices as visited or not
visit = [[0,0,0],[0,0,0],[0,0,0]]
# the path that is used in the back tracking
path = []
# this will be a list of lists containing ALL the paths that can reach the GOAL
ans = []
# these are the neighbors indices
row = [-1, 1, 0, 0]
col = [0, 0, 1, -1]

backtrack(0,0)

if len(ans) == 0: 
   print("no path found!")
else:
   print(ans)

My solution will give you all the paths that can reach your target in a list of lists called ans. If the length of ans is zero, then no paths are found.

If you didn't understand the comments written in the code or are by any means confused, do not hesitate at all to comment down and I will reply.

NOTE:(edit)

I assumed the starting states of the maze and the function content itself because you didn't provide any test cases or your full function itself.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.