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

时间:2021-08-31 16:45:09

I'm designing a maze generator in python and have various functions for different steps of the process. (I know the code can most definitely be improved but I'm just looking for an answer to my problem first before I work on optimizing it)

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

the first function generates a base maze in the form of a 2D list and works as expected:

第一个函数以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

Another function gets the neighbors of the selected cell, and also works as expected:

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

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

the next function removes the wall between two given cells:

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

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

yet when I try to put these functions together into one final function to build the maze, they do not work as they work on their own, for example:

然而,当我尝试将这些功能组合成一个最终功能来构建迷宫时,它们不会像他们自己一样工作,例如:

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))

these will produce different results despite the input being exactly the same?:

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

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 个解决方案

#1


0  

The problem is in your base_maze function, where you first create two types of row:

问题出在你的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)

This is fine so far and works as expected, however when you build the maze from there

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

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

You are filling up the maze list with multiple instances of the same list. This means if you modify row 0 of the maze, row 2 & 4 will also be affected. To illustrate:

您正在使用同一列表的多个实例填充迷宫列表。这意味着如果您修改迷宫的第0行,第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

Note that rows 0, 2, & 4 have all changed. This is because maze[0] is the same zero_row instance as maze[2] and maze[4].

请注意,行0,2和4都已更改。这是因为迷宫[0]与迷宫[2]和迷宫[4]是相同的zero_row实例。

Instead, when you create the maze you want to use a copy of the row lists. This can be done easily in Python using the following slicing notation

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

for i in range(num_rows  // 2):
    maze.append(zero_row[:]) # note the [:] syntax for copying a list
    maze.append(norm_row[:])
maze.append(zero_row[:])

#1


0  

The problem is in your base_maze function, where you first create two types of row:

问题出在你的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)

This is fine so far and works as expected, however when you build the maze from there

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

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

You are filling up the maze list with multiple instances of the same list. This means if you modify row 0 of the maze, row 2 & 4 will also be affected. To illustrate:

您正在使用同一列表的多个实例填充迷宫列表。这意味着如果您修改迷宫的第0行,第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

Note that rows 0, 2, & 4 have all changed. This is because maze[0] is the same zero_row instance as maze[2] and maze[4].

请注意,行0,2和4都已更改。这是因为迷宫[0]与迷宫[2]和迷宫[4]是相同的zero_row实例。

Instead, when you create the maze you want to use a copy of the row lists. This can be done easily in Python using the following slicing notation

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

for i in range(num_rows  // 2):
    maze.append(zero_row[:]) # note the [:] syntax for copying a list
    maze.append(norm_row[:])
maze.append(zero_row[:])