2018-05-11 12:31:53 +02:00
|
|
|
{-# LANGUAGE NamedFieldPuns #-}
|
2018-04-11 13:25:24 +02:00
|
|
|
{-# LANGUAGE StandaloneDeriving #-}
|
|
|
|
{-# LANGUAGE DeriveGeneric #-}
|
2018-05-12 11:21:59 +02:00
|
|
|
{-# LANGUAGE FlexibleInstances #-}
|
2019-01-08 22:48:18 +01:00
|
|
|
{-# LANGUAGE FlexibleContexts #-}
|
2018-05-11 12:31:53 +02:00
|
|
|
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
|
2018-05-15 18:21:07 +02:00
|
|
|
{-# LANGUAGE MultiParamTypeClasses #-}
|
2018-07-27 23:48:48 +02:00
|
|
|
{-# LANGUAGE OverloadedStrings #-}
|
2018-05-11 12:31:53 +02:00
|
|
|
module Game (
|
2018-07-12 22:33:13 +02:00
|
|
|
Key
|
2018-05-15 18:21:07 +02:00
|
|
|
, View
|
2018-07-12 22:33:13 +02:00
|
|
|
, T
|
2018-05-11 12:31:53 +02:00
|
|
|
, export
|
|
|
|
, new
|
2018-05-15 18:21:07 +02:00
|
|
|
, play
|
2018-05-11 12:31:53 +02:00
|
|
|
) where
|
2018-04-11 13:25:24 +02:00
|
|
|
|
2019-01-08 22:48:18 +01:00
|
|
|
import Control.Monad.Except (throwError)
|
2018-05-12 11:21:59 +02:00
|
|
|
import Data.Text (pack)
|
2018-07-12 22:33:13 +02:00
|
|
|
import Data.Map (mapWithKey)
|
2018-07-27 23:48:48 +02:00
|
|
|
import Data.HashMap.Strict (insert)
|
|
|
|
import Data.Aeson (FromJSON(..), ToJSON(..), ToJSON1(..), ToJSONKey(..), Value(..), genericParseJSON, genericToEncoding, genericLiftToEncoding, toEncoding1, toJSON1)
|
2018-05-12 11:21:59 +02:00
|
|
|
import Data.Aeson.Types (toJSONKeyText)
|
2018-07-12 22:33:13 +02:00
|
|
|
import qualified JSON (defaultOptions, singleLCField)
|
|
|
|
import qualified Data (Key)
|
2018-05-11 12:31:53 +02:00
|
|
|
import qualified Player (Key)
|
2018-05-12 11:21:59 +02:00
|
|
|
import qualified Hanafuda (Flower(..), Card(..), Pack, cardsOfPack, empty)
|
2018-07-12 22:33:13 +02:00
|
|
|
import qualified Hanafuda.Player (Player(..), Players(..))
|
2019-01-08 22:48:18 +01:00
|
|
|
import qualified Hanafuda.KoiKoi (Action(..), Game(..), Environment, Mode(..), Move(..), On(..), Over(..), Score, Source(..), Step(..), Yaku(..), new, play)
|
2018-04-11 13:25:24 +02:00
|
|
|
import GHC.Generics
|
|
|
|
|
2018-05-11 12:31:53 +02:00
|
|
|
deriving instance Generic Hanafuda.Card
|
2018-05-12 11:21:59 +02:00
|
|
|
deriving instance Generic Hanafuda.Flower
|
2019-01-08 22:48:18 +01:00
|
|
|
deriving instance Generic Hanafuda.KoiKoi.Action
|
2018-05-12 11:21:59 +02:00
|
|
|
deriving instance Generic Hanafuda.KoiKoi.Mode
|
2018-05-11 12:31:53 +02:00
|
|
|
deriving instance Generic Hanafuda.KoiKoi.Move
|
2018-05-12 11:21:59 +02:00
|
|
|
deriving instance Generic Hanafuda.KoiKoi.Yaku
|
2019-01-08 22:48:18 +01:00
|
|
|
deriving instance Generic Hanafuda.KoiKoi.Source
|
2018-05-12 11:21:59 +02:00
|
|
|
deriving instance Generic Hanafuda.KoiKoi.Step
|
2018-07-12 22:33:13 +02:00
|
|
|
deriving instance Generic1 (Hanafuda.Player.Player Player.Key)
|
|
|
|
deriving instance Generic1 (Hanafuda.Player.Players Player.Key)
|
2018-04-11 13:25:24 +02:00
|
|
|
|
2018-05-15 18:21:07 +02:00
|
|
|
type On = Hanafuda.KoiKoi.On Player.Key
|
|
|
|
type Over = Hanafuda.KoiKoi.Over Player.Key
|
|
|
|
type View = Hanafuda.KoiKoi.Game Player.Key
|
|
|
|
|
|
|
|
deriving instance Generic On
|
|
|
|
deriving instance Generic Over
|
|
|
|
deriving instance Generic View
|
|
|
|
|
2018-05-11 12:31:53 +02:00
|
|
|
instance FromJSON Hanafuda.Card
|
|
|
|
instance ToJSON Hanafuda.Card
|
2018-04-11 13:25:24 +02:00
|
|
|
|
2018-05-12 11:21:59 +02:00
|
|
|
instance ToJSON Hanafuda.Flower
|
|
|
|
|
|
|
|
instance ToJSON Hanafuda.Pack where
|
|
|
|
toJSON = toJSON . Hanafuda.cardsOfPack
|
|
|
|
toEncoding = toEncoding . Hanafuda.cardsOfPack
|
|
|
|
|
2019-01-08 22:48:18 +01:00
|
|
|
instance ToJSON Hanafuda.KoiKoi.Action
|
|
|
|
|
2018-05-12 11:21:59 +02:00
|
|
|
instance ToJSON Hanafuda.KoiKoi.Mode
|
|
|
|
|
2018-05-13 18:08:12 +02:00
|
|
|
instance FromJSON Hanafuda.KoiKoi.Move where
|
|
|
|
parseJSON = genericParseJSON JSON.singleLCField
|
2018-05-11 12:31:53 +02:00
|
|
|
instance ToJSON Hanafuda.KoiKoi.Move where
|
2018-04-11 13:25:24 +02:00
|
|
|
toEncoding = genericToEncoding JSON.singleLCField
|
2018-05-11 12:31:53 +02:00
|
|
|
|
2019-01-08 22:48:18 +01:00
|
|
|
instance ToJSON Hanafuda.KoiKoi.Source
|
|
|
|
|
|
|
|
instance ToJSON Hanafuda.KoiKoi.Step where
|
|
|
|
toEncoding = genericToEncoding JSON.defaultOptions
|
|
|
|
|
2018-07-12 22:33:13 +02:00
|
|
|
instance ToJSON1 (Hanafuda.Player.Player Player.Key) where
|
2018-05-12 11:21:59 +02:00
|
|
|
liftToEncoding = genericLiftToEncoding JSON.defaultOptions
|
|
|
|
|
2018-07-12 22:33:13 +02:00
|
|
|
instance ToJSON (Hanafuda.Player.Player Player.Key Hanafuda.KoiKoi.Score) where
|
2018-05-12 11:21:59 +02:00
|
|
|
toJSON = toJSON1
|
|
|
|
toEncoding = toEncoding1
|
|
|
|
|
|
|
|
instance ToJSON Hanafuda.KoiKoi.Yaku where
|
|
|
|
toEncoding = genericToEncoding JSON.defaultOptions
|
|
|
|
instance ToJSONKey Hanafuda.KoiKoi.Yaku where
|
|
|
|
toJSONKey = toJSONKeyText (pack . show)
|
|
|
|
|
2018-07-12 22:33:13 +02:00
|
|
|
instance ToJSON1 (Hanafuda.Player.Players Player.Key) where
|
|
|
|
liftToEncoding = genericLiftToEncoding JSON.defaultOptions
|
|
|
|
|
|
|
|
instance ToJSON (Hanafuda.Player.Players Player.Key Hanafuda.KoiKoi.Score) where
|
|
|
|
toJSON = toJSON1
|
|
|
|
toEncoding = toEncoding1
|
|
|
|
|
2018-07-15 17:57:40 +02:00
|
|
|
type T = Hanafuda.KoiKoi.On Player.Key
|
2018-05-15 18:21:07 +02:00
|
|
|
|
2018-07-12 22:33:13 +02:00
|
|
|
instance ToJSON T
|
2018-05-12 11:21:59 +02:00
|
|
|
|
2018-05-11 12:31:53 +02:00
|
|
|
type Key = Data.Key T
|
|
|
|
|
|
|
|
new :: Player.Key -> Player.Key -> IO T
|
|
|
|
new p1 p2 = do
|
2018-07-15 17:57:40 +02:00
|
|
|
Hanafuda.KoiKoi.new [p1, p2] Hanafuda.KoiKoi.WholeYear
|
2018-05-11 12:31:53 +02:00
|
|
|
|
2018-07-27 23:48:48 +02:00
|
|
|
export :: Player.Key -> T -> Value
|
|
|
|
export key on = Object $ insert "deck" (toJSON $ length $ Hanafuda.KoiKoi.deck on) $ ast
|
2018-05-11 12:31:53 +02:00
|
|
|
where
|
2018-07-12 22:33:13 +02:00
|
|
|
Hanafuda.Player.Players unfiltered = Hanafuda.KoiKoi.players on
|
2018-05-15 18:21:07 +02:00
|
|
|
maskOpponentsHand k player
|
|
|
|
| k == key = player
|
|
|
|
| otherwise = player {Hanafuda.Player.hand = Hanafuda.empty}
|
2018-07-27 23:48:48 +02:00
|
|
|
Object ast = toJSON $ on {
|
|
|
|
Hanafuda.KoiKoi.players = Hanafuda.Player.Players $ mapWithKey maskOpponentsHand unfiltered
|
|
|
|
}
|
2018-05-15 18:21:07 +02:00
|
|
|
|
2019-01-08 22:48:18 +01:00
|
|
|
play :: Hanafuda.KoiKoi.Environment m => Player.Key -> Hanafuda.KoiKoi.Move -> T -> m (Hanafuda.KoiKoi.Game Player.Key)
|
2018-07-15 17:57:40 +02:00
|
|
|
play key move on
|
2019-01-08 22:48:18 +01:00
|
|
|
| Hanafuda.KoiKoi.playing on == key =
|
|
|
|
Hanafuda.KoiKoi.play move on
|
|
|
|
| otherwise = throwError "Not your turn"
|