我正在设计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]]
答案 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_row
和maze[2]
的{{1}}实例相同。
相反,当您创建迷宫时,您想要使用行列表的副本。这可以使用以下切片表示法在Python中轻松完成
maze[4]