[2] start lab2 and add main.py

This commit is contained in:
YaroslavtsevAS 2026-05-24 15:32:34 +00:00
parent 473003b4ce
commit 3032b5283b

View File

@ -0,0 +1,174 @@
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)