我有一个程序可以搜索代表迷宫的2D列表:
####################################
#S# ## ######## # # # # #
# # # # # # #
# # ##### ## ###### # ####### # #
### # ## ## # # # #### #
# # # ####### # ### #E#
####################################
我理解递归错误是什么,但我不知道为什么这个代码会导致它,因为它应该只是导致找到" E"。有谁知道这可能会产生错误?
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)
答案 0 :(得分:6)
每次调用函数时,都会重新加载mazeList
。
所以在solve()
开始时,你就会回到起始状态,然后你最终会在圈子里跑。
使用关键字参数将mazeList
传递给递归调用,将其默认为None
并仅在迷宫仍为None
时加载:
def solve(x, y, mazeList=None):
if mazeList is None:
mazeList = loadMaze("sample.maze")
并将mazeList
传递给递归调用。
下一个问题是你永远不会返回递归调用;当您从solve()
内拨打solve()
时,仍需要返回结果:
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)
你还是会用这种技巧把自己画在角落里;要递归地解决迷宫问题,你需要尝试所有路径,而不仅仅是一个路径,并给每个递归调用一个迷宫的副本,只选择一个选定的路径。
您也始终测试 next 单元格,但从不考虑下一个单元格可能是目标;你永远不会将移到 E
,因为该单元格不等于' '
,所以它不是移动候选者。
以下版本可以解决你的迷宫:
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
分别对每个方向进行测试变得乏味,因此我将其替换为一系列方向的循环;每个元组都是x的变化,y是在该方向上移动时使用的字符。
演示,打印出已解决的迷宫:
>>> 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!"