84 lines
2.4 KiB
Haskell
84 lines
2.4 KiB
Haskell
module AI.Vacuum.ReflexAgent (simulateOnGrid, printSimulation) where
|
|
|
|
import AI.Vacuum.Cleaner
|
|
import AI.Vacuum.Grid
|
|
import AI.Vacuum.RandomGrid
|
|
import Data.Lens.Common
|
|
import Control.Monad.State
|
|
import System.Random
|
|
import System (getArgs)
|
|
import Data.Maybe (fromJust)
|
|
|
|
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
|
|
runCleaner turnsLeft cleaner =
|
|
if turnsLeft == 1
|
|
then do
|
|
cleaner' <- doAction TurnOff cleaner
|
|
return cleaner'
|
|
else do
|
|
let ph = cleaner^.perceptsHist
|
|
cleaner' <- case ph of
|
|
[] -> doAction GoForward cleaner
|
|
_ -> do
|
|
action <- lift $ chooseAction (head ph)
|
|
doAction action cleaner
|
|
case cleaner'^.state of
|
|
Off -> return cleaner'
|
|
On -> runCleaner (turnsLeft - 1) cleaner'
|
|
|
|
simulateOnGrid :: Int -> Grid -> StdGen -> (Cleaner, Grid)
|
|
simulateOnGrid maxTurns grid gen =
|
|
evalState (runStateT (runCleaner maxTurns cleaner) grid) gen
|
|
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 ""
|
|
|
|
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
|