检查完美迷宫输入的验证

时间:2015-04-05 07:32:41

标签: python recursion path-finding maze

我正致力于建立一个完美的迷宫项目。 我有一个类Maze和一个Cell类代表迷宫中的每个方块。在我的Cell类中,我有四个布尔变量(北,南,东,西)来表示在单元格的北边或南边是否有墙。还有一个名为visit的布尔变量,用于检查是否已访问过该单元。这是我的Cell类 init ()的代码。

def __init__(self):
    self.north = True
    self.south = True
    self.east = True
    self.west = True
    self.visit = False

对于Maze课程,我有self.maze(一堆Cell)和self.size = N(构建一个N * N迷宫)。 以下是Maze类的 init ():

def __init__(self, N):

    self.size = N
    self.maze = [[i for i in range(N + 2)] for i in range(N + 2)]

    for r in range(self.size + 2):
        for c in range(self.size + 2):
            self.maze[r][c] = Cell()

当我更新迷宫索引时,我写了两个函数来检查newX和newY是否在1< = x< = self.size和1< = y< 1的范围内。 = self.size,以及是否已访问过该单元格。 这是代码:

def in_range(self, x, y):

    if 1 <= x <= self.size and 1 <= y <= self.size:
        return True
    else:
        return False

def is_valid(self, x, y):

    if not self.maze[x][y].getVisit() and self.in_range(x,y):
        return True
    else:
        return False

毕竟,我写了主要结构:

def walk(self, s, x, y):

    neighbor = [(x + 1, y), (x - 1, y), (x, y + 1), (x, y - 1)]


    if s.size() == self.size**2: return

    else:

        while True:
            new = choice(neighbor)#choice() is import from random
            #print(self.is_valid(new[0], new[1]))
            if self.is_valid(new[0], new[1]):break
            else:
                if len(neighbor) != 0:
                    neighbor.remove(new)
                    new = choice(neighbor)
                else:
                    temp = s.pop(s)
                    self.walk(s, temp[0], temp[1])

                break
    print(new)

但是,运行我的代码仍会给我一个不在1和self.size之间的索引。我无法弄清楚为什么,我认为我的检查算法运行正常。 这是我得到的:

>>> ================================ RESTART 

================================
>>> 
>>> a = Maze(5)
>>> a.search()
1 2
(1, 3)
(2, 3)
(2, 4)
(1, 4)
(2, 4)
(2, 5)
(3, 5)
(4, 5)
(4, 4)
(4, 3)
(3, 3)
(3, 2)
(2, 2)
(2, 1)
(1, 1)
(0, 1)
(-1, 1)
(0, 1)
(1, 1)
(0, 1)
(-1, 1)
(-1, 2)
(-1, 1)
(0, 1)

有人可以帮帮我吗? PLZ,真的很感激!

2 个答案:

答案 0 :(得分:0)

在Python range中,如果您没有指定另一个起始位置,则从0开始。因此,当您初始化迷宫时,您有(0, *)(*, 0)中的单元格:

for r in range(self.size + 2):
    for c in range(self.size + 2):
        self.maze[r][c] = Cell()

当你计算邻居时,你不能检查你是否已经离开:

neighbor = [(x + 1, y), (x - 1, y), (x, y + 1), (x, y - 1)]

只有在将new分配给这样的坐标后才能检查它是否有效。但是,如果它有效并且没有邻居,则您再次呼叫walk。您应该尝试独立于in_range检查visit

此外,您的循环只能运行一次,因为new有效并且您已经退出循环或者它无效并且您已经退出循环。

最后,您忘了向我们提供search函数以及s是什么(而s.pop(s)看起来很有趣,因为pop的参数通常是索引,而不是顺序)。

答案 1 :(得分:0)

您可以通过仔细查看walk()或使用print语句对其进行分析来找到这一点。 在网格的末端出现问题(当x或y == 0或N-1时)。除非您允许环绕,否则我假设您的网格初始化会在网格的北部(y == 0),南部,东部和西部放置墙。 顺便说一下,你的网格有两个不必要的行和列:如果你想要N个单元格,编号为O ..(N-1),那么使用range(N),而不是range(N+2),否则使用{{1 }}。 (你是否用有效的== False填充任何不需要的单元格?)

无论如何,range(1,N+1)首先选择一个随机相邻小区,如果它是一个有效的小区,则会跳出while循环。但如果它不是,它会愉快地选择任何剩余的相邻小区(无论是否有效)和士兵。这是你的错误。始终测试有效性。 如果它已经用完了有效的邻居单元,它会通过执行walk()来回溯。 s.pop(s)也看起来像个bug。为什么不s.pop(s)? 顺便说一下,调用变量s.pop()而不是path

另外,这只是检查坐标的有效性;你从来没有真正检查过你是否曾经访问过这个单元格,所以你的递归回溯没有结束条件;你可以很容易地进入循环。

如果你重构s使用一个单独的生成器walk(),它会将已经测试过的随机选择的邻居返回为有效(和get_random_valid_neighbor()当你用完邻居时,你可以帮助自己很多)。

None