hastron/src/Hastron/Game/Types.hs

104 lines
4.1 KiB
Haskell

{-# LANGUAGE RecordWildCards #-}
module Hastron.Game.Types where
import Data.HashMap.Strict (HashMap)
import qualified Data.HashMap.Strict as Map
import Data.HashSet (HashSet)
import qualified Data.HashSet as Set
import Data.Tuple (swap)
type Point = (Int, Int)
type Timestamp = Int
type TimeInterval = Int
data Direction = Left | Right | Up | Down deriving (Show, Eq, Ord, Enum)
data Velocity = Velocity Int Direction deriving (Show, Eq, Ord)
type PlayerId = Int
data PlayerState = PlayerAlive
| PlayerDead
| PlayerDisconnected
| PlayerLeft
deriving (Show, Eq, Ord, Enum)
type PlayerTrail = [Point]
data PlayerBoost = PlayerBoost { boostActive :: Bool
, boostFuel :: Int
} deriving (Show, Eq)
type PlayerScore = Int
data Player = Player { playerId :: PlayerId
, playerState :: PlayerState
, playerPosition :: Point
, playerVelocity :: Velocity
, playerTrail :: PlayerTrail
, playerBoost :: PlayerBoost
, playerScore :: PlayerScore
, playerLastEventTime :: Int
} deriving (Show, Eq)
data PlayerEndState = PlayerWinner | PlayerLoser | PlayerDropped
deriving (Show, Eq, Ord, Enum)
data GameState = GameStarted | GameInit | GameFinished
deriving (Show, Eq, Ord, Enum)
data GameMap = GameMap { size :: Int
, gameMapBlockedPoints :: HashSet Point
} deriving (Show, Eq)
data GameSettings = GameSettings { gameBoostFactor :: Int
, gameBoostRefillFactor :: Double
} deriving (Show, Eq)
data Game = Game { gamePlayers :: HashMap PlayerId Player
, gameState :: GameState
, gameSettings :: GameSettings
, gameMap :: GameMap
} deriving (Show, Eq)
type GameResult = HashMap PlayerId (PlayerScore, PlayerEndState)
data InEvent = InPlayerTurnLeft PlayerId
| InPlayerTurnRight PlayerId
| InPlayerBoostChange PlayerId Bool
| InPlayerStateChange PlayerId PlayerState
| InPlayerIdle PlayerId
deriving (Show, Eq, Ord)
data OutEvent = OutPlayerPosition PlayerId Point Direction
| OutPlayerStateChange PlayerId PlayerState
| OutPlayerBoostChange PlayerId PlayerBoost
| OutGameStateChange GameState
| OutGameOver GameResult
deriving (Show, Eq)
newGameMap :: Int -> GameMap
newGameMap size = GameMap size $ Set.fromList borderPoints
where
borderPoints = let xs = [(x, y) | x <- [-1, size], y <- [0 .. size - 1]]
in xs ++ map swap xs
newGame :: Int -> GameSettings -> Game
newGame size gameSettings = Game { gamePlayers = Map.empty
, gameState = GameInit
, gameSettings = gameSettings
, gameMap = newGameMap size
}
newPlayer :: Int -> Point -> Velocity -> Int -> Player
newPlayer pId pos velocity boost =
Player pId PlayerAlive pos velocity [pos] (PlayerBoost False boost) 0 0
addPlayer :: Game -> Player -> Game
addPlayer game@Game{ gameMap = gameMap@GameMap{ .. }, .. } player@Player{ .. } =
game { gamePlayers = Map.insert playerId player gamePlayers
, gameMap = gameMap { gameMapBlockedPoints =
Set.insert playerPosition gameMapBlockedPoints } }