1 {-# LANGUAGE FlexibleContexts #-}
6 import Control.Monad.State
7 import Control.Monad.Reader
8 import Control.Monad.Writer
16 data Hint = PartyAt Place
21 data PlayerInformation = PlayerInformation
23 , piHints :: [(Day,Hint)]
26 data Score = NoScore | ToFew | Scored
28 data IncomingMessage = InternalMessage InternalMessage
29 | DayMessage DayMessage
30 | NightMessage NightMessage
32 -- Events that we want to send to the user code and that
33 -- can be reacted upon
34 data DayMessage = DayStarts
35 -- Events that we want to send to the user code and that
36 -- can NOT be reacted upon
37 data NightMessage = NightStarts
38 -- Pure bookkeeping events
39 data InternalMessage = MyPlayerId Player
43 | PlayerJoined Player -- the game
45 | PlayerEnters Player Place
46 | PlayerLeaves Player Place
49 | PlayerScore [(Player, Int)]
50 | PlayerNames [(Player, String)]
60 | PlayerPosition Player Place -- wann bekommt man das?
66 data ClientMessage = Tell Player Hint
69 type DayCallback d = DayMessage -> DayMonad d ()
70 type NightCallback d = NightMessage -> NightMonad d ()
72 data ParttyState = ParttyState
75 , psPlayerInfo :: Map Player PlayerInformation
76 , psPartyHistory:: [(Day,Place)]
78 , psPlayers :: [Player]
81 type DayMonad d = WriterT [ClientMessage] (ReaderT ParttyState (StateT d IO))
82 type NightMonad d = ReaderT ParttyState (StateT d IO)
87 -- Hostname, Port, Playername, Callback
88 runPartty :: String -> Int -> String -> DayCallback d -> NightCallback d -> IO ()
92 runner :: Handle -> DayCallback d -> NightCallback d -> ParttyState -> d -> IO ()
93 runner h dcb ncb = fix $ \loop ps d -> do
94 (e,ps') <- getNextUserMessage h ps
95 (client_messages, d') <- case e of
96 Left dm -> undefined {- run -} dcb dm
97 Right nm -> undefined {- run -} dcb nm
98 undefined -- send_client_messages client_messages
101 getNextUserMessage :: Handle -> ParttyState -> IO (Either DayMessage NightMessage, ParttyState)
102 getNextUserMessage h ps = do
104 e <- undefined {- parseIncomingMessage -} line
105 let ps' = undefined {- updateState -} e ps
107 InternalMessage ue -> getNextUserMessage h ps'
108 DayMessage dm -> return (Left dm, ps')
109 NightMessage nm -> return (Right nm, ps')
111 -- Convenience functions for accessing the state
113 whoIsHere :: (MonadReader ParttyState m) => m [Player]
114 whoIsHere = asks psPlayers
116 gameDay :: (MonadReader ParttyState m) => m Day
119 -- Interaction: use “tell”