p7/Format.hs

59 lines
1.5 KiB
Haskell
Raw Normal View History

2018-06-24 17:26:43 -04:00
module Format where
2018-06-24 19:21:29 -04:00
import System.Random
import State
import Timestamp
import Config
currentFormat :: Timestamp -> State
currentFormat t = strictApplyN n nextFormat initialRotation
where
n = t `monthsSince` genesis
2018-06-24 17:26:43 -04:00
nextFormat :: State -> State
nextFormat (p, b, r) = (np, nb, nr)
where
ip = rotateOld p
2018-06-24 19:21:29 -04:00
(np, nr) = (addNewPack . addNewPack) (ip, r)
2018-06-24 17:26:43 -04:00
nb = rotateBox b
legalOutRot :: [OutRot] -> [OutRot]
legalOutRot x = filter (\(Or _ n) -> n == 0) x
updatePackAge :: [OutRot] -> [OutRot]
2018-06-24 19:21:29 -04:00
updatePackAge p = map (\(Or s n) -> (Or s $ max 0 (n-1))) p
2018-06-24 17:26:43 -04:00
setIllegal :: InRot -> OutRot
setIllegal (Ir n) = Or n 3
setLegal :: OutRot -> InRot
setLegal (Or n _) = Ir n
rotateOld :: Pool -> Pool
rotateOld (i, o) = (ni, no)
where
ni = drop 2 i
2018-06-24 19:21:29 -04:00
no = (updatePackAge o) ++ dropped
2018-06-24 17:26:43 -04:00
dropped = map setIllegal (take 2 i)
addNewPack :: (Pool, StdGen) -> (Pool, StdGen)
addNewPack ((i, o), r) = ((ni, no), nr)
where
lp = length $ legalOutRot o
(ip, nr) = randomR (0, lp-1) r
np = (legalOutRot o) !! ip
2018-06-24 19:21:29 -04:00
ni = i ++ [(setLegal np)]
2018-06-24 17:26:43 -04:00
no = filter (\x -> x /= np) o
rotate :: Integer -> [a] -> [a]
2018-06-24 19:21:29 -04:00
rotate n xs = take lxs . drop ((fromIntegral n) `mod` lxs) . cycle $ xs
where
lxs = length xs
2018-06-24 17:26:43 -04:00
rotateBox :: BoxQueue -> BoxQueue
rotateBox (Bq x) = Bq $ rotate 1 x
strictApplyN :: Integer -> (a -> a) -> a -> a
strictApplyN 0 _ x = x
strictApplyN n f x = strictApplyN (n - 1) f $! (f x)