2026-rff_mp/YaroslavtsevAS/docs/2-nd-lab/main.py

174 lines
4.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.

import sys
import os
class Tile:
"""Клетка лабиринта"""
def __init__(self, x, y):
self._x = x
self._y = y
self._wall = False
self._entry = False
self._goal = False
@property
def x(self):
return self._x
@property
def y(self):
return self._y
@property
def is_wall(self):
return self._wall
@is_wall.setter
def is_wall(self, value):
self._wall = value
@property
def is_entry(self):
return self._entry
@is_entry.setter
def is_entry(self, value):
self._entry = value
@property
def is_goal(self):
return self._goal
@is_goal.setter
def is_goal(self, value):
self._goal = value
def can_walk(self):
return not self._wall
class Labyrinth:
"""Лабиринт двумерная сетка клеток"""
def __init__(self, width, height):
self._width = width
self._height = height
self._grid = [[Tile(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 tile_at(self, x, y):
if 0 <= x < self._width and 0 <= y < self._height:
return self._grid[y][x]
return None
def configure_tile(self, x, y, kind):
tile = self.tile_at(x, y)
if tile is None:
return
if kind == 'wall':
tile.is_wall = True
elif kind == 'entry':
if self._start:
self._start.is_entry = False
tile.is_entry = True
tile.is_wall = False
self._start = tile
elif kind == 'goal':
if self._exit:
self._exit.is_goal = False
tile.is_goal = True
tile.is_wall = False
self._exit = tile
elif kind == 'floor':
tile.is_wall = False
def neighbours(self, tile):
result = []
for dx, dy in ((0, -1), (0, 1), (-1, 0), (1, 0)):
nx, ny = tile.x + dx, tile.y + dy
nbr = self.tile_at(nx, ny)
if nbr and nbr.can_walk():
result.append(nbr)
return result
class LabyrinthBuilder:
def build(self, filename):
raise NotImplementedError
class TextLabyrinthBuilder(LabyrinthBuilder):
def build(self, filename):
with open(filename, 'r', encoding='utf-8') as f:
raw = [line.rstrip('\n') for line in f]
h = len(raw)
w = max(len(line) for line in raw) if h > 0 else 0
entries = 0
exits = 0
lab = Labyrinth(w, h)
for y, row in enumerate(raw):
for x, ch in enumerate(row):
if ch == '#':
lab.configure_tile(x, y, 'wall')
elif ch == 'S':
lab.configure_tile(x, y, 'entry')
entries += 1
elif ch == 'E':
lab.configure_tile(x, y, 'goal')
exits += 1
else:
lab.configure_tile(x, y, 'floor')
if entries != 1 or exits != 1:
raise ValueError(
f"Лабиринт должен содержать ровно один вход (S) и один выход (E). "
f"Найдено: S={entries}, E={exits}"
)
return lab
def show_labyrinth(lab):
os.system('cls' if os.name == 'nt' else 'clear')
print('=' * (lab.width * 2 + 4))
print(' ЛАБИРИНТ')
print('=' * (lab.width * 2 + 4))
for y in range(lab.height):
print(' ', end='')
for x in range(lab.width):
t = lab.tile_at(x, y)
if t == lab.start:
print('S', end=' ')
elif t == lab.exit:
print('E', end=' ')
elif t.is_wall:
print('#', end=' ')
else:
print('.', end=' ')
print()
print('=' * (lab.width * 2 + 4))
print(' S вход E выход # стена . пол')
if __name__ == '__main__':
if len(sys.argv) < 2:
print("Использование: python main.py <путь к файлу лабиринта>")
sys.exit(1)
maze_file = sys.argv[1]
builder = TextLabyrinthBuilder()
labyrinth = builder.build(maze_file)
show_labyrinth(labyrinth)