2026-rff_mp/SobolevNS/docs/data/task2_maze/maze_solver/model.py
2026-05-22 13:42:42 +03:00

93 lines
3.1 KiB
Python

"""
maze_solver/model.py - модель лабиринта (этап 1, без паттернов).
"""
class Cell:
"""Клетка лабиринта.
Атрибуты:
x, y - координаты
is_wall - стена ли
is_start - стартовая клетка
is_exit - клетка выхода
weight - стоимость прохода (по умолчанию 1, для взвешенного режима >1)
"""
__slots__ = ("x", "y", "is_wall", "is_start", "is_exit", "weight")
def __init__(self, x, y, is_wall=False, is_start=False, is_exit=False, weight=1):
self.x = x
self.y = y
self.is_wall = is_wall
self.is_start = is_start
self.is_exit = is_exit
self.weight = weight
def is_passable(self):
return not self.is_wall
def __repr__(self):
return f"Cell({self.x},{self.y},wall={self.is_wall})"
class Maze:
"""Лабиринт как двумерный массив клеток.
Атрибуты:
width, height - размеры
grid - список списков клеток [y][x]
start, exit_ - ссылки на клетки старта и выхода (могут быть None при ошибке)
"""
def __init__(self, width, height):
self.width = width
self.height = height
self.grid = [[Cell(x, y, is_wall=True) for x in range(width)]
for y in range(height)]
self.start = None
self.exit_ = None
def get_cell(self, x, y):
if 0 <= x < self.width and 0 <= y < self.height:
return self.grid[y][x]
return None
def get_neighbors(self, cell):
"""Соседи (вверх, вниз, влево, вправо), только проходимые и в пределах поля."""
out = []
for dx, dy in ((0, -1), (0, 1), (-1, 0), (1, 0)):
nb = self.get_cell(cell.x + dx, cell.y + dy)
if nb is not None and nb.is_passable():
out.append(nb)
return out
def render_text(self, path=None, player=None):
"""Возвращает текстовое представление лабиринта.
'#' стена, ' ' проход, 'S' старт, 'E' выход,
'.' клетка пути, '@' игрок.
"""
path_set = set()
if path:
for c in path:
path_set.add((c.x, c.y))
lines = []
for y in range(self.height):
row = []
for x in range(self.width):
cell = self.grid[y][x]
ch = ' '
if cell.is_wall:
ch = '#'
elif cell.is_start:
ch = 'S'
elif cell.is_exit:
ch = 'E'
elif (x, y) in path_set:
ch = '.'
if player is not None and player.x == x and player.y == y:
ch = '@'
row.append(ch)
lines.append("".join(row))
return "\n".join(lines)