classDiagram

    class Cell{
        +tuple coords
        +bool isWall
        +bool isStart
        +bool isExit
        +isPassable(): bool
    }

    class Maze{
        +np.array cells
        +int width
        +int height
        +Cell st
        +Cell ex
        +getCell(x,y): Cell
        +getNeighbors(cell): List~Cell~
    }

    class MazeBuilder{
        <<interface>>
        +buildFromFile(filename): Maze
    }

    class TextFileMazeBuilder{
        +buildFromFile(filename): Maze
    }

    MazeBuilder <|.. TextFileMazeBuilder

    class PathFindingStrategy{
        <<interface>>
        +findPath(maze,st,ex): list~Cell~
    }

    class BFS{
        +set~tuple~ visited
        +findPath(maze,st,ex): list~Cell~
    }

    class DFS{
        +set~tuple~ visited
        +findPath(maze,st,ex): list~Cell~
    }

    class Astar{
        +dict~tuple, int~
        +set~tuple~ visited
        +findPath(maze,st,ex): list~Cell~
    }

    PathFindingStrategy <|.. BFS
    PathFindingStrategy <|.. DFS
    PathFindingStrategy <|.. Astar

    class SearchStats{
        +float timeMs
        +int visitedCells
        +int pathLength
    }

    class MazeSolver{
        +Maze maze
        +PathFindingStrategy strategy
        +list~ConsoleView~ observers
        +setStrategy(strategy)
        +solve(): SearchStats
    }

    class MazeEvent{
        +string event_type
        +Maze maze
        +tuple player_position
        +list~tuple~ path 
    }

    class Observer{
        <<interface>>
        +update(event)
    }

    class ConsoleView{
        +Maze maze
        +tuple player_position
        +list~tuple~ path
        +update(event)
        +render(maze,player_position,path)
    }

    class Command{
        <<interface>>
        +execute()
        +undo()
    }

    class MoveCommand{
        +tuple previousCell
        +execute(player,direction)
        +undo(player)
    }

    Command <|.. MoveCommand

    class Player{
        +tuple currentCell
        +moveTo(cell)
    }

    class Direction{
        +tuple dir
    }

    MazeSolver --> PathFindingStrategy: uses
    MazeBuilder --> Maze: creates
    Maze --> Cell: contains
    ConsoleView ..|> Observer
    MazeSolver --> Observer: notifies
    MazeSolver --> MazeEvent: creates
    Observer --> MazeEvent: accepts
    MoveCommand --> Player: moves
    MoveCommand --> Direction: uses
    ConsoleView --> Player: accepts position
    ConsoleView --> Maze: renders
    MazeSolver --> SearchStats: returns
    MazeSolver --> Maze: accepts
    MazeEvent --> Player: stores position
    Player --> Cell: saves coords