Post-Cancellation, Pre-Nisei Netrunner Rotation
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

59 lines
1.5KB

  1. module Format where
  2. import System.Random
  3. import State
  4. import Timestamp
  5. import Config
  6. currentFormat :: Timestamp -> State
  7. currentFormat t = strictApplyN n nextFormat initialRotation
  8. where
  9. n = t `monthsSince` genesis
  10. nextFormat :: State -> State
  11. nextFormat (p, b, r) = (np, nb, nr)
  12. where
  13. ip = rotateOld p
  14. (np, nr) = (addNewPack . addNewPack) (ip, r)
  15. nb = rotateBox b
  16. legalOutRot :: [OutRot] -> [OutRot]
  17. legalOutRot x = filter (\(Or _ n) -> n == 0) x
  18. updatePackAge :: [OutRot] -> [OutRot]
  19. updatePackAge p = map (\(Or s n) -> (Or s $ max 0 (n-1))) p
  20. setIllegal :: InRot -> OutRot
  21. setIllegal (Ir n) = Or n 3
  22. setLegal :: OutRot -> InRot
  23. setLegal (Or n _) = Ir n
  24. rotateOld :: Pool -> Pool
  25. rotateOld (i, o) = (ni, no)
  26. where
  27. ni = drop 2 i
  28. no = (updatePackAge o) ++ dropped
  29. dropped = map setIllegal (take 2 i)
  30. addNewPack :: (Pool, StdGen) -> (Pool, StdGen)
  31. addNewPack ((i, o), r) = ((ni, no), nr)
  32. where
  33. lp = length $ legalOutRot o
  34. (ip, nr) = randomR (0, lp-1) r
  35. np = (legalOutRot o) !! ip
  36. ni = i ++ [(setLegal np)]
  37. no = filter (\x -> x /= np) o
  38. rotate :: Integer -> [a] -> [a]
  39. rotate n xs = take lxs . drop ((fromIntegral n) `mod` lxs) . cycle $ xs
  40. where
  41. lxs = length xs
  42. rotateBox :: BoxQueue -> BoxQueue
  43. rotateBox (Bq x) = Bq $ rotate 1 x
  44. strictApplyN :: Integer -> (a -> a) -> a -> a
  45. strictApplyN 0 _ x = x
  46. strictApplyN n f x = strictApplyN (n - 1) f $! (f x)