Compare commits
5 Commits
master
...
engine-gov
Author | SHA1 | Date |
---|---|---|
Govind Krishna Joshi | a7c0a01269 | |
Govind Krishna Joshi | af2cd56c81 | |
Govind Krishna Joshi | a61e874b16 | |
Govind Krishna Joshi | 4bbea62c27 | |
Govind Krishna Joshi | fc3df3a86d |
|
@ -15,3 +15,11 @@ cabal.sandbox.config
|
|||
*.prof
|
||||
*.aux
|
||||
*.hp
|
||||
|
||||
# Vim
|
||||
[._]*.s[a-w][a-z]
|
||||
[._]s[a-w][a-z]
|
||||
*.un~
|
||||
Session.vim
|
||||
.netrwhist
|
||||
*~
|
||||
|
|
|
@ -0,0 +1,7 @@
|
|||
module Main where
|
||||
|
||||
import Hastron.Game.Engine
|
||||
import Hastron.Server.Types
|
||||
|
||||
main :: IO()
|
||||
main = putStrLn "Hello World"
|
2
Setup.hs
2
Setup.hs
|
@ -1,2 +1,2 @@
|
|||
import Distribution.Simple
|
||||
import Distribution.Simple
|
||||
main = defaultMain
|
||||
|
|
|
@ -1,31 +1,50 @@
|
|||
-- Initial hastron.cabal generated by cabal init. For further
|
||||
-- documentation, see http://haskell.org/cabal/users-guide/
|
||||
|
||||
name: hastron
|
||||
version: 0.1.0.0
|
||||
-- synopsis:
|
||||
-- description:
|
||||
license: MIT
|
||||
license-file: LICENSE
|
||||
author: Abhinav Sarkar
|
||||
maintainer: abhinav@abhinavsarkar.net
|
||||
-- copyright:
|
||||
category: Game
|
||||
build-type: Simple
|
||||
extra-source-files: README.md
|
||||
cabal-version: >=1.10
|
||||
|
||||
library
|
||||
default-language: Haskell2010
|
||||
ghc-options: -Wall
|
||||
hs-source-dirs: src
|
||||
exposed-modules:
|
||||
Hastron.Server.Types
|
||||
Hastron.Utils
|
||||
Hastron.Game.Player
|
||||
Hastron.Game.Types
|
||||
Hastron.Game.Engine
|
||||
build-depends:
|
||||
base >=4.7 && <4.9,
|
||||
text >=1.2 && <1.3,
|
||||
unordered-containers >=0.2.5 && <0.3,
|
||||
hashable >=1.2 && <1.3
|
||||
|
||||
|
||||
executable hastron
|
||||
main-is: Main.hs
|
||||
other-modules: Hastron.Server.Types
|
||||
-- other-extensions:
|
||||
build-depends: base >=4.7 && <4.9,
|
||||
text >=1.2 && <1.3,
|
||||
unordered-containers >=0.2.5 && <0.3,
|
||||
dlist >= 0.7 && <0.8,
|
||||
mtl >= 2.2 && <2.3,
|
||||
bifunctors >=5 && <6,
|
||||
hashable >=1.2 && <1.3
|
||||
hs-source-dirs: src
|
||||
default-language: Haskell2010
|
||||
ghc-options: -Wall
|
||||
build-depends:
|
||||
base >=4.7 && <4.9,
|
||||
hastron
|
||||
default-language: Haskell2010
|
||||
|
||||
test-suite test
|
||||
type: exitcode-stdio-1.0
|
||||
ghc-options: -Wall
|
||||
default-language: Haskell2010
|
||||
hs-source-dirs: tests
|
||||
main-is: TestMain.hs
|
||||
build-depends:
|
||||
base >=4.7 && <4.9,
|
||||
hastron,
|
||||
tasty >=0.10 && <0.11,
|
||||
tasty-hunit >=0.9 && <0.10,
|
||||
tasty-quickcheck >=0.8 && <0.9,
|
||||
QuickCheck >=2.8 && <2.9
|
||||
|
||||
|
|
|
@ -0,0 +1,26 @@
|
|||
module Hastron.Game.Player where
|
||||
|
||||
import Hastron.Game.Types
|
||||
import qualified Hastron.Utils as Utils
|
||||
|
||||
turn :: Direction -> Player -> Player
|
||||
turn dir player = player { playerVelocity = changeDirection (playerVelocity player) dir }
|
||||
where changeDirection (Velocity v _) d = Velocity v d
|
||||
|
||||
turnRight :: Player -> Player
|
||||
turnRight player = turn (Utils.nextEnum (direction player)) player
|
||||
|
||||
turnLeft :: Player -> Player
|
||||
turnLeft player = turn (Utils.prevEnum (direction player)) player
|
||||
|
||||
direction :: Player -> Direction
|
||||
direction Player {playerVelocity=(Velocity _ dir)} = dir
|
||||
|
||||
toggleBoost :: PlayerBoost -> PlayerBoost
|
||||
toggleBoost boost@(PlayerBoost { boostActive = curr }) = boost { boostActive = not curr }
|
||||
|
||||
updateBoostValue :: (Double -> Double) -> PlayerBoost -> PlayerBoost
|
||||
updateBoostValue func boost@(PlayerBoost {boostFuel = fuel}) = boost { boostFuel = func fuel }
|
||||
|
||||
changeState :: PlayerState -> Player -> Player
|
||||
changeState new player = player { playerState = new }
|
|
@ -9,7 +9,11 @@ import Data.Tuple (swap)
|
|||
|
||||
type Point = (Int, Int)
|
||||
|
||||
data Direction = Left | Right | Up | Down deriving (Show, Eq, Ord, Enum)
|
||||
data Direction = Left
|
||||
| Up
|
||||
| Right
|
||||
| Down
|
||||
deriving (Show, Eq, Ord, Enum, Bounded)
|
||||
|
||||
data Velocity = Velocity Int Direction deriving (Show, Eq, Ord)
|
||||
|
||||
|
@ -19,7 +23,7 @@ data PlayerState = PlayerAlive
|
|||
| PlayerDead
|
||||
| PlayerDisconnected
|
||||
| PlayerLeft
|
||||
deriving (Show, Eq, Ord, Enum)
|
||||
deriving (Show, Eq, Ord, Enum, Bounded)
|
||||
|
||||
type PlayerTrail = [Point]
|
||||
|
||||
|
@ -40,7 +44,7 @@ data Player = Player { playerId :: PlayerId
|
|||
} deriving (Show, Eq)
|
||||
|
||||
data PlayerEndState = PlayerWinner | PlayerLoser | PlayerDropped
|
||||
deriving (Show, Eq, Ord, Enum)
|
||||
deriving (Show, Eq, Ord, Enum, Bounded)
|
||||
|
||||
data GameState = GameStarted | GameInit | GameFinished
|
||||
deriving (Show, Eq, Ord, Enum)
|
||||
|
|
|
@ -0,0 +1,11 @@
|
|||
module Hastron.Utils where
|
||||
|
||||
nextEnum :: (Enum a, Bounded a) => a -> a
|
||||
nextEnum = turnEnum 1
|
||||
|
||||
prevEnum :: (Enum a, Bounded a) => a -> a
|
||||
prevEnum = turnEnum (-1)
|
||||
|
||||
turnEnum :: (Enum a, Bounded a) => Int -> a -> a
|
||||
turnEnum n e = toEnum $ mod (sum [fromEnum e, n]) enumLength
|
||||
where enumLength = succ (fromEnum (maxBound `asTypeOf` e))
|
|
@ -1,7 +0,0 @@
|
|||
module Main where
|
||||
|
||||
import Hastron.Server.Types
|
||||
import Hastron.Game.Engine
|
||||
|
||||
main :: IO()
|
||||
main = putStrLn "Hello World"
|
|
@ -0,0 +1,63 @@
|
|||
module Hastron.Game.TestPlayer where
|
||||
|
||||
import qualified Test.QuickCheck.Arbitrary as Arbit
|
||||
import qualified Test.Tasty as Test
|
||||
import qualified Test.Tasty.QuickCheck as QC
|
||||
|
||||
import qualified Hastron.Game.Player as Player
|
||||
import qualified Hastron.Game.Types as Types
|
||||
import qualified Hastron.Utils as Utils
|
||||
|
||||
properties :: Test.TestTree
|
||||
properties = Test.testGroup "Player Properties"
|
||||
[ QC.testProperty "Turn player right" prop_turn_player_right
|
||||
, QC.testProperty "Turn player left" prop_turn_player_left
|
||||
]
|
||||
|
||||
-- | Arbitrary instance declarations
|
||||
instance Arbit.Arbitrary Types.Direction where
|
||||
arbitrary = Arbit.arbitraryBoundedEnum
|
||||
|
||||
instance Arbit.Arbitrary Types.Velocity where
|
||||
arbitrary = do
|
||||
vel <- Arbit.arbitrary
|
||||
dir <- Arbit.arbitrary
|
||||
return $ Types.Velocity vel dir
|
||||
|
||||
instance Arbit.Arbitrary Types.PlayerState where
|
||||
arbitrary = Arbit.arbitraryBoundedEnum
|
||||
|
||||
instance Arbit.Arbitrary Types.PlayerBoost where
|
||||
arbitrary = do
|
||||
active <- Arbit.arbitrary
|
||||
fuel <- Arbit.arbitrary
|
||||
return Types.PlayerBoost { Types.boostActive = active, Types.boostFuel = fuel }
|
||||
|
||||
instance Arbit.Arbitrary Types.Player where
|
||||
arbitrary = do
|
||||
id <- Arbit.arbitrary
|
||||
state <- Arbit.arbitrary
|
||||
position <- Arbit.arbitrary
|
||||
velocity <- Arbit.arbitrary
|
||||
trail <- Arbit.arbitrary
|
||||
boost <- Arbit.arbitrary
|
||||
score <- Arbit.arbitrary
|
||||
return Types.Player { Types.playerId = id
|
||||
, Types.playerState = state
|
||||
, Types.playerPosition = position
|
||||
, Types.playerVelocity = velocity
|
||||
, Types.playerTrail = trail
|
||||
, Types.playerBoost = boost
|
||||
, Types.playerScore = score
|
||||
}
|
||||
|
||||
|
||||
instance Arbit.Arbitrary Types.PlayerEndState where
|
||||
arbitrary = Arbit.arbitraryBoundedEnum
|
||||
|
||||
-- | Properties
|
||||
prop_turn_player_right :: Types.Player -> Bool
|
||||
prop_turn_player_right player = (Player.direction . Player.turnRight) player == (Utils.nextEnum . Player.direction) player
|
||||
|
||||
prop_turn_player_left :: Types.Player -> Bool
|
||||
prop_turn_player_left player = (Player.direction . Player.turnLeft) player == (Utils.prevEnum . Player.direction) player
|
|
@ -0,0 +1,24 @@
|
|||
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
|
||||
|
||||
module Hastron.TestUtils (properties) where
|
||||
|
||||
import qualified Test.QuickCheck.Arbitrary as Arbit
|
||||
import qualified Test.Tasty as Test
|
||||
import qualified Test.Tasty.QuickCheck as QC
|
||||
|
||||
import qualified Hastron.Utils as Utils
|
||||
|
||||
newtype Enum' a = Enum' a
|
||||
deriving (Eq, Bounded, Enum, Show)
|
||||
|
||||
instance (Enum a, Bounded a) => Arbit.Arbitrary (Enum' a) where
|
||||
arbitrary = Arbit.arbitraryBoundedEnum
|
||||
|
||||
properties :: Test.TestTree
|
||||
properties = Test.testGroup "Utils Properties"
|
||||
[ QC.testProperty "Additive inverse for turning" $
|
||||
\n e -> prop_additive_turning_inverse (n :: Int) (e :: Enum' Char)
|
||||
]
|
||||
|
||||
prop_additive_turning_inverse :: (Eq a, Show a, Enum a, Bounded a) => Int -> Enum' a -> Bool
|
||||
prop_additive_turning_inverse n (Enum' e) = e == ((Utils.turnEnum n) . (Utils.turnEnum (-n))) e
|
|
@ -0,0 +1,23 @@
|
|||
module Main where
|
||||
|
||||
import qualified Test.Tasty as Tasty
|
||||
|
||||
import qualified Hastron.Game.TestPlayer as Player
|
||||
import qualified Hastron.TestUtils as Utils
|
||||
|
||||
main :: IO ()
|
||||
main = Tasty.defaultMain tests
|
||||
|
||||
tests :: Tasty.TestTree
|
||||
tests = Tasty.testGroup "Tests" [properties, unitTests]
|
||||
|
||||
unitTests :: Tasty.TestTree
|
||||
unitTests = Tasty.testGroup "Unit Tests" [hUnitTests]
|
||||
|
||||
properties :: Tasty.TestTree
|
||||
properties = Tasty.testGroup "Quickcheck properties" [ Utils.properties
|
||||
, Player.properties
|
||||
]
|
||||
|
||||
hUnitTests :: Tasty.TestTree
|
||||
hUnitTests = Tasty.testGroup "HUnit unit tests" []
|
Loading…
Reference in New Issue