- Размещение границ: окружение уровня стенами (#)
- Размещение стен: добавление случайных стен на уровне для повышения сложности.
- Размещение игрока: размещение игрока (@) в случайном месте.
- Размещение коробок и Цели: случайное добавление ячеек ($) и соответствующих им целей (.).
- Проверка решаемости: проверка разрешимости уровня путем подтверждения того, что все коробки могут достичь соответствующих целей.
- Создание и возврат уровня: создание и возврат 2D-списка, представляющего уровень Сокобан.
Код: Выделить всё
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
Подробнее здесь: [url]https://stackoverflow.com/questions/78658892/my-python-sokoban-level-generator-hangs-indefinitely-without-display-the-level-i[/url]