在函数内调用函数不能按预期工作?

时间:2018-05-07 02:40:05

标签: python list function maze

我正在设计python中的迷宫生成器,并为该过程的不同步骤提供各种功能。 (我知道代码可以肯定会得到改进,但我只是在我优化它之前先寻找问题的答案)

第一个函数以2D列表的形式生成基本迷宫并按预期工作:

def base_maze(dimension):
    num_rows = int((2 * dimension[1]) + 1)          #number of rows / columns
    num_columns = int((2 * dimension[0]) + 1)       #from tuple input

    zero_row = []                                   #initialise a row of 0s
    for i in range(num_columns):
        zero_row.append(0)

    norm_row = []                                   #initialise a row of
    for i in range(num_columns // 2):               #alternating 0s and 1s
        norm_row.extend([0,1])
    norm_row.append(0)

    maze = []                                       #initialise maze
                                                    #(combination of zero rows 
    for i in range(num_rows  // 2):                 # and normal rows)
        maze.append(zero_row)
        maze.append(norm_row)
    maze.append(zero_row)

    return maze

另一个函数获取所选单元格的邻居,并且也按预期工作:

def get_neighbours(cell, dimension):

    y = cell[0]                                     #set x/y values
    max_y = dimension[0] - 1                        #for reference

    x = cell[1]
    max_x = dimension[1] - 1

    n = (x, y-1)                                    #calculate adjacent
    e = (x+1, y)                                    #coordinates
    s = (x, y+1)
    w = (x-1, y)

    if y > max_y or y < 0 or x > max_x or x < 0:        #check if x/y
        raise IndexError("Cell is out of maze bounds")  #in bounds

    neighbours = []

    if y > 0:                                       #add cells to list
        neighbours.append(n)                        #if they're valid
    if x < max_x:                                   #cells inside maze
        neighbours.append(e)
    if y < max_y:                                   
        neighbours.append(s)
    if x > 0:                                       
        neighbours.append(w)

    return neighbours

下一个函数删除了两个给定单元格之间的墙:

def remove_wall(maze, cellA, cellB):

    dimension = []
    x_dim = int(((len(maze[0]) - 1) / 2))           #calc the dimensions
    y_dim = int(((len(maze) - 1) / 2))              #of maze matrix (x,y)
    dimension.append(x_dim)
    dimension.append(y_dim)

    A_loc = maze[2*cellA[1]-1][2*cellA[0]-1]
    B_loc = maze[2*cellB[1]-1][2*cellB[0]-1]

    if cellB in get_neighbours(cellA, dimension):   #if cell B is a neighbour

        if cellA[0] == cellB[0] and cellA[1] < cellB[1]:            #if the x pos of A is equal
            adj_wall = maze[(2*cellA[0]+1)][2*cellA[1]+1+1] = 1     #to x pos of cell B and the y pos
                                                                    #of A is less than B (A is below B)
        elif cellA[0] == cellB[0] and cellA[1] > cellB[1]:          #the adjacent wall is set to 1 (removed)
            adj_wall = maze[(2*cellA[0]+1)][2*cellA[1]+1-1] = 1
                                                                    #same is done for all other directions
        if cellA[1] == cellB[1] and cellA[0] < cellB[0]:
            adj_wall = maze[(2*cellA[0]+1)+1][(2*cellA[1]+1)] = 1

        elif cellA[1] == cellB[1] and cellA[0] > cellB[0]:
            adj_wall = maze[(2*cellA[0]+1-1)][(2*cellA[1]+1)] = 1

        return maze

然而,当我尝试将这些功能组合成一个最终功能来构建迷宫时,它们无法正常工作,例如:

def test():
    maze1 = base_maze([3,3])
    maze2 = [[0, 0, 0, 0, 0, 0, 0], [0, 1, 0, 1, 0, 1, 0], [0, 0, 0, 0, 0, 0, 0], [0, 1, 0, 1, 0, 1, 0], [0, 0, 0, 0, 0, 0, 0], [0, 1, 0, 1, 0, 1, 0], [0, 0, 0, 0, 0, 0, 0]]

    if maze1 == maze2:
        print("they are exactly the same")
    else:
        print("WHY ARE THEY DIFFERENT???")

    remove_wall(maze1,(0,0),(0,1))
    remove_wall(maze2,(0,0),(0,1))

尽管输入完全相同,这些会产生不同的结果吗?:

test()
they are exactly the same
[[0, 0, 0, 0, 0, 0, 0], [0, 1, 1, 1, 0, 1, 0], [0, 0, 0, 0, 0, 0, 0], [0, 1, 1, 1, 0, 1, 0], [0, 0, 0, 0, 0, 0, 0], [0, 1, 1, 1, 0, 1, 0], [0, 0, 0, 0, 0, 0, 0]]
[[0, 0, 0, 0, 0, 0, 0], [0, 1, 1, 1, 0, 1, 0], [0, 0, 0, 0, 0, 0, 0], [0, 1, 0, 1, 0, 1, 0], [0, 0, 0, 0, 0, 0, 0], [0, 1, 0, 1, 0, 1, 0], [0, 0, 0, 0, 0, 0, 0]]

1 个答案:

答案 0 :(得分:0)

问题出在您的base_maze函数中,您首先要创建两种类型的行:

zero_row = []                                   #initialise a row of 0s
for i in range(num_columns):
    zero_row.append(0)

norm_row = []                                   #initialise a row of
for i in range(num_columns // 2):               #alternating 0s and 1s
    norm_row.extend([0,1])
norm_row.append(0)

到目前为止这很好并按预期工作,但是当你从那里建立迷宫时

for i in range(num_rows  // 2):                 # and normal rows)
    maze.append(zero_row)
    maze.append(norm_row)
maze.append(zero_row)

您正在使用同一列表的多个实例填充迷宫列表。这意味着如果您修改迷宫的第0行,第2行和第2行。 4也会受到影响。举例说明:

>>> def print_maze(maze):
...     print('\n'.join(' '.join(str(x) for x in row) for row in maze))
... 
>>> print_maze(maze)
0 0 0 0 0
0 1 0 1 0
0 0 0 0 0
0 1 0 1 0
0 0 0 0 0
>>> maze[0][0] = 3
>>> print_maze(maze)
3 0 0 0 0
0 1 0 1 0
3 0 0 0 0
0 1 0 1 0
3 0 0 0 0

请注意第0,2行和第0行。 4都改变了。这是因为maze[0]zero_rowmaze[2]的{​​{1}}实例相同。

相反,当您创建迷宫时,您想要使用行列表的副本。这可以使用以下切片表示法在Python中轻松完成

maze[4]