我最近一直试图在Haskell中创建一个迷宫求解器,并且我已经设法将一个主要工作的算法拼凑起来。然而,我很遗憾如何确定一个给定的迷宫是否无法解决。
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
协调系统基于每个方块'迷宫每个位置都有可以位于4个边的墙,此信息存储在Maze
数据类型中。
该算法会跟踪它访问过的地点,并存储它可以访问的地点列表,以及从一开始就指向该点的路径。
到目前为止,我试图考虑一个无法解决的迷宫,其条件是如果访问位置的大小与可访问位置相等,则无法继续解决方案(tentative == []
),然后迷宫无法解决。然而,这似乎没有成功。
试图解决以下不可能的迷宫时
+--+--+--+
| | |
+ + +--+
| | |
+ +--+ +
| |
+--+--+--+
Haskell返回" Maze Practical \ Main.lhs:(88,3) - (99,118):函数fastSolveMazeIter"中的非详尽模式而不是预期的错误消息。
答案 0 :(得分:1)
fastSolveMazeIter在其参数列表中包含模式(x:xs)。如果参数为空,会发生什么?