2021-12-20 15:23:12 -05:00
|
|
|
{-# LANGUAGE ScopedTypeVariables #-}
|
|
|
|
{-# LANGUAGE TypeApplications #-}
|
|
|
|
|
|
|
|
module GOL.Engine where
|
|
|
|
|
|
|
|
import Control.Comonad.Env
|
|
|
|
import Control.Comonad.Representable.Store
|
|
|
|
import Data.Bool (bool)
|
|
|
|
import GOL.Rule
|
|
|
|
import GOL.Space
|
|
|
|
|
|
|
|
type GOL f = EnvT Rule (Store f)
|
|
|
|
|
2021-12-20 15:28:11 -05:00
|
|
|
getNeighbors :: forall f a. Space f => GOL f a -> [a]
|
|
|
|
getNeighbors = experiment $ neighbors @f
|
2021-12-20 15:26:18 -05:00
|
|
|
|
2021-12-20 15:28:11 -05:00
|
|
|
nextState :: Space f => GOL f Bool -> Bool
|
2021-12-20 15:26:18 -05:00
|
|
|
nextState = do
|
|
|
|
selfState <- extract
|
|
|
|
neighborStates <- getNeighbors
|
|
|
|
let count = sum . fmap (bool 0 1) $ neighborStates
|
|
|
|
|
|
|
|
Rule survive birth <- ask
|
|
|
|
return $ if selfState
|
|
|
|
then survive count
|
|
|
|
else birth count
|
|
|
|
|
|
|
|
|
2021-12-20 15:28:11 -05:00
|
|
|
tick :: Space f => GOL f Bool -> GOL f Bool
|
2021-12-20 15:26:18 -05:00
|
|
|
tick = extend nextState
|