Skat Engine und AI auf Haskell Basis
25개 이상의 토픽을 선택하실 수 없습니다. Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

99 lines
2.8KB

  1. {-# LANGUAGE TypeSynonymInstances #-}
  2. {-# LANGUAGE FlexibleInstances #-}
  3. {-# LANGUAGE FlexibleContexts #-}
  4. module AI.Socket (
  5. mkSocketEnv
  6. ) where
  7. import Control.Monad.Trans (liftIO)
  8. import Control.Monad.Reader
  9. import Control.Monad.State
  10. import Control.Concurrent
  11. import Control.Concurrent.Chan
  12. import Player
  13. import Pile
  14. import Card
  15. import Utils
  16. import Render
  17. import AI.Server
  18. data SocketEnv = SocketEnv { getTeam :: Team
  19. , getHand :: Hand
  20. , table :: [CardS Played]
  21. , myHand :: [Card]
  22. , socketThread :: Maybe ThreadId
  23. , socketServer :: Maybe ServerEnv }
  24. deriving Show
  25. setTable :: [CardS Played] -> SocketEnv -> SocketEnv
  26. setTable tab env = env { table = tab }
  27. setHand :: [Card] -> SocketEnv -> SocketEnv
  28. setHand hand env = env { myHand = hand }
  29. setSocket :: ThreadId -> SocketEnv -> SocketEnv
  30. setSocket n env = env { socketThread = Just n }
  31. clearSocket :: SocketEnv -> SocketEnv
  32. clearSocket env = env { socketThread = Nothing }
  33. setServer :: ServerEnv -> SocketEnv -> SocketEnv
  34. setServer s env = env { socketServer = Just s }
  35. type Socket m = StateT SocketEnv m
  36. instance MonadPlayer m => MonadPlayer (Socket m) where
  37. trumpColour = lift $ trumpColour
  38. turnColour = lift $ turnColour
  39. showSkat = lift . showSkat
  40. instance Player SocketEnv where
  41. team = getTeam
  42. hand = getHand
  43. chooseCard p table _ hand = runStateT (do
  44. modify $ setTable table
  45. modify $ setHand hand
  46. choose) p
  47. choose :: MonadPlayer m => Socket m Card
  48. choose = do
  49. initialize
  50. trumpCol <- trumpColour
  51. turnCol <- turnColour
  52. hand <- gets myHand
  53. (Just server) <- gets socketServer
  54. liftIO $ writeChan (global server) "hi"
  55. let possible = filter (isAllowed trumpCol turnCol hand) hand
  56. case length hand of
  57. 1 -> liftIO (putStrLn "stopping server") >> stop
  58. _ -> return ()
  59. return $ head possible
  60. initialize :: MonadPlayer m => Socket m ()
  61. initialize = do
  62. state <- gets socketThread
  63. case state of
  64. Just _ -> return ()
  65. Nothing -> do
  66. liftIO $ putStrLn "initializing server"
  67. server <- liftIO $ initServer 4242 (DelimiterBuffering "\n") sampleHandler
  68. n <- liftIO $ forkIO $ runReaderT procRequests server
  69. modify $ setSocket n
  70. modify $ setServer server
  71. stop :: MonadPlayer m => Socket m ()
  72. stop = do
  73. state <- gets socketThread
  74. case state of
  75. Just n -> do liftIO $ putStrLn "killing thread"
  76. liftIO $ killThread n
  77. modify clearSocket
  78. Just server <- gets socketServer
  79. liftIO $ close server
  80. Nothing -> return ()
  81. mkSocketEnv :: Team -> Hand -> SocketEnv
  82. mkSocketEnv tm h = SocketEnv tm h [] [] Nothing Nothing