packages feed

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
@@ -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)