SoccerFun-0.4.2: SoccerFun/Tape.hs
{-# LANGUAGE UnicodeSyntax, TemplateHaskell #-}
-- | record a match to a tape which is serialisable
module SoccerFun.Tape where
import Prelude.Unicode
import Data.DeriveTH
import Data.Binary
import SoccerFun.MatchControl
import SoccerFun.Player
import SoccerFun.Types
import SoccerFun.Field
import SoccerFun.Geometry
import SoccerFun.Ball
import SoccerFun.RefereeAction
import Control.Monad
import Codec.Compression.GZip
instance Binary Match where
put m = do
put $ team1 m
put $ team2 m
put $ theBall m
put $ theField m
put $ playingHalf m
put $ playingTime m
put $ score m
put $ unittime m
get = do
team1 ← get
team2 ← get
theBall ← get
theField ← get
playingHalf ← get
playingTime ← get
score ← get
unittime ← get
return $ Match
{team1 = team1,
team2 = team2,
theBall = theBall,
theField = theField,
theReferee = undefined,
playingHalf = playingHalf,
playingTime = playingTime,
score = score,
seed = undefined,
unittime = unittime}
instance Binary Player where
put p = do
put $ playerID p
put $ name p
put $ height p
put $ pos p
put $ speed p
put $ nose p
put $ skills p
put $ effect p
put $ stamina p
put $ health p
get = do
playerID ← get
name ← get
height ← get
pos ← get
speed ← get
nose ← get
skills ← get
effect ← get
stamina ← get
health ← get
return $ Player
{playerID = playerID,
name = name,
height = height,
pos = pos,
speed = speed,
nose = nose,
skills = skills,
effect = effect,
stamina = stamina,
health = health,
brain = undefined}
$( derive makeBinary ''Half )
$( derive makeBinary ''Field )
$( derive makeBinary ''Position3D )
$( derive makeBinary ''Ball )
$( derive makeBinary ''BallState )
$( derive makeBinary ''PlayerID )
$( derive makeBinary ''Position )
$( derive makeBinary ''Speed )
$( derive makeBinary ''Skill )
$( derive makeBinary ''PlayerEffect )
$( derive makeBinary ''Success )
$( derive makeBinary ''Speed3D )
$( derive makeBinary ''FeintDirection )
$( derive makeBinary ''RefereeAction )
$( derive makeBinary ''PlayerAction )
$( derive makeBinary ''Edge )
$( derive makeBinary ''ATeam )
$( derive makeBinary ''Reprimand )
data Tape = Tape [Step]
magic = "SoccerFun tape"
version = "0.4.2"
-- TODO: include framerate
instance Binary Tape where
put (Tape steps) = do
put magic
put version
put $ compress $ encode steps
get = do
let checkMagic m = when (not $ m ≡ magic) (error "This file does not contain a SoccerFun tape!")
checkMagic =<< get
let checkVersion v = when (not $ v ≡ version) (error $ "Incompatible tape version: " ⧺ show v)
checkVersion =<< get
liftM (Tape ∘ decode ∘ decompress) get
recordMatch ∷ Match → Tape
recordMatch m = Tape $ recordMatch' (([],[]), m) where
recordMatch' ∷ (([RefereeAction],[PlayerWithAction]),Match) → [(([RefereeAction],[PlayerWithAction]),Match)]
recordMatch' = takeWhile matchRunning ∘ iterate (stepMatch ∘ snd)
matchRunning (actions,match) = playingTime match > 0