haskell-snake-1.0.0: src/Game/HSnake/Player.hs
module Game.HSnake.Player where
import Control.Lens
import Game.HSnake.Basic
import Game.HSnake.Snake
import Data.List
data PlayerType = AI | Human
deriving (Eq, Show)
data Player = Player {
_playerType :: PlayerType
,_snake :: Snake
{-|
Temporary state variable to store next move's snake direction
Without this when snake went North, and user quickly typed
West, then South, snake would bump into itself
-}
,_nextSnakeDirection :: Direction
,_colour :: Colour
} deriving (Eq, Show)
makeLenses ''Player
initialPlayer :: Player
initialPlayer = Player
Human
initialSnake
(initialSnake^.direction)
Green
initialPlayerBottom :: Player
initialPlayerBottom = Player
Human
initialSnakeBottom
(initialSnakeBottom^.direction)
Green
initialComputer :: Player
initialComputer = Player
AI
initialSnakeBottom
(initialSnakeBottom^.direction)
Blue
isHuman :: Player -> Bool
isHuman (Player Human _ _ _) = True
isHuman _ = False
checkPlayerCollision :: Player -> Bool
checkPlayerCollision player = checkCollision $ player^.snake
movePlayer :: Player -> Player
movePlayer pl = snake .~ (moveSnake $ pl^.snake) $ pl
playerEatsApple :: Point -> Player -> Bool
playerEatsApple apple player = snakeEatsApple (player^.snake) apple
sumPlayersPosition :: [Player] -> [Point]
sumPlayersPosition ps = foldl (++) [] $ map (\pl -> pl^.snake^.position) ps
totalPlayersPosition :: [Player] -> [Point]
totalPlayersPosition = nub . sumPlayersPosition
checkPlayersCollision :: [Player] -> Bool
checkPlayersCollision ps = (length (filter checkPlayerCollision ps) > 0) ||
(length (totalPlayersPosition ps) < (length (sumPlayersPosition ps)))
increasePlayerSnakeLength :: Player -> Player
increasePlayerSnakeLength pl = snake .~ (increaseSnakeLength $ pl^.snake) $ pl
setNextPlayerDirection :: Player -> Direction -> Player
setNextPlayerDirection pl dir = nextSnakeDirection .~ dir $ pl
updatePlayerDirection :: Player -> Player
updatePlayerDirection pl = snake .~ changeSnakeDirection (pl^.snake) (pl^.nextSnakeDirection) $ pl