我已经使用 numpy 在 Python 中实现了 Sokoban 级别生成器,但当我运行代码时,它不会打印任何内容或生成预期的 Sokoban 级别。生成器应该经过
我已经使用 numpy 在 Python 中实现了 Sokoban 级别生成器,但是当我运行代码时,它不会打印任何内容或生成预期的 Sokoban 级别。生成器应该经历几个步骤:
-
放置边界:用墙围绕关卡(#)
-
放置墙壁:在关卡内添加随机墙壁以增加复杂性。
-
放置玩家:将玩家(@)定位在随机位置。
-
放置盒子和目标:随机添加盒子 ($) 及其各自的目标 (.)。
-
检查可解性:确认所有箱子都能达到各自的目标,从而保证关卡可解。
-
生成和返回级别:构建并返回表示推箱子级别的二维列表。
代码实现:
import numpy as np
class LevelGenerator:
def __init__(self, size, num_walls):
self.size = size
self.num_walls = num_walls
self.level = np.full((size, size), ' ')
self.generate_level()
def place_borders(self):
self.level[0, :] = '#'
self.level[:, 0] = '#'
self.level[-1, :] = '#'
self.level[:, -1] = '#'
def place_walls(self):
for _ in range(self.num_walls):
while True:
x, y = np.random.randint(1, self.size-1, size=2)
if self.level[x, y] == ' ':
self.level[x, y] = '#'
break
def place_player(self):
while True:
x, y = np.random.randint(1, self.size-1, size=2)
if self.level[x, y] == ' ':
self.level[x, y] = '@'
self.player_pos = (x, y)
break
def place_boxes_and_goals(self):
num_boxes = (self.size - 2) // 2
self.boxes = []
self.goals = []
for _ in range(num_boxes):
while True:
x, y = np.random.randint(1, self.size-1, size=2)
if self.level[x, y] == ' ':
self.level[x, y] = '$'
self.boxes.append((x, y))
break
for _ in range(num_boxes):
while True:
x, y = np.random.randint(1, self.size-1, size=2)
if self.level[x, y] == ' ':
self.level[x, y] = '.'
self.goals.append((x, y))
break
def is_solvable(self):
return all(self.is_reachable(box) for box in self.boxes) and all(self.is_reachable(goal) for goal in self.goals)
def is_reachable(self, target):
x, y = target
if self.level[x, y] in '#':
return False
visited = set()
stack = [self.player_pos]
while stack:
cx, cy = stack.pop()
if (cx, cy) == target:
return True
if (cx, cy) in visited:
continue
visited.add((cx, cy))
for dx, dy in [(-1, 0), (1, 0), (0, -1), (0, 1)]:
nx, ny = cx + dx, cy + dy
if 0 <= nx < self.size and 0 <= ny < self.size and self.level[nx, ny] not in '#$' and (nx, ny) not in visited:
stack.append((nx, ny))
return False
def generate_level(self):
while True:
self.level.fill(' ')
self.place_borders()
self.place_walls()
self.place_player()
self.place_boxes_and_goals()
if self.is_solvable():
break
def get_level(self):
return self.level
# Example usage
print("Generating Sokoban level...")
size = 10
num_walls = 20
generator = LevelGenerator(size, num_walls)
level = generator.get_level()
print("\n".join("".join(row) for row in level))
运行代码后,程序似乎无限期地挂起,没有显示任何内容,而是打印出推箱子的等级。我期望程序根据指定的 (size = 10)
墙壁大小和数量 (num_walls = 20)
.
有人能帮忙找出是什么原因导致代码无法显示或打印生成的推箱子关卡吗?如果您能提供任何关于如何修复此问题的见解或建议,我们将不胜感激。