95 lines
2.3 KiB
Python
95 lines
2.3 KiB
Python
from __future__ import annotations
|
|
|
|
import argparse
|
|
|
|
from maze_solver import (
|
|
AStarStrategy,
|
|
BFSStrategy,
|
|
ConsoleView,
|
|
DFSStrategy,
|
|
DijkstraStrategy,
|
|
Direction,
|
|
MazeSolver,
|
|
MoveCommand,
|
|
Player,
|
|
TextFileMazeBuilder,
|
|
)
|
|
|
|
|
|
STRATEGIES = {
|
|
"bfs": BFSStrategy,
|
|
"dfs": DFSStrategy,
|
|
"astar": AStarStrategy,
|
|
"dijkstra": DijkstraStrategy,
|
|
}
|
|
|
|
|
|
def main() -> None:
|
|
parser = argparse.ArgumentParser(description="Find a path through a text maze.")
|
|
parser.add_argument("--maze", default="data/mazes/small.txt")
|
|
parser.add_argument(
|
|
"--strategy",
|
|
choices=sorted(STRATEGIES),
|
|
default="astar",
|
|
help="Path-finding algorithm.",
|
|
)
|
|
parser.add_argument("--render", action="store_true", help="Print maze with path.")
|
|
parser.add_argument(
|
|
"--manual",
|
|
action="store_true",
|
|
help="Manual W/A/S/D mode with Z undo and Q quit.",
|
|
)
|
|
args = parser.parse_args()
|
|
|
|
maze = TextFileMazeBuilder().build_from_file(args.maze)
|
|
strategy = STRATEGIES[args.strategy]()
|
|
solver = MazeSolver(maze, strategy)
|
|
view = ConsoleView()
|
|
solver.add_observer(view)
|
|
|
|
stats = solver.solve()
|
|
print(
|
|
f"Summary: strategy={stats.strategy_name}, time={stats.time_ms:.3f} ms, "
|
|
f"visited={stats.visited_cells}, path_length={stats.path_length}"
|
|
)
|
|
|
|
if args.render:
|
|
print(view.render(maze, path=stats.path))
|
|
|
|
if args.manual:
|
|
run_manual_mode(maze, view)
|
|
|
|
|
|
def run_manual_mode(maze, view: ConsoleView) -> None:
|
|
player = Player.at_start(maze)
|
|
history: list[MoveCommand] = []
|
|
|
|
while True:
|
|
print(view.render(maze, player_position=player.current_cell))
|
|
if player.current_cell == maze.exit:
|
|
print("Exit reached.")
|
|
return
|
|
|
|
key = input("Move W/A/S/D, undo Z, quit Q: ").strip().lower()
|
|
if key == "q":
|
|
return
|
|
if key == "z":
|
|
if history:
|
|
history.pop().undo()
|
|
continue
|
|
|
|
try:
|
|
command = MoveCommand(player, Direction.from_key(key))
|
|
except ValueError as exc:
|
|
print(exc)
|
|
continue
|
|
|
|
if command.execute():
|
|
history.append(command)
|
|
else:
|
|
print("Move blocked.")
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|