from abc import ABC, abstractmethod

class Observer(ABC):

    @abstractmethod
    def update(self, event):
        pass

class ConsoleView(Observer):

    def update(self, event):
        print(f"\n[Событие] {event}")

    def render(self, maze, player=None, path=None):

        path = path or []

        print()

        for row in maze.cells:

            line = ""

            for cell in row:

                if player and cell == player.position:
                    line += "P"

                elif cell.isStart:
                    line += "S"

                elif cell.isExit:
                    line += "E"

                elif cell.isWall:
                    line += "#"

                elif cell in path:
                    line += "*"

                else:
                    line += " "

            print(line)


class Command(ABC):
    @abstractmethod
    def execute(self):
        pass
    @abstractmethod
    def undo(self):
        pass

class Player:
    def __init__(self, start_cell):
        self.position = start_cell

class MoveCommand(Command):
    def __init__(self, player, new_cell):
        self.player = player
        self.new_cell = new_cell
        self.old_cell = None
    def execute(self):
        self.old_cell = self.player.position
        self.player.position = self.new_cell
    def undo(self):
        self.player.position = self.old_cell