コード例 #1
0
ファイル: GamePlayService.cs プロジェクト: luhis/card-hero
        async Task IGamePlayService.MakeMoveAsync(MoveModel move, CancellationToken cancellationToken)
        {
            var game = await ValidateMoveInternalAsync(move, cancellationToken : cancellationToken);

            var turns = await _turnRepository.GetTurnsByGameIdAsync(game.Id, cancellationToken : cancellationToken);

            var currentTurn = turns
                              .Where(x => !x.EndTime.HasValue)
                              .OrderByDescending(x => x.StartTime)
                              .FirstOrDefault();

            var turnUpdate = new TurnUpdateData
            {
                EndTime = DateTime.UtcNow,
            };

            await _turnRepository.UpdateTurnAsync(currentTurn.Id, turnUpdate, cancellationToken : cancellationToken);

            var currentMove = new MoveData
            {
                GameDeckCardCollectionId = move.GameDeckCardCollectionId,
                Column = move.Column,
                Row    = move.Row,
                TurnId = currentTurn.Id,
            };

            await _moveRepository.AddMoveAsync(currentMove, cancellationToken : cancellationToken);

            var nextUserId = game.UserIds
                             .SkipWhile(x => x != move.UserId)
                             .Skip(1)
                             .FirstOrDefault();

            if (nextUserId == default)
            {
                nextUserId = game.UserIds.First();
            }

            var newTurn = new TurnData
            {
                CurrentUserId = nextUserId,
                GameId        = game.Id,
                StartTime     = DateTime.UtcNow,
            };

            await _turnRepository.AddTurnAsync(newTurn, cancellationToken : cancellationToken);

            var gameUpdate = new GameUpdateData
            {
                CurrentUserId = nextUserId,
            };
            await _gameRepository.UpdateGameAsync(game.Id, gameUpdate, cancellationToken : cancellationToken);
        }
コード例 #2
0
        private async Task PrepareGameForPlayAsync(int id, int[] userIds, CancellationToken cancellationToken)
        {
            var randomUserIds = userIds.OrderBy(x => RandomNumberGenerator.GetInt32(int.MinValue, int.MaxValue)).ToArray();
            var currentUserId = randomUserIds[0];

            var updateGame = new GameUpdateData
            {
                CurrentUserId = currentUserId,
            };

            await _gameRepository.UpdateGameAsync(id, updateGame, cancellationToken : cancellationToken);

            await _gameRepository.UpdateGameUsersOrderAsync(id, randomUserIds, cancellationToken : cancellationToken);

            var newTurn = new TurnData
            {
                CurrentUserId = currentUserId,
                GameId        = id,
            };
            await _turnRepository.AddTurnAsync(newTurn, cancellationToken : cancellationToken);
        }
コード例 #3
0
ファイル: GameService.cs プロジェクト: luhis/card-hero
        private async Task AddUserToGameInternalAsync(int id, int userId, int deckId, CancellationToken cancellationToken = default)
        {
            var game = await _gameRepository.GetGameByIdAsync(id);

            if (game == null)
            {
                throw new InvalidGameException($"Game { id } does not exist.");
            }

            var gameUsers = await _gameRepository.GetGameUsersAsync(id, cancellationToken : cancellationToken);

            if (gameUsers.Any(x => x.Id == userId))
            {
                throw new InvalidPlayerException($"User { userId } is already in game { id }.");
            }

            var gul = gameUsers.Length;

            if (gul >= game.MaxPlayers)
            {
                throw new InvalidPlayerException($"Game { id } is already filled.");
            }

            var deck = await _deckRepository.GetDeckByIdAsync(deckId, userId, cancellationToken : cancellationToken);

            if (deck == null)
            {
                throw new InvalidDeckException($"Deck { deckId } does not exist.");
            }

            if (deck.UserId != userId)
            {
                throw new InvalidDeckException($"Deck { deckId } does not belong to user { userId }.");
            }

            var dc  = deck.Cards.Select(x => x.CardId).ToArray();
            var dcc = dc.Length;

            if (dcc < deck.MaxCards)
            {
                throw new InvalidDeckException($"Deck { deckId } needs { deck.MaxCards } cards. Currently only has { dcc }.");
            }

            await _gameDeckRepository.AddGameDeckAsync(id, userId, deck.Name, deck.Description, dc, cancellationToken : cancellationToken);

            if (gul + 1 == game.MaxPlayers)
            {
                var allUsers       = gameUsers.Select(x => x.Id).Concat(new int[] { userId }).ToArray();
                var currentUserIdx = new Random().Next(0, allUsers.Length);
                var currentUserId  = allUsers[currentUserIdx];
                var updateGame     = new GameUpdateData
                {
                    CurrentUserId = currentUserId,
                };

                await _gameRepository.UpdateGameAsync(id, updateGame, cancellationToken : cancellationToken);

                var newTurn = new TurnData
                {
                    CurrentUserId = currentUserId,
                    GameId        = game.Id,
                };
                await _turnRepository.AddTurnAsync(newTurn, cancellationToken : cancellationToken);
            }
        }