在python中解决迷宫

时间:2017-05-27 16:52:54

标签: python recursion

我发现这个代码可以解决这样的迷宫:

+-+-+-+-+-+-+-+-+-+-+
| |         |   |   |
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}所以我们下去等等。

这是对的吗?我迷失了一点。

2 个答案:

答案 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磁贴上。

希望这有帮助。