-openValveSuccessor here opened
- | here `S.member` opened = return []
- | otherwise = return [(here, S.insert here opened)]
-
-walkSuccessor here opened =
- do cave <- asks getCave
- let neighbours = (cave ! here) ^. tunnels
- return [(n, opened) | n <- neighbours]
+agentSuccessor :: Int -> S.Set RoomID -> Int -> RoomID -> CaveContext [SingleSearchState]
+agentSuccessor now opened aTime here
+ | aTime /= now = return [SingleSearchState { _currentRoom = here, _currentTime = aTime, _sOpenValves = opened }]
+ | otherwise =
+ do cave <- asks getCave
+ timeLimit <- asks getTimeLimit
+ let remaining = S.toList $ S.filter (\t -> (t ^. tunnelTo) `S.notMember` opened) ((cave ! here) ^. tunnels)
+ let moves = [ SingleSearchState
+ { _currentRoom = (t ^. tunnelTo)
+ , _currentTime = now + (t ^. tunnelLength)
+ , _sOpenValves = opened
+ }
+ | t <- remaining
+ , now + (t ^. tunnelLength) <= timeLimit
+ ]
+ let opens = if here `S.notMember` opened && (cave ! here) ^. flowRate > 0
+ then [SingleSearchState { _currentRoom = here, _currentTime = aTime + 1, _sOpenValves = S.insert here opened }]
+ else []
+ -- let nexts = moves ++ opens
+ let nexts = if null opens then moves else opens
+ let nexts' = if null nexts
+ then [ SingleSearchState
+ { _currentRoom = here
+ , _currentTime = timeLimit
+ , _sOpenValves = opened
+ } ]
+ else nexts
+ return nexts'