问题
I have a program that searches through a 2D list that represents a maze like so:
####################################
#S# ## ######## # # # # #
# # # # # # #
# # ##### ## ###### # ####### # #
### # ## ## # # # #### #
# # # ####### # ### #E#
####################################
I understand what a recursion error is but I don't know why this code causes it as it should simply lead to finding the "E". Does anyone know how this possibly generates the error?
def solve(x,y):
mazeList = loadMaze("sample.maze")
if mazeList[y][x] == "E":
return "YOU'VE SOLVED THE MAZE!"
elif mazeList[y][x+1] == " ": #right
mazeList[y][x+1] = ">"
solve(x+1,y)
elif mazeList[y+1][x] == " ": #down
mazeList[y+1][x] = "v"
solve(x,y+1)
elif mazeList[y][x-1] == " ": #left
mazeList[y][x-1] = "<"
solve(x-1,y)
elif mazeList[y-1][x] == " ": #up
mazeList[y-1][x] = "^"
solve(x,y-1)
回答1:
You re-load mazeList
each time you call the function.
So at the start of solve()
you are right back at the starting conditions, and you end up running in circles.
Use a keyword argument to pass mazeList
on to recursive calls, default it to None
and only load the maze when it is still None
:
def solve(x, y, mazeList=None):
if mazeList is None:
mazeList = loadMaze("sample.maze")
and pass mazeList
to recursive calls.
Next problem is that you never return recursive calls; when you call solve()
from within solve()
you still need to return its result:
def solve(x, y, mazeList=None):
if mazeList is None:
mazeList = loadMaze("sample.maze")
if mazeList[y][x] == "E":
return "YOU'VE SOLVED THE MAZE!"
elif mazeList[y][x+1] == " ": #right
mazeList[y][x+1] = ">"
return solve(x+1,y,mazeList)
elif mazeList[y+1][x] == " ": #down
mazeList[y+1][x] = "v"
return solve(x,y+1,mazeList)
elif mazeList[y][x-1] == " ": #left
mazeList[y][x-1] = "<"
return solve(x-1,y,mazeList)
elif mazeList[y-1][x] == " ": #up
mazeList[y-1][x] = "^"
return solve(x,y-1,mazeList)
You'd still paint yourself in a corner with this technique; to recursively solve a maze, you need to try all paths, not just one, and give each recursive call a copy of the maze with the one chosen path marked out only.
You also always test for the next cell, but never take into account that that next cell could be the goal; you never move onto E
because that cell is not equal to ' '
, so it's not a move candidate.
The following version can solve your maze:
directions = (
(1, 0, '>'),
(0, 1, 'v'),
(-1, 0, '<'),
(0, -1, '^'),
)
def solve(x, y, mazeList=None):
if mazeList is None:
mazeList = loadMaze("sample.maze")
for dx, dy, char in directions:
nx, ny = x + dx, y + dy
if mazeList[ny][nx] == "E":
return "YOU'VE SOLVED THE MAZE!"
if mazeList[ny][nx] == " ":
new_maze = [m[:] for m in mazeList]
new_maze[ny][nx] = char
result = solve(nx, ny, new_maze)
if result is not None:
return result
Testing for each direction separately was getting tedious, so I replaced that with a loop over a sequence of directions instead; each tuple is a change in x, in y and the character to use when moving in that direction.
Demo, with printout of the solved maze:
>>> def loadMaze(ignored):
... maze = '''\
... ####################################
... #S# ## ######## # # # # #
... # # # # # # #
... # # ##### ## ###### # ####### # #
... ### # ## ## # # # #### #
... # # # ####### # ### #E#
... ####################################
... '''
... return [list(m) for m in maze.splitlines()]
...
>>> directions = (
... (1, 0, '>'),
... (0, 1, 'v'),
... (-1, 0, '<'),
... (0, -1, '^'),
... )
>>>
>>> def solve(x, y, mazeList=None):
... if mazeList is None:
... mazeList = loadMaze("sample.maze")
... for dx, dy, char in directions:
... nx, ny = x + dx, y + dy
... if mazeList[ny][nx] == "E":
... print '\n'.join([''.join(m) for m in mazeList])
... return "YOU'VE SOLVED THE MAZE!"
... if mazeList[ny][nx] == " ":
... new_maze = [m[:] for m in mazeList]
... new_maze[ny][nx] = char
... result = solve(nx, ny, new_maze)
... if result is not None:
... return result
...
>>> solve(1, 1)
####################################
#S# ## ######## # #^>>>>># ^>># #
#v#^>># ^>>> #^# v>>>>#v>>#
#v>>#v#####^##v######^# ####### #v#
### #v##^>>>##v>>>>>#^# # ####v#
# #v>>># #######v>># ### #E#
####################################
"YOU'VE SOLVED THE MAZE!"
来源:https://stackoverflow.com/questions/22717248/runtime-error-in-python-maximum-recursion-depth-exceeded