Pygame 迷宫游戏无法正确创建关卡
Pygame Maze Game not creating levels correctly
所以我正在尝试为学校的项目创建一个带有关卡的迷宫游戏。代码有点重复抱歉,我才刚刚开始使用 pygame 编码。当 运行 时,程序应该输出一个迷宫,一旦用户完成就可以进入下一个级别 - 每个级别都是随机生成的。然而,只有第一个关卡显示正确,其余关卡似乎是一个网格 - 这让我觉得游戏正在旧的迷宫上创建一个新的迷宫。
我已经粘贴了下面的代码 - 请随时留下任何关于如何改进我所拥有的代码的建议:)
class Maze:
def __init__(self, rows=30, cols=40):
self.rows = rows
self.cols = cols
self.keep_going = 1
self.maze = {}
for y in range(rows):
for x in range(cols):
cell = {'south' : 1, 'east' : 1, 'visited': 0}
self.maze[(x,y)] = cell
def generate(self, start_cell=None, stack=[])
if start_cell is None:
start_cell = self.maze[(self.cols-1, self.rows-1)]
if not self.keep_going:
return
self.check_finished()
neighbors = []
# if the stack is empty, add the start cell
if len(stack) == 0:
stack.append(start_cell)
# set current cell to last cell
curr_cell = stack[-1]
# get neighbors and shuffle 'em up a bit
neighbors = self.get_neighbors(curr_cell)
shuffle(neighbors)
for neighbor in neighbors:
if neighbor['visited'] == 0:
neighbor['visited'] = 1
stack.append(neighbor)
self.knock_wall(curr_cell, neighbor)
self.generate(start_cell, stack)
def get_coords(self, cell):
# grabs coords of a given cell
coords = (-1, -1)
for k in self.maze:
if self.maze[k] is cell:
coords = (k[0], k[1])
break
return coords
def get_neighbors(self, cell):
# obvious
neighbors = []
(x, y) = self.get_coords(cell)
if (x, y) == (-1, -1):
return neighbors
north = (x, y-1)
south = (x, y+1)
east = (x+1, y)
west = (x-1, y)
if north in self.maze:
neighbors.append(self.maze[north])
if south in self.maze:
neighbors.append(self.maze[south])
if east in self.maze:
neighbors.append(self.maze[east])
if west in self.maze:
neighbors.append(self.maze[west])
return neighbors
def knock_wall(self, cell, neighbor):
# knocks down wall between cell and neighbor.
xc, yc = self.get_coords(cell)
xn, yn = self.get_coords(neighbor)
# Which neighbor?
if xc == xn and yc == yn + 1:
# neighbor's above, knock out south wall of neighbor
neighbor['south'] = 0
elif xc == xn and yc == yn - 1:
# neighbor's below, knock out south wall of cell
cell['south'] = 0
elif xc == xn + 1 and yc == yn:
# neighbor's left, knock out east wall of neighbor
neighbor['east'] = 0
elif xc == xn - 1 and yc == yn:
# neighbor's right, knock down east wall of cell
cell['east'] = 0
def check_finished(self):
# Checks if we're done generating
done = 1
for k in self.maze:
if self.maze[k]['visited'] == 0:
done = 0
break
if done:
self.keep_going = 0
[...] the rest of the levels appear to be a grid- which is making me think that the game is creating a new maze over the old.
此问题是由 Python 中的一个常见错误引起的。
Important warning: The default value is evaluated only once. This makes a difference when the default is a mutable object such as a list, dictionary, or instances of most classes
在您的情况下,class Maze
的方法 generate
的参数具有默认参数:
class Maze:
# [...]
def generate(self, start_cell=None, stack=[]):
# [...]
在方法 generate
中,元素附加到 stack
。迷宫是根据默认参数生成的:
self.maze_obj.generate(self.maze_obj.maze[(0,0)])
导致第1代狼牙棒成功,而后代失败,因为stack
包含了前一代过程的所有要素
将空列表传递给generate
以解决问题:
self.maze_obj.generate(self.maze_obj.maze[(0,0)])
self.maze_obj.generate(self.maze_obj.maze[(0,0)], [])
或将默认参数更改为 None
:
class Maze:
# [...]
def generate(self, start_cell=None, stack=None):
if stack == None:
stack = []
所以我正在尝试为学校的项目创建一个带有关卡的迷宫游戏。代码有点重复抱歉,我才刚刚开始使用 pygame 编码。当 运行 时,程序应该输出一个迷宫,一旦用户完成就可以进入下一个级别 - 每个级别都是随机生成的。然而,只有第一个关卡显示正确,其余关卡似乎是一个网格 - 这让我觉得游戏正在旧的迷宫上创建一个新的迷宫。
我已经粘贴了下面的代码 - 请随时留下任何关于如何改进我所拥有的代码的建议:)
class Maze:
def __init__(self, rows=30, cols=40):
self.rows = rows
self.cols = cols
self.keep_going = 1
self.maze = {}
for y in range(rows):
for x in range(cols):
cell = {'south' : 1, 'east' : 1, 'visited': 0}
self.maze[(x,y)] = cell
def generate(self, start_cell=None, stack=[])
if start_cell is None:
start_cell = self.maze[(self.cols-1, self.rows-1)]
if not self.keep_going:
return
self.check_finished()
neighbors = []
# if the stack is empty, add the start cell
if len(stack) == 0:
stack.append(start_cell)
# set current cell to last cell
curr_cell = stack[-1]
# get neighbors and shuffle 'em up a bit
neighbors = self.get_neighbors(curr_cell)
shuffle(neighbors)
for neighbor in neighbors:
if neighbor['visited'] == 0:
neighbor['visited'] = 1
stack.append(neighbor)
self.knock_wall(curr_cell, neighbor)
self.generate(start_cell, stack)
def get_coords(self, cell):
# grabs coords of a given cell
coords = (-1, -1)
for k in self.maze:
if self.maze[k] is cell:
coords = (k[0], k[1])
break
return coords
def get_neighbors(self, cell):
# obvious
neighbors = []
(x, y) = self.get_coords(cell)
if (x, y) == (-1, -1):
return neighbors
north = (x, y-1)
south = (x, y+1)
east = (x+1, y)
west = (x-1, y)
if north in self.maze:
neighbors.append(self.maze[north])
if south in self.maze:
neighbors.append(self.maze[south])
if east in self.maze:
neighbors.append(self.maze[east])
if west in self.maze:
neighbors.append(self.maze[west])
return neighbors
def knock_wall(self, cell, neighbor):
# knocks down wall between cell and neighbor.
xc, yc = self.get_coords(cell)
xn, yn = self.get_coords(neighbor)
# Which neighbor?
if xc == xn and yc == yn + 1:
# neighbor's above, knock out south wall of neighbor
neighbor['south'] = 0
elif xc == xn and yc == yn - 1:
# neighbor's below, knock out south wall of cell
cell['south'] = 0
elif xc == xn + 1 and yc == yn:
# neighbor's left, knock out east wall of neighbor
neighbor['east'] = 0
elif xc == xn - 1 and yc == yn:
# neighbor's right, knock down east wall of cell
cell['east'] = 0
def check_finished(self):
# Checks if we're done generating
done = 1
for k in self.maze:
if self.maze[k]['visited'] == 0:
done = 0
break
if done:
self.keep_going = 0
[...] the rest of the levels appear to be a grid- which is making me think that the game is creating a new maze over the old.
此问题是由 Python 中的一个常见错误引起的。
Important warning: The default value is evaluated only once. This makes a difference when the default is a mutable object such as a list, dictionary, or instances of most classes
在您的情况下,class Maze
的方法 generate
的参数具有默认参数:
class Maze: # [...] def generate(self, start_cell=None, stack=[]): # [...]
在方法 generate
中,元素附加到 stack
。迷宫是根据默认参数生成的:
self.maze_obj.generate(self.maze_obj.maze[(0,0)])
导致第1代狼牙棒成功,而后代失败,因为stack
包含了前一代过程的所有要素
将空列表传递给generate
以解决问题:
self.maze_obj.generate(self.maze_obj.maze[(0,0)])
self.maze_obj.generate(self.maze_obj.maze[(0,0)], [])
或将默认参数更改为 None
:
class Maze:
# [...]
def generate(self, start_cell=None, stack=None):
if stack == None:
stack = []