我发现这个代码可以解决这样的迷宫:
+-+-+-+-+-+-+-+-+-+-+
| | | | |
S +-+-+-+-+ + +-+ + +
| | | | |
+-+-+-+ +-+ +-+-+-+ +
| | | | |
+ + + + + +-+ +-+-+-+
| | | | | | |
+ + +-+ +-+-+ + + + +
| | | | | | | |
+ +-+ + + + + +-+-+-+
| | | | | |
+ + +-+-+-+ + +-+-+ +
| | | | |
+ +-+-+ +-+-+ +-+-+-+
| | | | | |
+ + + +-+-+-+-+ + +-+
| | | | | | |
+ + + + + + +-+-+-+ +
| | | E
+-+-+-+-+-+-+-+-+-+-+
这是代码:
def read_maze(fname):
mz = []
with open(fname, 'U') as f:
for r in f:
mz.append(list(r.replace('\n', '')))
return mz
PATH, START, EXIT, VISITED, SOLUTION = " SE.o"
class Maze():
def __init__(self,maze):
self.maze = maze
self.start_y = [row.count(START) for row in self.maze].index(1)
self.start_x = self.maze[self.start_y].index(START)
def __repr__(self):
return "\n".join("".join(row)for row in self.maze)
def solve(self, x=None, y=None):
if x==None:
x, y = self.start_x,self.start_y
if self.maze[y][x] in (PATH,START):
self.maze[y][x] = VISITED
if self.solve(x+1,y) or self.solve(x-1,y) or self.solve(x,y+1) or self.solve(x,y-1):
self.maze[y][x]=SOLUTION
return True
elif self.maze[y][x] == EXIT:
return True
return False
maze = read_maze("maze.txt")
mz = Maze(maze)
print (mz)
print ("-----------------------------")
if mz.solve():
print(mz)
任何人都可以帮我理解递归函数solve()
吗?
首先,函数检查当前位置是在PATH还是START中,第一次显然处于START状态,在我们的情况下是(x = 0; y = 2)。所以代码将其标记为VISITED。
我不完全理解的是该计划下一步做什么?有一个if条件,第一个选项是self.solve(x+1,y)
- 在这种情况下我们是正确的,这是一个自由位置,它在PATH中(所以我们将其标记为VISITED),但是(x + 1 + 1,y)不是,所以我们传递给or
的第二个值(即(x-1,y)
,所以我们再次获得(x+1+(1-1),y) = (x+1,y)
,现在我们传递给第三个{{1}所以我们下去等等。
这是对的吗?我迷失了一点。
答案 0 :(得分:2)
内联说明
def solve(self, x=None, y=None):
# initializes x, y as start location
# occurs during first call of 'solve', i.e. zeroth recursion
if x==None:
x, y = self.start_x,self.start_y
# equivalent to, if the current (x, y) tile is walk-able
# implicitly ignores visited tiles
if self.maze[y][x] in (PATH,START):
# mark tile (x, y) as visited
self.maze[y][x] = VISITED
# if one of the adjacent tiles from (x, y) leads to a solution
# this is where the recursion occurs, i.e. 'solve' is called using the adjacent tiles
# this will be recursively called until one of the calls return True upon finding the exit
# when one of the calls encounter an exit, then this will create a chain reaction where each call returns True to its caller until the first call returns true
if self.solve(x+1,y) or self.solve(x-1,y) or self.solve(x,y+1) or self.solve(x,y-1):
# mark (x, y) as part of the solution
self.maze[y][x]=SOLUTION
# tells that a solution has been found, value used by caller
return True
# if the (x, y) tile is the exit then a solution has been found
elif self.maze[y][x] == EXIT:
return True
# if non of the if statements return, then by default no solution has been found where tile (x, y) is in the solution path.
return False
迷宫传奇
<space>
可行走的瓷砖S
启动磁贴E
退出磁贴.
访问了瓷砖o
tile是解决方案路径的一部分 solve()
之前的迷宫
+-+-+-+-+-+-+-+-+-+-+
| | | | |
S +-+-+-+-+ + +-+ + +
| | | | |
+-+-+-+ +-+ +-+-+-+ +
| | | | |
+ + + + + +-+ +-+-+-+
| | | | | | |
+ + +-+ +-+-+ + + + +
| | | | | | | |
+ +-+ + + + + +-+-+-+
| | | | | |
+ + +-+-+-+ + +-+-+ +
| | | | |
+ +-+-+ +-+-+ +-+-+-+
| | | | | |
+ + + +-+-+-+-+ + +-+
| | | | | | |
+ + + + + + +-+-+-+ +
| | | E
+-+-+-+-+-+-+-+-+-+-+
solve()
之后的迷宫
+-+-+-+-+-+-+-+-+-+-+
| |.........|...|...|
oo+-+-+-+-+.+.+-+.+.+
|ooooooo..|.|.....|.|
+-+-+-+o+-+.+-+-+-+.+
|ooo..|o|...|.......|
+o+o+.+o+.+-+.+-+-+-+
|o|o|.|o|.......|...|
+o+o+-+o+-+-+.+.+.+.+
|o|ooo|o|ooo|.|...|.|
+o+-+o+o+o+o+.+-+-+-+
|o|ooo|ooo|o|.......|
+o+o+-+-+-+o+.+-+-+.+
|o|ooooooooo|.|.....|
+o+-+-+ +-+-+.+-+-+-+
|o|ooo| |...| |
+o+o+o+-+-+-+-+.+ +-+
|o|o|o| |ooo....| |
+o+o+o+ +o+o+-+-+-+ +
|ooo|ooooo|oooooooooE
+-+-+-+-+-+-+-+-+-+-+
答案 1 :(得分:1)
solve
仅在代码位于“退出”磁贴或导致“退出”磁贴的路径的一部分时返回True
。现在,代码以递归的方式潜入迷宫中:每当一个&#39; PATH&#39;找到了瓷砖,它将其标记为VISITED
并访问所有相邻的瓷砖(下一次递归)或墙面瓷砖,然后返回&#39; False&#39; (不能继续这个方向)。这一直持续到最终找到EXIT
磁贴,返回第一个&#39; True&#39;。这会将递归减少一个并将VISITED
标志更改为SOLUTION
,再次返回True
,再次减少递归。现在这种情况一直持续到代码回到START
磁贴上。
希望这有帮助。