from __future__ import annotations import tempfile import unittest from pathlib import Path from maze_solver import ( AStarStrategy, BFSStrategy, Direction, MazeSolver, MoveCommand, Player, TextFileMazeBuilder, ) SIMPLE_MAZE = """\ ####### #S E# # ### # # # #######""" class MazeSolverTest(unittest.TestCase): def build_maze(self): with tempfile.TemporaryDirectory() as directory: path = Path(directory) / "maze.txt" path.write_text(SIMPLE_MAZE, encoding="utf-8") return TextFileMazeBuilder().build_from_file(path) def test_builder_reads_start_exit_and_neighbors(self) -> None: maze = self.build_maze() self.assertEqual((maze.start.x, maze.start.y), (1, 1)) self.assertEqual((maze.exit.x, maze.exit.y), (5, 1)) self.assertTrue(maze.get_cell(2, 1).is_passable()) self.assertFalse(maze.get_cell(0, 0).is_passable()) def test_bfs_and_astar_find_shortest_path(self) -> None: maze = self.build_maze() bfs_stats = MazeSolver(maze, BFSStrategy()).solve() astar_stats = MazeSolver(maze, AStarStrategy()).solve() self.assertEqual(bfs_stats.path_length, 5) self.assertEqual(astar_stats.path_length, 5) self.assertEqual(bfs_stats.path[0], maze.start) self.assertEqual(bfs_stats.path[-1], maze.exit) def test_move_command_can_execute_and_undo(self) -> None: maze = self.build_maze() player = Player.at_start(maze) command = MoveCommand(player, Direction.RIGHT) self.assertTrue(command.execute()) self.assertEqual((player.current_cell.x, player.current_cell.y), (2, 1)) self.assertTrue(command.undo()) self.assertEqual(player.current_cell, maze.start) if __name__ == "__main__": unittest.main()