{-# LANGUAGE GADTs #-} {-# LANGUAGE TemplateHaskell #-} {-# LANGUAGE ScopedTypeVariables #-} {-# LANGUAGE NamedFieldPuns #-} {-# LANGUAGE DeriveDataTypeable #-} {-# LANGUAGE StandaloneDeriving #-} {-# LANGUAGE DeriveGeneric #-} {-# LANGUAGE RankNTypes #-} -- | Types for the engine module Nomyx.Core.Engine.Types where import Prelude hiding (log) import Language.Nomyx.Expression import Data.Lens.Template import Data.Time import Data.Typeable import Data.Data import Control.Monad.Error (ErrorT(..)) import Control.Monad.State import Control.Monad.Reader import GHC.Generics import System.Random -- * Evaluation -- | Environment necessary for the evaluation of any nomyx expressions or events --TODO: should the first field be a "Maybe RuleNumber"? --Indeed an evaluation is not always performed by a rule but also by the system (in which case we currently use rule number 0) data EvalEnv = EvalEnv { _eRuleNumber :: RuleNumber, -- number of the rule requesting the evaluation _eGame :: Game, -- game to be read/modified evalNomexFunc :: forall a. Nomex a -> Evaluate a, -- evaluation function evalNomexNEFunc :: forall b. NomexNE b -> EvaluateNE b} -- evaluation function without effect -- | Environment necessary for the evaluation of Nomex type Evaluate a = ErrorT String (State EvalEnv ) a -- | Environment necessary for the evaluation of NomexNE type EvaluateNE a = Reader EvalEnv a -- * Game type GameName = String -- | The state of the game: data Game = Game { _gameName :: GameName, _gameDesc :: GameDesc, _rules :: [RuleInfo], _players :: [PlayerInfo], _variables :: [Var], _events :: [EventInfo], _outputs :: [Output], _victory :: Maybe VictoryInfo, _logs :: [Log], _currentTime :: UTCTime, _randomGen :: StdGen} deriving (Typeable) data GameDesc = GameDesc { _desc :: String, _forumURL :: String} deriving (Eq, Show, Read, Ord) instance Eq Game where (Game {_gameName=gn1}) == (Game {_gameName=gn2}) = gn1 == gn2 instance Ord Game where compare (Game {_gameName=gn1}) (Game {_gameName=gn2}) = compare gn1 gn2 emptyGame name desc date gen = Game { _gameName = name, _gameDesc = desc, _rules = [], _players = [], _variables = [], _events = [], _outputs = [], _victory = Nothing, _logs = [], _randomGen = gen, _currentTime = date} -- * Variables -- | stores the variable's data data Var = forall a . (Typeable a, Show a) => Var { _vRuleNumber :: RuleNumber, _vName :: String, vData :: a} instance Show Var where show (Var a b c) = "Rule number = " ++ (show a) ++ ", Name = " ++ (show b) ++ ", Value = " ++ (show c) ++ "\n" -- * Events -- a form field data FormField = RadioField PlayerNumber String [(Int, String)] | TextField PlayerNumber String | TextAreaField PlayerNumber String | ButtonField PlayerNumber String | CheckboxField PlayerNumber String [(Int, String)] deriving (Show, Read, Ord, Eq, Generic) -- data sent back by the form fields data InputData = RadioData Int | CheckboxData [Int] | TextData String | TextAreaData String | ButtonData deriving (Show, Read, Eq, Ord) -- * Outputs data Output = Output { _outputNumber :: OutputNumber, -- number of the output _oRuleNumber :: RuleNumber, -- rule that triggered the output _oPlayerNumber :: (Maybe PlayerNumber), -- player to display the output to (Nothing means display to all players) _output :: NomexNE String, -- output string _oStatus :: Status} -- status of the output deriving (Show) instance Eq Output where (Output {_outputNumber=on1}) == (Output {_outputNumber=on2}) = on1 == on2 instance Ord Output where (Output {_outputNumber=r1}) <= (Output {_outputNumber=r2}) = r1 <= r2 -- * Logs data Log = Log { _lPlayerNumber :: Maybe PlayerNumber, _lTime :: UTCTime, _lMsg :: String} deriving (Show) -- * Rules data SubmitRule = SubmitRule RuleName RuleDesc RuleCode deriving (Show, Read, Eq, Ord, Data, Typeable) $( makeLenses [''Game, ''GameDesc, ''Var, ''Output, ''EvalEnv] )