104 lines
4.1 KiB
Haskell
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 } }
|