2026-rff_mp/BorisovMI/lab_2/docs/data/maze.py

123 lines
3.3 KiB
Python

from abc import ABC, abstractclassmethod
from collections import deque
import heapq
import time
import os
import time
import csv
import random
class Cell:
def __init__(self, x, y):
self.x = x
self.y = y
self.isWall = False
self.isStart = False
self.isExit = False
def __eq__(self, other):
if other is None:
return False
return self.x == other.x and self.y == other.y
def __lt__(self, other):
if other is None:
return False
return (self.x, self.y) < (other.x, other.y)
def __hash__(self):
return hash((self.x, self.y))
def __repr__(self):
return f"Cell({self.x}, {self.y})"
def isPassable(self):
return not self.isWall
class Maze:
def __init__(self, width, height):
self.width = width
self.height = height
self.grid = [[Cell(x, y) for y in range(height)] for x in range(width)]
self.start = None
self.exit = None
def getCell(self, x, y):
if 0 <= x < self.width and 0 <= y < self.height:
return self.grid[x][y]
return None
def getNeighbors(self, cell):
neighbors = []
directions = [(0, 1), (0, -1), (1, 0), (-1, 0)]
for dx, dy in directions:
neighbor = self.getCell(cell.x + dx, cell.y + dy)
if neighbor and neighbor.isPassable():
neighbors.append(neighbor)
return neighbors
def setStart(self, x, y):
cell = self.getCell(x, y)
if cell:
cell.isStart = True
self.start = cell
def setExit(self, x, y):
cell = self.getCell(x, y)
if cell:
cell.isExit = True
self.exit = cell
class MazeBuilder(ABC):
def buildFromFile(self, filename):
pass
class TextileMazeBuilder(MazeBuilder):
def buildFromFile(self, filename):
with open(filename, 'r', encoding='utf-8') as f:
lines = f.readlines()
lines = [line.rstrip('\n\r') for line in lines]
height = len(lines)
width = len(lines[0]) if height > 0 else 0
for line in lines:
if len(line) != width:
raise ValueError("все строки одинаковой длины")
maze = Maze(width, height)
for y in range(height):
for x in range(width):
char = lines[y][x]
cell = maze.getCell(x, y)
if char == '#':
cell.isWall = True
elif char == ' ':
cell.isWall = False
elif char == 's':
cell.isWall = False
cell.isStart = True
maze.start = cell
elif char == 'e':
cell.isWall = False
cell.isExit = True
maze.exit = cell
else:
raise ValueError(f"неизв сим")
if maze.start is None:
raise ValueError("в лабиринте не найден старт")
if maze.exit is None:
raise ValueError("в лабиринте не найден выход")
return maze