Stop imposing only one game per user, it was silly and finally harder to do well than to simply keep games by ID and allow several games in parallel for one user

This commit is contained in:
Tissevert 2020-01-25 11:54:27 +01:00
parent 9270ce17aa
commit b95a7c958d
2 changed files with 23 additions and 25 deletions

View file

@ -10,13 +10,13 @@ import Data.Aeson (encode, eitherDecode')
import Data.ByteString.Lazy.Char8 (ByteString, append, pack, putStrLn) import Data.ByteString.Lazy.Char8 (ByteString, append, pack, putStrLn)
import qualified Data.ByteString.Lazy.Char8 as ByteString (concat) import qualified Data.ByteString.Lazy.Char8 as ByteString (concat)
import Data.Map ((!)) import Data.Map ((!))
import qualified Data.Map as Map (delete, empty, member) import qualified Data.Map as Map (delete, empty, lookup)
import Control.Monad.Reader (ReaderT, ask) import Control.Monad.Reader (ReaderT, ask)
import Control.Monad.Trans (lift) import Control.Monad.Trans (lift)
import Hanafuda.KoiKoi (Step(..)) import Hanafuda.KoiKoi (Step(..))
import Hanafuda.Message (Coordinates(..), FromClient(..), T(..), orderCoordinates) import Hanafuda.Message (FromClient(..), T(..), orderCoordinates)
import qualified Hanafuda.Message as Message ( import qualified Hanafuda.Message as Message (
T(..), FromClient, PublicGame(..), PublicState(..) Coordinates(..), FromClient, PublicGame(..), PublicState(..), T(..)
) )
import Network.WebSockets (Connection, receiveData, sendTextData) import Network.WebSockets (Connection, receiveData, sendTextData)
import Prelude hiding (error, putStrLn) import Prelude hiding (error, putStrLn)
@ -58,16 +58,14 @@ answer (Message.Relay {Message.from, Message.message = Message.LogIn {Message.na
| from == key = return $ LoggedIn {key, name} | from == key = return $ LoggedIn {key, name}
-} -}
answer state@(Connected {games}) (Relay {from, message = Invitation {}}) = answer state@(Connected {}) (Relay {from, message = Invitation {}}) =
-- policy : one game per player only send (Answer {accept = True, to = from}) >> return state
send (Answer {accept = not $ Map.member from games, to = from})
>> return state
answer state@(Connected {playerID, games}) message@(Game {}) = do answer state@(Connected {playerID, games}) message@(Game {}) = do
case Message.step $ Message.public game of case Message.step $ Message.public game of
Over -> Over ->
let opponentID = Message.nextPlayer (Message.public game) ! playerID in let xGameID = Message.gameID . Message.coordinates $ Message.public game in
return $ state {games = Map.delete opponentID games} return $ state {games = Map.delete xGameID games}
_ -> _ ->
if Message.playing (Message.public game) == playerID if Message.playing (Message.public game) == playerID
then then
@ -82,21 +80,21 @@ answer state (Error {error}) = do
debug $ "Received error from server : " `append` pack error debug $ "Received error from server : " `append` pack error
return state return state
answer state@(Connected {games}) (Relay {from, message = Sync {latestKnown}}) answer state@(Connected {games}) (Relay {from, message = Sync {latestKnown}}) =
| not $ Map.member from games = case Map.lookup gameID games of
send (Yield {onGameID = gameID latestKnown, to = from}) >> return state Nothing -> send $ Yield {onGameID = gameID, to = from}
| otherwise = Just game ->
case orderCoordinates latestKnownHere latestKnown of let latestKnownHere = Message.coordinates $ Message.public game in
Just LT -> send $ Yield {onGameID = gameID latestKnown, to = from} case orderCoordinates latestKnown latestKnownHere of
Just GT -> send $ Share {gameSave = game} Just LT -> send $ Share {gameSave = game}
Just GT -> send $ Yield {onGameID = gameID, to = from}
_ -> return () _ -> return ()
>> return state >> return state
where where
game = games ! from gameID = Message.gameID latestKnown
latestKnownHere = Message.coordinates $ Message.public game
answer state@(Connected {games}) (Relay {from, message = Yield {}}) = answer state@(Connected {games}) (Relay {message = Yield {onGameID}}) =
send (Share {gameSave = games ! from}) >> return state send (Share {gameSave = games ! onGameID}) >> return state
{- {-
- Ignore - Ignore

View file

@ -8,7 +8,7 @@ module Session (
import Config (libDir) import Config (libDir)
import Data.Map (Map) import Data.Map (Map)
import qualified Data.Map as Map (empty) import qualified Data.Map as Map (empty)
import Hanafuda.KoiKoi (PlayerID) import Hanafuda.KoiKoi (GameID, PlayerID)
import qualified Hanafuda.Message as Message (PublicGame) import qualified Hanafuda.Message as Message (PublicGame)
import System.Directory (createDirectoryIfMissing, doesFileExist) import System.Directory (createDirectoryIfMissing, doesFileExist)
import System.FilePath ((</>)) import System.FilePath ((</>))
@ -17,7 +17,7 @@ data State =
New New
| Connected { | Connected {
playerID :: PlayerID playerID :: PlayerID
, games :: Map PlayerID Message.PublicGame , games :: Map GameID Message.PublicGame
} }
deriving Show deriving Show