{-# LANGUAGE TypeSynonymInstances #-} {-# LANGUAGE FlexibleInstances #-} {-# LANGUAGE FlexibleContexts #-} module AI.Socket ( mkSocketEnv ) where import Control.Monad.Trans (liftIO) import Control.Monad.Reader import Control.Monad.State import Control.Concurrent import Control.Concurrent.Chan import Player import Pile import Card import Utils import Render import AI.Server data SocketEnv = SocketEnv { getTeam :: Team , getHand :: Hand , table :: [CardS Played] , myHand :: [Card] , socketThread :: Maybe ThreadId , socketServer :: Maybe ServerEnv } deriving Show setTable :: [CardS Played] -> SocketEnv -> SocketEnv setTable tab env = env { table = tab } setHand :: [Card] -> SocketEnv -> SocketEnv setHand hand env = env { myHand = hand } setSocket :: ThreadId -> SocketEnv -> SocketEnv setSocket n env = env { socketThread = Just n } clearSocket :: SocketEnv -> SocketEnv clearSocket env = env { socketThread = Nothing } setServer :: ServerEnv -> SocketEnv -> SocketEnv setServer s env = env { socketServer = Just s } type Socket m = StateT SocketEnv m instance MonadPlayer m => MonadPlayer (Socket m) where trumpColour = lift $ trumpColour turnColour = lift $ turnColour showSkat = lift . showSkat instance Player SocketEnv where team = getTeam hand = getHand chooseCard p table _ hand = runStateT (do modify $ setTable table modify $ setHand hand choose) p choose :: MonadPlayer m => Socket m Card choose = do initialize trumpCol <- trumpColour turnCol <- turnColour hand <- gets myHand (Just server) <- gets socketServer liftIO $ writeChan (global server) "hi" let possible = filter (isAllowed trumpCol turnCol hand) hand case length hand of 1 -> liftIO (putStrLn "stopping server") >> stop _ -> return () return $ head possible initialize :: MonadPlayer m => Socket m () initialize = do state <- gets socketThread case state of Just _ -> return () Nothing -> do liftIO $ putStrLn "initializing server" server <- liftIO $ initServer 4242 (DelimiterBuffering "\n") sampleHandler n <- liftIO $ forkIO $ runReaderT procRequests server modify $ setSocket n modify $ setServer server stop :: MonadPlayer m => Socket m () stop = do state <- gets socketThread case state of Just n -> do liftIO $ putStrLn "killing thread" liftIO $ killThread n modify clearSocket Just server <- gets socketServer liftIO $ close server Nothing -> return () mkSocketEnv :: Team -> Hand -> SocketEnv mkSocketEnv tm h = SocketEnv tm h [] [] Nothing Nothing