我想解决“AI - 一种现代方法”的书中涉及网格单元格,并选择随机移动浏览网格的问题2.8。运行状态内状态一元功能不工作
2.7实施为一个N×M的矩形室,其中每个正方形 具有含有污垢的5%的机会的环境中,和n和m是在 随机选自范围为8〜15,包括端值。
2.8设计并实现一个纯反射代理环境 练习2.7,忽略返回家的要求,并测量其性能 。
所以我用了两个状态单元 - 一个用Grid
作为状态,另一个用StdGen
作为状态。代码编译没有任何错误,但是当我从GHCi运行它时,它会卡住并且不会返回。
代码的相关部分:
支持代码
type RandomState = State StdGen
makeGrid :: (Int, Int) -> (Int, Int) -> Float -> RandomState Grid
doAction :: Action -> Cleaner -> State Grid Cleaner
getRandomR :: Random a => (a, a) -> RandomState a
getRandomR limits = do
gen <- get
let (val, gen') = randomR limits gen
put gen'
return val
chooseAction :: Percepts -> RandomState Action
chooseAction percepts
| PhotoSensor `elem` percepts = return SuckDirt
| InfraredSensor `elem` percepts = return TurnOff
| TouchSensor `elem` percepts = return TurnLeft
| otherwise = do
r <- getRandomR ((1, 3) :: (Int, Int))
case r of
1 -> return GoForward
2 -> return TurnRight
3 -> return TurnLeft
主代码
runCleaner :: Int -> Cleaner -> StateT Grid RandomState Cleaner
runCleaner turnsLeft [email protected](Cleaner _ _ _ ph _) =
if turnsLeft == 0
then return cleaner
else do
grid <- get
gen <- lift $ get
cleaner <- case ph of
[] -> do
let (cleaner, grid) = runState (doAction GoForward cleaner) grid
put grid
return cleaner
_ -> do
let (action, gen) = runState (chooseAction (head ph)) gen
lift $ put gen
let (cleaner, grid) = runState (doAction action cleaner) grid
put grid
return cleaner
case clState cleaner 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 $ cell (0,0) grid) East
我调用simulateOnGrid
功能从GHCI这样的:
> gen <- newStdGen
> let grid = evalState (makeGrid (8,15) (8,15) 0.05) gen
> simulateOnGrid 5 grid gen
和代码卡在该行:
let (cleaner, grid) = runState (doAction GoForward cleaner) grid
我已经通过把痕迹,代码确认。对doAction
函数的调用永远不会发生。
这个问题似乎是runCleaner
函数中runState
的使用,但是我找不到任何理由。
请说明原因以及是否有办法解决此问题。
另外,使用runState
里面的monadic函数对我来说感觉不对。请建议是否有更好的方法来做到这一点。