Skat Engine und AI auf Haskell Basis
25'ten fazla konu seçemezsiniz Konular bir harf veya rakamla başlamalı, kısa çizgiler ('-') içerebilir ve en fazla 35 karakter uzunluğunda olabilir.

96 satır
3.2KB

  1. {-# LANGUAGE TypeSynonymInstances #-}
  2. {-# LANGUAGE FlexibleInstances #-}
  3. {-# LANGUAGE OverloadedStrings #-}
  4. module Skat.AI.Online where
  5. import Control.Monad.Reader
  6. import Network.WebSockets (Connection, sendTextData, receiveData)
  7. import Data.Aeson
  8. import qualified Data.ByteString.Lazy.Char8 as BS
  9. import Skat.Player
  10. import qualified Skat.Player.Utils as P
  11. import Skat.Pile
  12. import Skat.Card
  13. import Skat.Render
  14. class Monad m => MonadClient m where
  15. query :: String -> m ()
  16. response :: m String
  17. data OnlineEnv = OnlineEnv { getTeam :: Team
  18. , getHand :: Hand
  19. , connection :: Connection }
  20. deriving Show
  21. instance Show Connection where
  22. show _ = "A connection"
  23. instance Player OnlineEnv where
  24. team = getTeam
  25. hand = getHand
  26. chooseCard p table _ hand = runReaderT (choose table hand) p >>= \c -> return (c, p)
  27. onCardPlayed p c = runReaderT (cardPlayed c) p >> return p
  28. onGameResults p res = runReaderT (onResults res) p
  29. onGameStart p singlePlayer = runReaderT (onStart singlePlayer) p
  30. type Online m = ReaderT OnlineEnv m
  31. instance MonadIO m => MonadClient (Online m) where
  32. query s = do
  33. conn <- asks connection
  34. liftIO $ sendTextData conn (BS.pack s)
  35. response = do
  36. conn <- asks connection
  37. liftIO $ BS.unpack <$> receiveData conn
  38. instance MonadPlayer m => MonadPlayer (Online m) where
  39. trumpColour = lift $ trumpColour
  40. turnColour = lift $ turnColour
  41. showSkat = lift . showSkat
  42. choose :: MonadPlayer m => [CardS Played] -> [Card] -> Online m Card
  43. choose table hand = do
  44. query (BS.unpack $ encode $ ChooseQuery hand table)
  45. r <- response
  46. case decode (BS.pack r) of
  47. Just (ChosenResponse card) -> do
  48. allowed <- P.isAllowed hand card
  49. if card `elem` hand && allowed then return card else choose table hand
  50. Nothing -> choose table hand
  51. cardPlayed :: MonadPlayer m => CardS Played -> Online m ()
  52. cardPlayed card = query (BS.unpack $ encode $ CardPlayedQuery card)
  53. onResults :: MonadIO m => (Int, Int) -> Online m ()
  54. onResults (sgl, tm) = query (BS.unpack $ encode $ GameResultsQuery sgl tm)
  55. onStart :: MonadPlayer m => Hand -> Online m ()
  56. onStart singlePlayer = do
  57. trCol <- trumpColour
  58. ownHand <- asks getHand
  59. query (BS.unpack $ encode $ GameStartQuery trCol ownHand singlePlayer)
  60. data Query = ChooseQuery [Card] [CardS Played]
  61. | CardPlayedQuery (CardS Played)
  62. | GameResultsQuery Int Int
  63. | GameStartQuery Colour Hand Hand
  64. data Response = ChosenResponse Card
  65. instance ToJSON Query where
  66. toJSON (ChooseQuery hand table) =
  67. object ["query" .= ("choose_card" :: String), "hand" .= hand, "table" .= table]
  68. toJSON (CardPlayedQuery card) =
  69. object ["query" .= ("card_played" :: String), "card" .= card]
  70. toJSON (GameResultsQuery sgl tm) =
  71. object ["query" .= ("results" :: String), "single" .= sgl, "team" .= tm]
  72. toJSON (GameStartQuery trumps handNo sglPlayer) =
  73. object ["query" .= ("start_game" :: String), "trumps" .= show trumps,
  74. "hand" .= toInt handNo, "single" .= toInt sglPlayer]
  75. instance FromJSON Response where
  76. parseJSON = withObject "ChosenResponse" $ \v -> ChosenResponse
  77. <$> v .: "card"