| otherwise = world { robot = there }
where there = world.robot ^+^ dir
movedBox = bigBoxActual world.boxes there
- rWorld = do boxMoves <- moveBigBoxes world dir movedBox
- let froms = fmap fst boxMoves
- let tos = fmap snd boxMoves
- let boxes' = (S.fromList tos) `S.union` (world.boxes `S.difference` (S.fromList froms))
- let world' = world { boxes = boxes' }
- return world' { robot = there }
-
+ rWorld =
+ do boxMoves <- moveBigBoxes world dir movedBox
+ let froms = S.fromList $ fmap fst boxMoves
+ let tos = S.fromList $ fmap snd boxMoves
+ let boxes' = S.union tos (world.boxes `S.difference` froms)
+ return world { boxes = boxes', robot = there }
moveBigBoxes :: World -> Position -> Position -> Maybe [Move]
moveBigBoxes world dir box
| any (\t -> t `S.member` world.walls) there = Nothing
| any (\t -> t `isBigBox` world.boxes) there = allMoves
- | otherwise = Just $ [ thisMove ]
+ | otherwise = Just [ thisMove ]
where there = case dir of
U -> [box ^+^ U, box ^+^ R ^+^ U]
D -> [box ^+^ D, box ^+^ R ^+^ D]
R -> [box ^+^ R ^+^ R]
_ -> []
thisMove = (box, box ^+^ dir)
- allMoves = do let there' = nub $ fmap (bigBoxActual world.boxes) $ filter (\t -> t `isBigBox` world.boxes) there
+ allMoves = do let there' = nub $ fmap (bigBoxActual world.boxes)
+ $ filter (\t -> t `isBigBox` world.boxes) there
moves <- traverse (moveBigBoxes world dir) there'
let moves' = concat moves
return $ thisMove : moves'