Reputation: 432
I have been recently trying to create a maze-solver in Haskell and I have managed to piece together a mostly working algorithm. However I am lost as to how to determine if a given maze is impossible to solve.
solveMazeQuickly :: Maze -> Place -> Place -> Path
solveMazeQuickly maze start target = fastSolveMazeIter maze target [(start, [])] [start] -- last is the elem of visited nodes along with its paths
fastSolveMazeIter :: Maze -> Place -> [(Place, Path)] -> [Place] -> Path
fastSolveMazeIter maze target (x:xs) visited -- last argument is the list of visited places
| (tenatives == []) && (length (x:xs) == length (visited)) = error "unsolvable maze"
| currentPos == target = pathPos -- return the path if we're already there
| otherwise = fastSolveMazeIter maze target (xs++tenatives) (visited++(map fst tenatives))
where currentPos = fst x -- current position
pathPos = snd x -- the path to current position
tenatives = scan currentPos pathPos -- the 'successful' tried paths
try pos curPath d
| ((hasWall maze pos d) == False) && ((nextPos `elem` visited) == False) = [(nextPos, curPath++[d])] -- disregard visited positions
| otherwise = []
where nextPos = move d pos
scan pos curPath = (try pos curPath N) ++ (try pos curPath S) ++ (try pos curPath E) ++ (try pos curPath W) -- try the four directions
The co-ordinate system is based on each 'squares' of the maze. Each position has walls that can be on its 4 sides, and this information is stored inside the Maze
datatype.
The algorithm keeps track of the places that it has visited, as well as storing a list of the places that it can access, together with the path to that point from the start.
Thus far, I have attempted to take into account for an unsolvable maze with a condition that if the visited positions are equal in size to the accessible positions, with no possible way to continue the solution (tentative == []
), then the maze is unsolvable. However that does not seem to do the trick.
When attempting to solve the following impossible maze
+--+--+--+
| | |
+ + +--+
| | |
+ +--+ +
| |
+--+--+--+
Haskell returns "Maze Practical\Main.lhs:(88,3)-(99,118): Non-exhaustive patterns in function fastSolveMazeIter" instead of the intended error message.
Upvotes: 3
Views: 743
Reputation: 17786
fastSolveMazeIter includes the pattern (x:xs) in its argument list. What should happen if the argument is empty?
Upvotes: 1