public NinthPlanetServer CreateGameFromState(SavedGameState gameState)
        {
            var gameInfo = gameState.GameInfo;

            if (gameInfo is null)
            {
                throw new ArgumentException("Game info is empty.", nameof(gameState));
            }

            if (gameInfo.GameType != GameType.NinthPlanet)
            {
                throw new ArgumentException($"Expected game type to be {GameType.NinthPlanet} but {gameInfo.GameType} was found.", nameof(gameState));
            }

            if (loggerFactory is null)
            {
                throw new ArgumentNullException(nameof(loggerFactory));
            }

            var gameLobby = new GameLobby(
                gameInfo.Id,
                gameInfo.MaximumNumberOfPlayers,
                gameState.PlayersInLobby,
                loggerFactory.CreateLogger <GameLobby>());

            gameLobby.AddPlayer(gameInfo.OwnerId);

            GameRound gameRound = null;

            if (gameState.RoundState != null)
            {
                gameRound = gameRoundFactory.CreateGameRound(gameInfo, null);
            }

            return(new NinthPlanetServer(
                       gameInfo,
                       gameLobby,
                       gameRound,
                       gameRoundFactory,
                       loggerFactory.CreateLogger <NinthPlanetServer>()));
        }
Exemple #2
0
        public void BeginRound(int userId, IGameMessenger gameMessenger)
        {
            if (RoundInProgress)
            {
                throw new InvalidOperationException("Round is already running.");
            }

            if (userId != GameOwnerId)
            {
                throw new InvalidOperationException("Only game owner can start round.");
            }

            // time based rng will suffice
            var rng            = new Random();
            var playersAtTable = this.playerLobby.PlayersInLobby.ToList();
            var playerStates   = this.playerLobby.PlayersInLobby.ToDictionary(x => x, x => new PlayerPrivateState());

            var cardDeck = DeckBuilder.CreateCardDeck();

            cardDeck = cardDeck.FisherYatesShuffle(rng);

            int playerIndex = 0;

            // deal cards
            foreach (var card in cardDeck)
            {
                var playerId = playersAtTable[playerIndex];
                playerIndex = (++playerIndex) % playersAtTable.Count;

                var playerState = playerStates[playerId];
                playerState.CardsInHand.Add(card);
            }

            foreach (var playerId in playersAtTable)
            {
                var playerState = playerStates[playerId];
                playerState.CardsInHand.Sort(new CardComparer());
            }

            var goalDeck = DeckBuilder.CreateGoalDeck();

            goalDeck = goalDeck.FisherYatesShuffle(rng);

            var playerOrder = playersAtTable.FisherYatesShuffle(rng);
            var captain     = playerOrder[rng.Next(0, playerOrder.Count - 1)];

            this.currentRound = gameRoundFactory.CreateGameRound(
                GameInfo,
                new SavedRoundState
            {
                CaptainPlayerId = captain,
                CurrentPlayerId = captain,
                AvailableGoals  = goalDeck.Take(5).Select(x => new TaskCard {
                    Card = x
                }).ToList(),
                PlayerStates        = playerStates,
                ColorOfCurrentTrick = null,
                HelpIsAvailable     = true,
                PlayerOrder         = playerOrder
            });

            foreach (var playerId in playersAtTable)
            {
                // each player can see different board state.
                var msg = CreateGameMsg <GameHasStarted>();
                msg.State = this.GetGameState(playerId);
                gameMessenger.SendMessage(msg, playerId);
            }
            ;
        }