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 中的一个常见错误引起的。

Default Argument Values

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 = []