-- Copyright (c) 2014-2015 Jonathan M. Lange -- -- Licensed under the Apache License, Version 2.0 (the "License"); -- you may not use this file except in compliance with the License. -- You may obtain a copy of the License at -- -- http://www.apache.org/licenses/LICENSE-2.0 -- -- Unless required by applicable law or agreed to in writing, software -- distributed under the License is distributed on an "AS IS" BASIS, -- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -- See the License for the specific language governing permissions and -- limitations under the License. {-# LANGUAGE DeriveTraversable #-} {-# LANGUAGE NoImplicitPrelude #-} module Haverer.PlayerSet ( PlayerSet , PlayerSetError(..) , toPlayerSet , toPlayers , randomize , rotate ) where import BasicPrelude import Control.Monad.Except import Control.Monad.Random import Data.Foldable (Foldable) import Data.Traversable (Traversable) import System.Random.Shuffle data PlayerSetError a = InvalidNumPlayers Int | DuplicatePlayers [a] deriving (Show, Eq) newtype PlayerSet a = PlayerSet { toPlayers :: [a] } deriving (Show, Eq, Functor, Traversable, Foldable) toPlayerSet :: Ord a => [a] -> Either (PlayerSetError a) (PlayerSet a) toPlayerSet playerIds | numPlayers /= numDistinctPlayers = throwError (DuplicatePlayers playerIds) | numPlayers < 2 || numPlayers > 4 = throwError (InvalidNumPlayers numPlayers) | otherwise = (return . PlayerSet) playerIds where numPlayers = length playerIds numDistinctPlayers = (length . nub . sort) playerIds -- | Rotate the order of the PlayerSet -- -- The player who was first is now last, whoever was second is now third, -- whoever was third is now second, etc. -- -- Since 0.3 rotate :: PlayerSet a -> PlayerSet a rotate (PlayerSet (x:xs)) = PlayerSet (xs ++ [x]) rotate _ = error "Empty PlayerSet is impossible" -- | Randomize the order of the PlayerSet -- -- Since 0.3 randomize :: MonadRandom m => PlayerSet a -> m (PlayerSet a) randomize = map PlayerSet . shuffleM . toPlayers