[2] start lab2 and add main.py
This commit is contained in:
parent
473003b4ce
commit
3032b5283b
174
YaroslavtsevAS/docs/2-nd-lab/main.py
Normal file
174
YaroslavtsevAS/docs/2-nd-lab/main.py
Normal 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)
|
||||
Loading…
Reference in New Issue
Block a user