{-# LANGUAGE DataKinds #-} {-# LANGUAGE TypeOperators #-} {-# LANGUAGE OverloadedStrings #-} {-| Module : Hangman player Module Description : Library to handle a single or group of __players.__ Copyright : >implying License : >implying Maintainer : Florian Hageneder Stability : none Portability : what? -} module Player where import Data.Aeson import Data.Aeson.TH import Data.List (find) -- | The maximum amount of failures a player is allowed to do before he has to die maxFaliures = 10 -- | Data type to bundle Imformation about a player within an game session. data Player = Player { playerId :: Int -- ^ ID of the player , secret :: String -- ^ The secret key of the player , failures :: Int -- ^ The amount of failures the player had , isAlive :: Bool -- ^ If the player is still alive } deriving (Eq, Show, Read) instance ToJSON Player where toJSON (Player pid secret failures isAlive) = object [ "playerID" .= pid , "failures" .= failures , "alive" .= isAlive , "maxFailures" .= Player.maxFaliures ] {- | Creates a new Player with the given id. The player is initialized with NO secret and alive newPlayer 4 >>> (4, "", 0, True) -} newPlayer :: Int -- ^ the id for the player -> Player -- ^ created player newPlayer pid = Player pid "password" 0 True {- | returns a list of all players alive -} playersAlive :: [Player] -- ^ A set of players -> [Player] -- ^ All players currently allowed to play playersAlive = filter isAlive {- | Updates the player after an wrong try. Kills him after last failure -} wrongGuess :: Player -- ^ player that guessed wrong -> Player -- ^ updated player wrongGuess p | not $ isAlive p = p | otherwise = let newFailures = failures p + 1 in Player (playerId p) (secret p) newFailures (newFailures < maxFaliures) -- | Grants access to a player with given id if the key does match getPlayerForId :: [Player] -- ^ The set of players to search in -> Int -- ^ The id of the player to fetch -> String -- ^ The secret key of the player -> Maybe Player -- ^ A player or Nothing if id or key did not match getPlayerForId [] _ _ = Nothing getPlayerForId _ _ "" = Nothing getPlayerForId xs pid key | pid < 0 = Nothing | otherwise = do let player = find (\x -> playerId x == pid) xs case player of Nothing -> Nothing Just p -> if secret p == key then return p else Nothing -- | Sets the state of an player to dead killPlayer :: Player -- ^ currently player who did a terrible mistake -> Player -- ^ Now dead player killPlayer p = p {isAlive = False}