-instance Eq Explorer where
- e1 == e2 = (_position e1 == _position e2) && (_keysHeld e1 == _keysHeld e2)
-
-instance Ord Explorer where
- e1 `compare` e2 =
- if _position e1 == _position e2
- then (_keysHeld e1) `compare` (_keysHeld e2)
- else (_position e1) `compare` (_position e2)
-
-
- -- positionE :: e -> Position
- -- keysHeldE :: e -> Keys
-
-successors :: Explorer -> CaveContext (Q.Seq Explorer)
-successors explorer = -- return Q.empty
- do let heres = explorer ^. position
- cavern <- asks _cave
- let kH = explorer ^. keysHeld
- let locations0 = M.filterWithKey (\k _ds -> anyEdgeTouch heres k) cavern
- let locations1 = M.filter (\e -> S.null ((e ^. keysRequired) `S.difference` kH)) locations0
- let succs = M.foldrWithKey' (\k e q -> (extendExplorer explorer k e) <| q) Q.empty locations1
- return succs
-
-estimateCost :: Explorer -> CaveContext Int
-estimateCost explorer = -- return 0
- do let heres = explorer ^. position
- ks <- asks _keys
- cavern <- asks _cave
- let kH = explorer ^. keysHeld
- let unfound = ks `S.difference` kH
- let unfoundEdges0 = M.filterWithKey (\k _ -> anyEdgeTouch heres k) cavern
- let unfoundEdges = M.filterWithKey (\k _ -> not $ anyEdgeTouch kH k) unfoundEdges0
- let furthest = maximum $ (0:) $ map _distance $ M.elems unfoundEdges
- return $ max 0 $ furthest + (S.size unfound) - 1
-
-emptyExplorer :: S.Set Char -> Explorer
-emptyExplorer ps = Explorer { _position = ps, _keysHeld = S.empty, _travelled = 0 }
-
-extendExplorer :: Explorer -> EdgeKey -> CaveEdge -> Explorer
-extendExplorer explorer edgeKey edge =
- explorer & position .~ pos'
- & keysHeld .~ kH'
- & travelled .~ d'
- where here = S.findMin $ S.filter (\p -> edgeTouches p edgeKey) (explorer ^. position)
- there = edgeOther here edgeKey
- kH' = S.insert there (explorer ^. keysHeld)
- d' = (explorer ^. travelled) + (edge ^. distance)
- pos' = S.insert there $ S.delete here (explorer ^. position)
-
-