deterministic-game-engine 0.2.1 → 0.3.0
raw patch · 13 files changed
+162/−149 lines, 13 filesdep ~deterministic-game-enginePVP ok
version bump matches the API change (PVP)
Dependency ranges changed: deterministic-game-engine
API changes (from Hackage documentation)
- GameEngine: GameActions :: (GameState a -> Player) -> (GameState a -> Move b) -> (GameState a -> Move b -> GameState a) -> (GameState a -> Bool) -> (GameState a -> Player -> Int) -> GameActions a b
- GameEngine: GameEngine :: GameActions a b -> GameState a -> GameEngine a b
- GameEngine: GameState :: a -> GameState a
- GameEngine: Move :: a -> Move a
- GameEngine: Player :: Symbol -> Player
- GameEngine: actions :: GameEngine a b -> GameActions a b
- GameEngine: data GameActions a b
- GameEngine: data GameEngine a b
- GameEngine: data GameState a
- GameEngine: data Move a
- GameEngine: data Player
- GameEngine: getMove :: GameActions a b -> GameState a -> Move b
- GameEngine: getPlayer :: GameActions a b -> GameState a -> Player
- GameEngine: getResult :: GameActions a b -> GameState a -> Move b -> GameState a
- GameEngine: getScore :: GameActions a b -> GameState a -> Player -> Int
- GameEngine: isTerminal :: GameActions a b -> GameState a -> Bool
- GameEngine: play :: Monad m => (GameState a -> m (GameState a)) -> GameEngine a b -> m Int
- GameEngine: playIO :: (GameState a -> IO ()) -> GameEngine a b -> IO Int
- GameEngine: playSimple :: GameEngine a b -> Int
- GameEngine: state :: GameEngine a b -> GameState a
- GameEngine: type Symbol = Char
+ Game.Deterministic.GameEngine: GameActions :: (GameState a -> m Player) -> (GameState a -> m (Move b)) -> (GameState a -> Move b -> m (GameState a)) -> (GameState a -> m Bool) -> (GameState a -> Player -> m Int) -> GameActions m a b
+ Game.Deterministic.GameEngine: GameEngine :: GameActions m a b -> GameState a -> GameEngine m a b
+ Game.Deterministic.GameEngine: GameState :: a -> GameState a
+ Game.Deterministic.GameEngine: Move :: a -> Move a
+ Game.Deterministic.GameEngine: Player :: Symbol -> Player
+ Game.Deterministic.GameEngine: actions :: GameEngine m a b -> GameActions m a b
+ Game.Deterministic.GameEngine: data GameActions m a b
+ Game.Deterministic.GameEngine: data GameEngine m a b
+ Game.Deterministic.GameEngine: data GameState a
+ Game.Deterministic.GameEngine: data Move a
+ Game.Deterministic.GameEngine: data Player
+ Game.Deterministic.GameEngine: getMove :: GameActions m a b -> GameState a -> m (Move b)
+ Game.Deterministic.GameEngine: getPlayer :: GameActions m a b -> GameState a -> m Player
+ Game.Deterministic.GameEngine: getResult :: GameActions m a b -> GameState a -> Move b -> m (GameState a)
+ Game.Deterministic.GameEngine: getScore :: GameActions m a b -> GameState a -> Player -> m Int
+ Game.Deterministic.GameEngine: isTerminal :: GameActions m a b -> GameState a -> m Bool
+ Game.Deterministic.GameEngine: play :: Monad m => GameEngine m a b -> m Int
+ Game.Deterministic.GameEngine: playIO :: GameEngineIO a b -> IO Int
+ Game.Deterministic.GameEngine: playSimple :: GameEngineSimple a b -> Int
+ Game.Deterministic.GameEngine: state :: GameEngine m a b -> GameState a
+ Game.Deterministic.GameEngine: type GameEngineIO a b = GameEngine IO a b
+ Game.Deterministic.GameEngine: type GameEngineSimple a b = GameEngine Identity a b
+ Game.Deterministic.GameEngine: type Symbol = Char
Files
- Spec/Spec.hs +0/−1
- Src/GameEngine.hs +0/−90
- Src/GameEngine/GameActions.hs +0/−27
- Src/GameEngine/GameState.hs +0/−6
- Src/GameEngine/Move.hs +0/−6
- Src/GameEngine/Player.hs +0/−10
- deterministic-game-engine.cabal +9/−9
- spec/Spec.hs +1/−0
- src/Game/Deterministic/GameEngine.hs +103/−0
- src/Game/Deterministic/GameEngine/GameActions.hs +27/−0
- src/Game/Deterministic/GameEngine/GameState.hs +6/−0
- src/Game/Deterministic/GameEngine/Move.hs +6/−0
- src/Game/Deterministic/GameEngine/Player.hs +10/−0
− Spec/Spec.hs
@@ -1,1 +0,0 @@-{-# OPTIONS_GHC -F -pgmF hspec-discover #-}
− Src/GameEngine.hs
@@ -1,90 +0,0 @@-{- |--Haskell library for creating simple deterministic games,-such as tic-tac-toe. The engine requires a minimal set of-actions related to the game, and then will run the game-until a terminal state is reached.--Simple generic example below. See the specs for a more detailed example.--> import GameEngine->-> game :: GameEngine Int Int-> game = GameEngine gameActions initialState->-> gameActions :: GameActions Int Int-> gameActions = GameActions {-> getPlayer = -- find the next player from a game state,-> getMove = -- find a move from the game state,-> getResult = -- transitions from a state to another state,-> isTerminal = -- determines if the game is terminal,-> getScore = -- get score from a terminal state-> }->-> initialState :: GameState Int-> initialState = GameState 0->-> -- run the game engine until a terminal state is reached-> playSimple game---}--{-# LANGUAGE RankNTypes #-}---module GameEngine (- Symbol,- GameState(..),- Player(..),- Move(..),- GameActions(..),- GameEngine(..),- play,- playSimple,- playIO- ) where---import Control.Monad.Identity-import GameEngine.GameState-import GameEngine.GameActions-import GameEngine.Move-import GameEngine.Player---data GameEngine a b = GameEngine {- actions :: GameActions a b,- -- ^ Defines how the game will be played-- state :: GameState a- -- ^ The current state of the game- }--- ^ Holds information about how the game is played, and the current state of the game.----- TODO: provided function should be forced to be an identity only function--- forall a. a -> m a-play :: Monad m => (GameState a -> m (GameState a)) -> GameEngine a b -> m Int--- ^ Run the provided game engine under a monadic context until a terminal state is reached.--- Note: provided function should act as an identity only, and should not modify the game state.-play f engine- | performWithState isTerminal engine = return . performWithState getScore engine $ performWithState getPlayer engine- | otherwise = f (getNextState engine) >>= play f . GameEngine (actions engine)---playSimple :: GameEngine a b -> Int--- ^ Run the provided game engine without a context until a terminal state is reached.-playSimple = runIdentity . play Identity---playIO :: (GameState a -> IO ()) -> GameEngine a b -> IO Int--- ^ Run the provided game engine within an IO context until a terminal state is reached.-playIO f = play (\x -> f x >> return x)---getNextState :: GameEngine a b -> GameState a-getNextState engine = performWithState getResult engine $ performWithState getMove engine---performWithState :: (GameActions a b -> GameState a -> c) -> GameEngine a b -> c-performWithState f engine = f (actions engine) $ state engine
− Src/GameEngine/GameActions.hs
@@ -1,27 +0,0 @@-module GameEngine.GameActions (- GameActions(..)- ) where---import GameEngine.Player-import GameEngine.Move-import GameEngine.GameState---data GameActions a b = GameActions {- getPlayer :: GameState a -> Player,- -- ^ Specifies which player has the move in the state-- getMove :: GameState a -> Move b,- -- ^ Returns a legal move in the state-- getResult :: GameState a -> Move b -> GameState a,- -- ^ The transition model, which determines the result of a move-- isTerminal :: GameState a -> Bool,- -- ^ True if game is over, False otherwise-- getScore :: GameState a -> Player -> Int- -- ^ A utility function to determine the numeric value for a game that ends in a terminal state- }--- ^ Set of actions that defines how the game will be played
− Src/GameEngine/GameState.hs
@@ -1,6 +0,0 @@-module GameEngine.GameState (- GameState(..)- ) where---data GameState a = GameState a deriving (Eq, Show)
− Src/GameEngine/Move.hs
@@ -1,6 +0,0 @@-module GameEngine.Move (- Move(..)- ) where---data Move a = Move a deriving (Eq, Show)
− Src/GameEngine/Player.hs
@@ -1,10 +0,0 @@-module GameEngine.Player (- Symbol,- Player(..)- ) where---type Symbol = Char---data Player = Player Symbol deriving (Eq, Show)
deterministic-game-engine.cabal view
@@ -1,5 +1,5 @@ name: deterministic-game-engine-version: 0.2.1+version: 0.3.0 synopsis: Simple deterministic game engine description: Haskell library for creating simple deterministic games, such as tic-tac-toe. The engine requires a minimal set of@@ -22,12 +22,12 @@ library- hs-source-dirs: Src- exposed-modules: GameEngine- other-modules: GameEngine.GameActions,- GameEngine.GameState,- GameEngine.Move,- GameEngine.Player+ hs-source-dirs: src+ exposed-modules: Game.Deterministic.GameEngine+ other-modules: Game.Deterministic.GameEngine.GameActions,+ Game.Deterministic.GameEngine.GameState,+ Game.Deterministic.GameEngine.Move,+ Game.Deterministic.GameEngine.Player build-depends: base <5.0, mtl@@ -36,12 +36,12 @@ test-suite test- hs-source-dirs: Spec+ hs-source-dirs: spec main-is: Spec.hs ghc-options: -Wall type: exitcode-stdio-1.0 build-depends: base <5.0, hspec >=2.1 && <2.2,- deterministic-game-engine ==0.2.1+ deterministic-game-engine ==0.3.0 default-language: Haskell2010
+ spec/Spec.hs view
@@ -0,0 +1,1 @@+{-# OPTIONS_GHC -F -pgmF hspec-discover #-}
+ src/Game/Deterministic/GameEngine.hs view
@@ -0,0 +1,103 @@+{- |++Haskell library for creating simple deterministic games,+such as tic-tac-toe. The engine requires a minimal set of+actions related to the game, and then will run the game+until a terminal state is reached.++Simple generic example below. See the specs for a more detailed example.++> import GameEngine+>+> game :: GameEngine Int Int+> game = GameEngine gameActions initialState+>+> gameActions :: GameActions Int Int+> gameActions = GameActions {+> getPlayer = -- find the next player from a game state,+> getMove = -- find a move from the game state,+> getResult = -- transitions from a state to another state,+> isTerminal = -- determines if the game is terminal,+> getScore = -- get score from a terminal state+> }+>+> initialState :: GameState Int+> initialState = GameState 0+>+> -- run the game engine until a terminal state is reached+> playSimple game++-}++{-# LANGUAGE RankNTypes #-}+++module Game.Deterministic.GameEngine (+ Symbol,+ GameState(..),+ Player(..),+ Move(..),+ GameActions(..),+ GameEngine(..),+ GameEngineSimple,+ GameEngineIO,+ play,+ playSimple,+ playIO+ ) where+++import Control.Monad.Identity+import Game.Deterministic.GameEngine.GameActions+import Game.Deterministic.GameEngine.GameState+import Game.Deterministic.GameEngine.Move+import Game.Deterministic.GameEngine.Player+++data GameEngine m a b = GameEngine {+ actions :: GameActions m a b,+ -- ^ Defines how the game will be played++ state :: GameState a+ -- ^ The current state of the game+ }+-- ^ Holds information about how the game is played, and the current state of the game.+++type GameEngineSimple a b = GameEngine Identity a b+type GameEngineIO a b = GameEngine IO a b+++play :: Monad m => GameEngine m a b -> m Int+-- ^ Run the provided game engine under a monadic context until a terminal state is reached.+play engine = do+ isTerm <- isTerminal gameActions gameState++ if isTerm then do+ player <- getPlayer gameActions gameState+ getScore gameActions gameState player+ else do+ nextState <- getNextState engine+ play $ GameEngine (actions engine) nextState+ where+ gameActions = actions engine+ gameState = state engine+++playSimple :: GameEngineSimple a b -> Int+-- ^ Run the provided game engine without a context until a terminal state is reached.+playSimple = runIdentity . play+++playIO :: GameEngineIO a b -> IO Int+-- ^ Run the provided game engine within an IO context until a terminal state is reached.+playIO = play+++getNextState :: Monad m => GameEngine m a b -> m (GameState a)+getNextState engine = do+ nextMove <- getMove gameActions gameState+ getResult gameActions gameState nextMove+ where+ gameActions = actions engine+ gameState = state engine
+ src/Game/Deterministic/GameEngine/GameActions.hs view
@@ -0,0 +1,27 @@+module Game.Deterministic.GameEngine.GameActions (+ GameActions(..)+ ) where+++import Game.Deterministic.GameEngine.GameState+import Game.Deterministic.GameEngine.Move+import Game.Deterministic.GameEngine.Player+++data GameActions m a b = GameActions {+ getPlayer :: GameState a -> m Player,+ -- ^ Specifies which player has the move in the state++ getMove :: GameState a -> m (Move b),+ -- ^ Returns a legal move in the state++ getResult :: GameState a -> Move b -> m (GameState a),+ -- ^ The transition model, which determines the result of a move++ isTerminal :: GameState a -> m Bool,+ -- ^ True if game is over, False otherwise++ getScore :: GameState a -> Player -> m Int+ -- ^ A utility function to determine the numeric value for a game that ends in a terminal state+ }+-- ^ Set of actions that defines how the game will be played
+ src/Game/Deterministic/GameEngine/GameState.hs view
@@ -0,0 +1,6 @@+module Game.Deterministic.GameEngine.GameState (+ GameState(..)+ ) where+++data GameState a = GameState a deriving (Eq, Show)
+ src/Game/Deterministic/GameEngine/Move.hs view
@@ -0,0 +1,6 @@+module Game.Deterministic.GameEngine.Move (+ Move(..)+ ) where+++data Move a = Move a deriving (Eq, Show)
+ src/Game/Deterministic/GameEngine/Player.hs view
@@ -0,0 +1,10 @@+module Game.Deterministic.GameEngine.Player (+ Symbol,+ Player(..)+ ) where+++type Symbol = Char+++data Player = Player Symbol deriving (Eq, Show)