diff --git a/KislyuninED/docks/data/2-st-exercize/maze-core.py b/KislyuninED/docks/data/2-st-exercize/maze-core.py new file mode 100644 index 0000000..562af2a --- /dev/null +++ b/KislyuninED/docks/data/2-st-exercize/maze-core.py @@ -0,0 +1,143 @@ +import sys +from collections import deque +import heapq +import time +import os + + +class Cell: + def __init__(self, x, y): + self._x = x + self._y = y + self._is_wall = False + self._is_start = False + self._is_exit = False + + @property + def x(self): + return self._x + + @property + def y(self): + return self._y + + @property + def is_wall(self): + return self._is_wall + + @is_wall.setter + def is_wall(self, value): + self._is_wall = value + + @property + def is_start(self): + return self._is_start + + @is_start.setter + def is_start(self, value): + self._is_start = value + + @property + def is_exit(self): + return self._is_exit + + @is_exit.setter + def is_exit(self, value): + self._is_exit = value + + def is_passable(self): + return not self._is_wall + + +class Maze: + def __init__(self, width, height): + self._width = width + self._height = height + self._cells = [[Cell(x, y) for x in range(width)] for y in range(height)] + self._start = None + self._exit = None + + @property + def width(self): + return self._width + + @property + def height(self): + return self._height + + @property + def start(self): + return self._start + + @property + def exit(self): + return self._exit + + def get_cell(self, x, y): + if 0 <= x < self._width and 0 <= y < self._height: + return self._cells[y][x] + return None + + def set_cell(self, x, y, cell_type): + cell = self.get_cell(x, y) + if cell is None: + return + + if cell_type == 'wall': + cell.is_wall = True + elif cell_type == 'start': + if self._start: + self._start.is_start = False + cell.is_start = True + cell.is_wall = False + self._start = cell + elif cell_type == 'exit': + if self._exit: + self._exit.is_exit = False + cell.is_exit = True + cell.is_wall = False + self._exit = cell + elif cell_type == 'path': + cell.is_wall = False + + def get_neighbors(self, 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 + + +class MazeBuilder: + def build_from_file(self, filename): + raise NotImplementedError("Need to realise in calss") + + +class TextFileMazeBuilder(MazeBuilder): + def build_from_file(self, filename): + with open(filename, 'r') as f: + lines = [line.rstrip('\n') for line in f.readlines()] + height = len(lines) + width = max(len(line) for line in lines) if height > 0 else 0 + start_en = 0 + exit_en = 0 + maze = Maze(width, height) + + for y, line in enumerate(lines): + for x, ch in enumerate(line): + if ch == "#": + maze.set_cell(x, y, "wall") + elif ch == "S": + maze.set_cell(x, y, "start") + start_en += 1 + elif ch == "E": + maze.set_cell(x, y, "exit") + exit_en += 1 + else: + maze.set_cell(x, y, 'path') + if start_en != 1 or exit_en != 1: + raise ValueError(f"Labirint must have one S and one E. Found: S={start_en}, E={exit_en}") + return maze \ No newline at end of file