diff --git a/BorisovMI/lab_2/docs/data/maze.py b/BorisovMI/lab_2/docs/data/maze.py index abe4624..cec87ec 100644 --- a/BorisovMI/lab_2/docs/data/maze.py +++ b/BorisovMI/lab_2/docs/data/maze.py @@ -268,3 +268,192 @@ class MazeSolver: ) return path, stats + +class Observer: + def update(self, event): + pass + +class ConsoleView(Observer): + def render(self, maze, player_position=None, path=None): + """отрисовка""" + os.system('cls' if os.name == 'nt' else 'clear') + + path_set = set(path) if path else set() + + for y in range(maze.height): + for x in range(maze.width): + cell = maze.getCell(x, y) + + if player_position and cell == player_position: + print('P', end='') + elif cell == maze.start: + print('S', end='') + elif cell == maze.exit: + print('E', end='') + elif cell in path_set: + print('.', end='') + elif cell.isWall: + print('#', end='') + else: + print(' ', end='') + print() + + def update(self, event): + if event['type'] == 'path_found': + print(f"длина пути {len(event['path'])}") + self.render(event['maze'], path=event['path']) + elif event['type'] == 'move': + print(f"шаг {event['step']}") + self.render(event['maze'], event['player'], event['path']) + elif event['type'] == 'maze_loaded': + print("перегрузка") + self.render(event['maze']) + + +class ObservableMazeSolver: + def __init__(self, maze): + self.maze = maze + self.strategy = None + self.observers = [] + + def attach(self, observer): + self.observers.append(observer) + + def notify(self, event): + for observer in self.observers: + observer.update(event) + + def setStrategy(self, strategy): + self.strategy = strategy + + def solve(self): + if self.strategy is None: + raise ValueError("") + + + path = self.strategy.findPath(self.maze, self.maze.start, self.maze.exit) + + self.notify({ + 'type': 'path_found', + 'maze': self.maze, + 'path': path + }) + + return path + +class Player: + def __init__(self, start_cell): + self.currentCell = start_cell + self.previousCell = None + + def moveTo(self, cell): + self.previousCell = self.currentCell + self.currentCell = cell + + def undoMove(self): + if self.previousCell: + self.currentCell, self.previousCell = self.previousCell, None + return True + return False + + +class Command: + def execute(self): + pass + + def undo(self): + pass + +class MoveCommand(Command): + def __init__(self, player, direction, maze): + self.player = player + self.dx, self.dy = direction + self.maze = maze + self.executed = False + + def execute(self): + new_x = self.player.currentCell.x + self.dx + new_y = self.player.currentCell.y + self.dy + new_cell = self.maze.getCell(new_x, new_y) + + if new_cell and new_cell.isPassable(): + self.player.moveTo(new_cell) + self.executed = True + return True + return False + + def undo(self): + if self.executed: + self.player.undoMove() + self.executed = False + return True + return False + +def clear_console(): + os.system('cls' if os.name == 'nt' else 'clear') + +def render_maze_with_player(maze, player, path=None): + path_set = set(path) if path else set() + + for y in range(maze.height): + for x in range(maze.width): + cell = maze.getCell(x, y) + + if cell == player.currentCell: + print('P', end='') + elif cell == maze.start: + print('S', end='') + elif cell == maze.exit: + print('E', end='') + elif cell in path_set: + print('.', end='') + elif cell.isWall: + print('#', end='') + else: + print(' ', end='') + print() + + +def run_game(maze, path=None): + player = Player(maze.start) + history = [] + + directions = { + 'w': (0, -1), + 's': (0, 1), + 'a': (-1, 0), + 'd': (1, 0) + } + + print(" W/A/S/D - движение, U - отмена, Q - выход") + if path: + print(f"мин путь {len(path)} шагов") + + while True: + print() + render_maze_with_player(maze, player, path) + + if player.currentCell == maze.exit: + print("\n*** выход ***") + break + + key = input("\n> ").lower() + + if key == 'q': + print("выход из игры") + break + elif key == 'u': + if history: + cmd = history.pop() + cmd.undo() + print("отмена хода") + else: + print("нет ходов") + elif key in directions: + cmd = MoveCommand(player, directions[key], maze) + if cmd.execute(): + history.append(cmd) + else: + print("стена") + else: + print("неизвестно")