russel-norvig-ai-problems/chapter2/AI/Vacuum/TableLookupAgent.hs

102 lines
2.7 KiB
Haskell
Raw Permalink Normal View History

2011-10-05 19:35:14 +05:30
module AI.Vacuum.TableLookupAgent where
import AI.Vacuum.Cleaner
import AI.Vacuum.Grid
2011-10-04 17:04:22 +05:30
import Control.Monad.State
2011-10-05 19:35:14 +05:30
import Data.Lens.Common
import Data.Maybe (fromJust)
2011-10-04 17:04:22 +05:30
-- Problem 2.6
2011-10-05 19:35:14 +05:30
2011-10-04 17:04:22 +05:30
possiblePerceptsHistories :: [PerceptsHistory]
possiblePerceptsHistories = takeWhile ((<= 9) . length) $
[[]] : [[PhotoSensor]] : concatMap (\s -> [[] : s, [PhotoSensor] : s]) possiblePerceptsHistories
-- 0 -> t
-- 1 -> s
-- t -> 0 -> m | 1 -> X
-- s -> 0 -> t | 1 -> X
-- m -> 0 -> t | 1 -> s
-- X -> X
chooseAction :: PerceptsHistory -> Maybe Action
2011-10-05 19:35:14 +05:30
chooseAction ph =
2011-10-04 17:04:22 +05:30
case ph of
[] -> Just GoForward
[[]] -> Just TurnRight
[[PhotoSensor]] -> Just SuckDirt
(_:ps) ->
2011-10-04 17:04:22 +05:30
case lookup ps perceptsHistoryToActionMap of
Just (Just prevAction) -> chooseAction' ph prevAction
2011-10-05 19:35:14 +05:30
_ -> Nothing
2011-10-04 17:04:22 +05:30
chooseAction' :: PerceptsHistory -> Action -> Maybe Action
chooseAction' ph prevAction
2011-10-05 19:35:14 +05:30
| prevAction == TurnRight || prevAction == TurnLeft =
2011-10-04 17:04:22 +05:30
case head ph of
[] -> Just GoForward
[PhotoSensor] -> Nothing
| prevAction == SuckDirt =
case head ph of
[] -> Just TurnRight
[PhotoSensor] -> Nothing
| prevAction == GoForward =
case head ph of
[] -> Just TurnRight
[PhotoSensor] -> Just SuckDirt
| prevAction == TurnOff = error "Cannot move after turnoff"
2011-10-05 19:35:14 +05:30
2011-10-04 17:04:22 +05:30
perceptsHistoryToActionMap :: [(PerceptsHistory, Maybe Action)]
perceptsHistoryToActionMap =
map (\ph -> (ph, chooseAction ph)) possiblePerceptsHistories
grid1 = gridFromCellList [
2011-10-05 19:35:14 +05:30
Cell (0, 0) Home, Cell (1, 0) Empty,
2011-10-04 17:04:22 +05:30
Cell (0, 1) Empty, Cell (1, 1) Empty
]
grid2 = gridFromCellList [
2011-10-05 19:35:14 +05:30
Cell (0, 0) Home, Cell (1, 0) Dirt,
2011-10-04 17:04:22 +05:30
Cell (0, 1) Empty, Cell (1, 1) Empty
]
grid3 = gridFromCellList [
2011-10-05 19:35:14 +05:30
Cell (0, 0) Home, Cell (1, 0) Empty,
2011-10-04 17:04:22 +05:30
Cell (0, 1) Dirt, Cell (1, 1) Empty
]
grid4 = gridFromCellList [
2011-10-05 19:35:14 +05:30
Cell (0, 0) Home, Cell (1, 0) Empty,
2011-10-04 17:04:22 +05:30
Cell (0, 1) Empty, Cell (1, 1) Dirt
]
grid5 = gridFromCellList [
2011-10-05 19:35:14 +05:30
Cell (0, 0) Home, Cell (1, 0) Dirt,
2011-10-04 17:04:22 +05:30
Cell (0, 1) Dirt, Cell (1, 1) Empty
]
grid6 = gridFromCellList [
2011-10-05 19:35:14 +05:30
Cell (0, 0) Home, Cell (1, 0) Empty,
2011-10-04 17:04:22 +05:30
Cell (0, 1) Dirt, Cell (1, 1) Dirt
]
grid7 = gridFromCellList [
2011-10-05 19:35:14 +05:30
Cell (0, 0) Home, Cell (1, 0) Dirt,
2011-10-04 17:04:22 +05:30
Cell (0, 1) Empty, Cell (1, 1) Dirt
]
runCleaner :: Cleaner -> State Grid Cleaner
2011-10-05 19:35:14 +05:30
runCleaner cleaner = do
case chooseAction $ cleaner^.perceptsHist of
2011-10-04 17:04:22 +05:30
Just action -> do
2011-10-05 19:35:14 +05:30
cleaner' <- doAction action cleaner
if InfraredSensor `elem` (head $ cleaner'^.perceptsHist)
then doAction TurnOff cleaner'
else runCleaner cleaner'
2011-10-04 17:04:22 +05:30
_ -> doAction TurnOff cleaner
2011-10-05 19:35:14 +05:30
2011-10-04 17:04:22 +05:30
simulateOnGrid :: Grid -> (Cleaner, Grid)
2011-10-05 19:35:14 +05:30
simulateOnGrid grid =
2011-10-04 17:04:22 +05:30
runState (runCleaner cleaner) grid
2011-10-05 19:35:14 +05:30
where cleaner = createCleaner (fromJust $ lookupCell (0, 0) grid) East