aboutsummaryrefslogtreecommitdiff
path: root/server/lib/Cafp/InfiniteDeck.hs
diff options
context:
space:
mode:
authorJasper Van der Jeugt2020-07-31 19:39:40 +0200
committerJasper Van der Jeugt2020-07-31 19:39:40 +0200
commit5a1586d0a5745da547254558e8f1de8e2a94c469 (patch)
tree27922c8fe5357548c8a867b1087b4d0989beeac1 /server/lib/Cafp/InfiniteDeck.hs
parente3a2052522471d39e410f4ea13d51d3d18f52b80 (diff)
Shuffling
Diffstat (limited to 'server/lib/Cafp/InfiniteDeck.hs')
-rw-r--r--server/lib/Cafp/InfiniteDeck.hs36
1 files changed, 36 insertions, 0 deletions
diff --git a/server/lib/Cafp/InfiniteDeck.hs b/server/lib/Cafp/InfiniteDeck.hs
new file mode 100644
index 0000000..8772011
--- /dev/null
+++ b/server/lib/Cafp/InfiniteDeck.hs
@@ -0,0 +1,36 @@
+module Cafp.InfiniteDeck
+ ( InfiniteDeck
+ , new
+ , newIO
+ , pop
+ , popN
+ ) where
+
+import Data.List (intercalate)
+import qualified Data.Vector as V
+import System.Random (StdGen, newStdGen)
+import VectorShuffling.Immutable (shuffle)
+
+newtype InfiniteDeck a = InfiniteDeck [a]
+
+instance Show a => Show (InfiniteDeck a) where
+ show (InfiniteDeck xs) =
+ "[" ++ intercalate ", " (map show $ take 5 xs) ++ "...]"
+
+new :: V.Vector a -> StdGen -> InfiniteDeck a
+new vec gen0
+ | V.null vec = error "Cafp.InfiniteDeck.new: empty vector"
+ | otherwise = InfiniteDeck (V.toList x ++ xs)
+ where
+ (x, gen1) = shuffle vec gen0
+ InfiniteDeck xs = new vec gen1
+
+newIO :: V.Vector a -> IO (InfiniteDeck a)
+newIO vec = new vec <$> newStdGen
+
+pop :: InfiniteDeck a -> (a, InfiniteDeck a)
+pop (InfiniteDeck []) = error "Cafp.InfiniteDeck.pop: empty"
+pop (InfiniteDeck (x : xs)) = (x, InfiniteDeck xs)
+
+popN :: Int -> InfiniteDeck a -> ([a], InfiniteDeck a)
+popN n (InfiniteDeck xs) = let (ys, zs) = splitAt n xs in (ys, InfiniteDeck zs)