65 lines
1.8 KiB
Python
65 lines
1.8 KiB
Python
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()
|