From 05c3a5cb6c2bc4ccf4ccf711c24d2def27852886 Mon Sep 17 00:00:00 2001 From: Roman Date: Sun, 24 May 2026 13:08:02 +0300 Subject: [PATCH] [2] initial commit --- zhigalovrd/lab2/builder.py | 36 ++++++++++++++++++++++++++++++++++++ zhigalovrd/lab2/git | 0 zhigalovrd/lab2/maze.py | 35 +++++++++++++++++++++++++++++++++++ 3 files changed, 71 insertions(+) create mode 100644 zhigalovrd/lab2/builder.py create mode 100644 zhigalovrd/lab2/git create mode 100644 zhigalovrd/lab2/maze.py diff --git a/zhigalovrd/lab2/builder.py b/zhigalovrd/lab2/builder.py new file mode 100644 index 0000000..a38c988 --- /dev/null +++ b/zhigalovrd/lab2/builder.py @@ -0,0 +1,36 @@ +from abc import ABC, abstractmethod +from maze import Maze, Cell + +class MazeBuilder(ABC): + @abstractmethod + def build_from_file(self, filename: str) -> Maze: + pass + +class TextFileMazeBuilder(MazeBuilder): + def build_from_file(self, filename: str) -> Maze: + with open(filename, 'r', encoding='utf-8') as f: + lines = [line.rstrip('\n') for line in f] + + if not lines: + raise ValueError("Файл пуст") + height = len(lines) + width = max(len(line) for line in lines) + maze = Maze(width, height) + + for y, line in enumerate(lines): + for x, ch in enumerate(line): + if x >= width: + continue + cell = maze.get_cell(x, y) + if ch == '#': + cell.is_wall = True + elif ch == 'S': + cell.is_start = True + maze.start = cell + elif ch == 'E': + cell.is_exit = True + maze.exit = cell + # пробел или любой другой символ – проход + if maze.start is None or maze.exit is None: + raise ValueError("Лабиринт должен содержать S (старт) и E (выход)") + return maze \ No newline at end of file diff --git a/zhigalovrd/lab2/git b/zhigalovrd/lab2/git new file mode 100644 index 0000000..e69de29 diff --git a/zhigalovrd/lab2/maze.py b/zhigalovrd/lab2/maze.py new file mode 100644 index 0000000..0bd51c1 --- /dev/null +++ b/zhigalovrd/lab2/maze.py @@ -0,0 +1,35 @@ +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 + + def is_passable(self) -> bool: + return not self.is_wall + +class Maze: + def __init__(self, width: int, height: int): + self.width = width + self.height = height + self.cells = [[Cell(x, y) for x in range(width)] for y in range(height)] + self.start: Optional[Cell] = None + self.exit: Optional[Cell] = None + + 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 = [] + for dx, dy in ((0,1), (0,-1), (1,0), (-1,0)): + 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 \ No newline at end of file