{-# LANGUAGE DeriveFunctor #-} module Game.TurnCounter ( TurnCounter (..) , newTurnCounter , nextTurn, nextTurnWith , previousTurn, previousTurnWith , currentPlayer , nextPlayer , previousPlayer , currentRound ) where import Data.List (find) data TurnCounter p = TurnCounter { tcPlayers :: [p] , tcCounter :: Int } deriving (Eq, Show, Functor) newTurnCounter :: [p] -> TurnCounter p newTurnCounter players = TurnCounter { tcPlayers = players , tcCounter = 0 } nextTurn :: TurnCounter p -> TurnCounter p nextTurn (TurnCounter ps c) = TurnCounter ps (c+1) nextTurnWith :: (p -> Bool) -> TurnCounter p -> Maybe (TurnCounter p) nextTurnWith predicate tc = find (predicate . currentPlayer) $ take (length (tcPlayers tc)) $ iterate nextTurn (nextTurn tc) previousTurn :: TurnCounter p -> TurnCounter p previousTurn (TurnCounter ps c) = TurnCounter ps (c-1) previousTurnWith :: (p -> Bool) -> TurnCounter p -> Maybe (TurnCounter p) previousTurnWith predicate tc = find (predicate . currentPlayer) $ take (length (tcPlayers tc)) $ iterate previousTurn (previousTurn tc) currentPlayer :: TurnCounter p -> p currentPlayer (TurnCounter ps c) = ps !! (c `mod` length ps) nextPlayer :: TurnCounter p -> p nextPlayer = currentPlayer . nextTurn previousPlayer :: TurnCounter p -> p previousPlayer = currentPlayer . previousTurn currentRound :: TurnCounter p -> Int currentRound (TurnCounter ps c) = c `div` length ps