2026-rff_mp/ivanchenkoam/maze_project/models.py

113 lines
3.6 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

"""Модели данных: Cell, Maze, Player"""
from dataclasses import dataclass
from typing import List, Optional
@dataclass
class Cell:
"""Клетка лабиринта"""
x: int
y: int
is_wall: bool = False
is_start: bool = False
is_exit: bool = False
weight: int = 1 # для взвешенных лабиринтов
def is_passable(self) -> bool:
"""Проверка, можно ли пройти через клетку"""
return not self.is_wall
def __hash__(self) -> int:
return hash((self.x, self.y))
def __eq__(self, other: object) -> bool:
if not isinstance(other, Cell):
return False
return self.x == other.x and self.y == other.y
class Maze:
"""Лабиринт"""
def __init__(self, width: int, height: int):
self.width = width
self.height = height
self._cells: List[List[Cell]] = []
self.start: Optional[Cell] = None
self.exit: Optional[Cell] = None
self.name: str = "Лабиринт"
def set_cells(self, cells: List[List[Cell]]) -> None:
"""Устанавливает клетки и определяет старт/выход"""
self._cells = cells
for row in cells:
for cell in row:
if cell.is_start:
self.start = cell
if cell.is_exit:
self.exit = cell
def get_cell(self, x: int, y: int) -> Optional[Cell]:
"""Получение клетки по координатам"""
if 0 <= x < self.width and 0 <= y < self.height:
return self._cells[y][x]
return None
def get_neighbors(self, cell: Cell) -> List[Cell]:
"""Получение всех проходимых соседей клетки"""
neighbors = []
directions = [(0, -1), (0, 1), (-1, 0), (1, 0)] # вверх, вниз, влево, вправо
for dx, dy in directions:
nx, ny = cell.x + dx, cell.y + dy
neighbor = self.get_cell(nx, ny)
if neighbor and neighbor.is_passable():
neighbors.append(neighbor)
return neighbors
def __str__(self) -> str:
"""Строковое представление лабиринта"""
result = []
for row in self._cells:
line = ''
for cell in row:
if cell.is_start:
line += 'S'
elif cell.is_exit:
line += 'E'
elif cell.is_wall:
line += '#'
else:
line += ' '
result.append(line)
return '\n'.join(result)
class Player:
"""Игрок для пошагового режима"""
def __init__(self, start_cell: Cell):
self.current_cell = start_cell
self.start_cell = start_cell
self.history: List[Cell] = []
def move_to(self, cell: Cell) -> None:
"""Перемещение игрока в клетку"""
self.history.append(self.current_cell)
self.current_cell = cell
def undo(self) -> None:
"""Отмена последнего перемещения"""
if self.history:
self.current_cell = self.history.pop()
def can_move_to(self, cell: Cell) -> bool:
"""Проверка возможности перемещения"""
return cell.is_passable()
def reset(self) -> None:
"""Сброс игрока на старт"""
self.current_cell = self.start_cell
self.history.clear()