{-# LANGUAGE FlexibleInstances #-} {-# LANGUAGE TypeFamilies #-} module PathFinding.Algorithm where import qualified Data.Map as M import PathFinding.Class import Data.Proxy -- TODO: remove the need to both have pos and neightboors findPath :: (PathFinding carte, pos ~ Pos carte, Ord pos) => pos -> pos -> carte -> [pos] findPath from to carte = dijkstra (mkqueue proxy [from]) M.empty where proxy = proxify carte backtrack currentPos visited = case M.lookup currentPos visited of Nothing -> [] Just next -> let currPos = locate carte next in if currPos == from then [from] else currPos : backtrack currPos visited dijkstra open closed = case dequeue proxy open of Nothing -> error "notFound" Just (curr, next) -> let currPos = locate carte curr in if currPos == to then currPos : backtrack currPos closed else let nbh = filter (\e -> M.notMember (locate carte e) closed) (neighbors carte currPos) in dijkstra (enqueue proxy nbh next) (foldl (\c e -> M.insert (locate carte e) curr c) closed nbh)