2026-rff_mp/raskatovia/docs/data/task2/maze.py

96 lines
2.7 KiB
Python

class Cell:
def __init__(self, row, col, value):
self.row = row
self.col = col
self.value = value
def is_wall(self):
return self.value == "#"
def is_start(self):
return self.value == "S"
def is_finish(self):
return self.value == "F"
class Maze:
def __init__(self, cells, start, finish):
self.cells = cells
self.start = start
self.finish = finish
self.height = len(cells)
self.width = len(cells[0]) if cells else 0
def inside(self, row, col):
return 0 <= row < self.height and 0 <= col < self.width
def get_cell(self, row, col):
if not self.inside(row, col):
return None
return self.cells[row][col]
def is_free(self, row, col):
cell = self.get_cell(row, col)
return cell is not None and not cell.is_wall()
def neighbors(self, row, col):
variants = [
(row - 1, col),
(row + 1, col),
(row, col - 1),
(row, col + 1)
]
result = []
for next_row, next_col in variants:
if self.is_free(next_row, next_col):
result.append((next_row, next_col))
return result
def draw(self, path=None):
path_set = set(path) if path else set()
lines = []
for row in range(self.height):
line = ""
for col in range(self.width):
cell = self.cells[row][col]
if (row, col) in path_set and not cell.is_start() and not cell.is_finish():
line += "*"
else:
line += cell.value
lines.append(line)
return "\n".join(lines)
class MazeBuilder:
def __init__(self):
self.lines = []
def from_file(self, filename):
with open(filename, "r", encoding="utf-8") as file:
self.lines = [line.rstrip("\n") for line in file if line.strip()]
return self
def build(self):
cells = []
start = None
finish = None
width = len(self.lines[0])
for row, line in enumerate(self.lines):
if len(line) != width:
raise ValueError("maze lines have different length")
cell_row = []
for col, value in enumerate(line):
cell = Cell(row, col, value)
if cell.is_start():
start = (row, col)
if cell.is_finish():
finish = (row, col)
cell_row.append(cell)
cells.append(cell_row)
if start is None or finish is None:
raise ValueError("maze must have start and finish")
return Maze(cells, start, finish)