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

84 lines
2.4 KiB
Haskell
Raw Normal View History

module AI.Vacuum.ReflexAgent (simulateOnGrid, printSimulation) where
2011-10-05 19:35:14 +05:30
import AI.Vacuum.Cleaner
import AI.Vacuum.Grid
2011-10-05 11:18:20 +05:30
import AI.Vacuum.RandomGrid
2011-10-05 19:35:14 +05:30
import Data.Lens.Common
2011-10-05 11:18:20 +05:30
import Control.Monad.State
import System.Random
2011-10-06 20:52:52 +05:30
import System (getArgs)
import Data.Maybe (fromJust)
2011-10-05 11:18:20 +05:30
chooseAction :: Percepts -> RandomState Action
chooseAction percepts
| PhotoSensor `elem` percepts = return SuckDirt
| InfraredSensor `elem` percepts = return TurnOff
| TouchSensor `elem` percepts = do
r <- getRandomR (True, False)
if r
then return TurnLeft
else return TurnRight
| otherwise = do
r <- getRandomR ((0.0, 1.0) :: (Float, Float))
chooseRandom r
where
chooseRandom r
| r < 0.1 = return TurnRight
| r < 0.2 = return TurnLeft
| otherwise = return GoForward
runCleaner :: Int -> Cleaner -> StateT Grid RandomState Cleaner
2011-10-05 19:35:14 +05:30
runCleaner turnsLeft cleaner =
2011-10-05 11:18:20 +05:30
if turnsLeft == 1
then do
cleaner' <- doAction TurnOff cleaner
return cleaner'
else do
2011-10-05 19:35:14 +05:30
let ph = cleaner^.perceptsHist
cleaner' <- case ph of
[] -> doAction GoForward cleaner
2011-10-05 11:18:20 +05:30
_ -> do
action <- lift $ chooseAction (head ph)
doAction action cleaner
case cleaner'^.state of
Off -> return cleaner'
On -> runCleaner (turnsLeft - 1) cleaner'
2011-10-05 11:18:20 +05:30
simulateOnGrid :: Int -> Grid -> StdGen -> (Cleaner, Grid)
simulateOnGrid maxTurns grid gen =
evalState (runStateT (runCleaner maxTurns cleaner) grid) gen
2011-10-05 19:35:14 +05:30
where cleaner = createCleaner (fromJust $ lookupCell (0,0) grid) East
printSimulation :: Int -> Int -> Int -> Float -> Bool -> IO ()
printSimulation
minSize maxSize maxTurns dirtProb toPrintGrid = do
gen <- newStdGen
let grid = evalState
(makeRandomGrid (minSize,maxSize) (minSize,maxSize) dirtProb 0.0)
gen
when toPrintGrid $ do
putStrLn "Grid before traversal"
printGrid grid
putStrLn ""
let (cleaner, grid') = simulateOnGrid maxTurns grid gen
when toPrintGrid $ do
putStrLn "Grid after traversal"
printPath cleaner grid'
putStrLn ""
2011-10-06 20:52:52 +05:30
printRunStats cleaner grid
main :: IO ()
main = do
args <- getArgs
let minSize = (read $ args !! 0) :: Int
let maxSize = (read $ args !! 1) :: Int
let dirtProb = (read $ args !! 2) :: Float
let maxTurns = (read $ args !! 3) :: Int
let toPrintGrid = (read $ args !! 4) :: Bool
printSimulation minSize maxSize maxTurns dirtProb toPrintGrid