Exemple #1
0
        public async Task <Game> JoinAsync(Game passedGame)
        {
            await _repository.AddOrUpdatePlayerGameAsync(_playerIdentity.Id, Player.Game.From(_playerIdentity.Id, passedGame));

            if (passedGame.MaxPlayers == passedGame.Players.Count)
            {
                var playerOrders = _uniqueRandomRangeCreator.CreateArrayWithAllNumbersFromRange(passedGame.Players.Count);
                var game         = await _repository.StartGameAsync(passedGame.Id !, playerOrders);

                if (game != null)
                {
                    foreach (var player in game.Players)
                    {
                        await _repository.AddOrUpdatePlayerGameAsync(player.Id, Player.Game.From(player.Id, game));
                    }

                    await _gameHub.GameStartedAsync(game);

                    return(game);
                }
            }
            else
            {
                await _gameHub.PlayerAddedAsync(passedGame);
            }

            return(passedGame);
        }
        public async Task Should_throw_when_adding_game_to_player_for_unknown_player()
        {
            var player = new PlayerBuilder()
                         .Einstein
                         .Build();
            var game = Player.Game.From(player.Id, new GameBuilder().FirstPlayerEinstein.RandomId);

            // Act
            await Assert.ThrowsAsync <UpdateException>(() => _repository.AddOrUpdatePlayerGameAsync(player.Id, game));
        }
            public async Task <TicTacToe> Handle(AddTicTacToeStepCommand request, CancellationToken cancellationToken)
            {
                var game = await _gameRepository.GetAsync <TicTacToe>(request.GameId);

                if (game == null)
                {
                    throw new ItemNotFoundException();
                }

                if (game.Status != GameStatus.InGame)
                {
                    throw new ValidationException("Game is not yet or no longer playable");
                }

                if (request.CellIndex < 0 || request.CellIndex >= TicTacToe.CellCount)
                {
                    throw new ValidationException($"Invalid cell index, it should be greather than zero and less than {TicTacToe.CellCount}");
                }

                if (game.Cells[request.CellIndex] != null)
                {
                    throw new ValidationException("This cell has already a value");
                }

                var nextPlayer = game.NextPlayer;

                if (nextPlayer.Id != _playerIdentity.Id)
                {
                    throw new ValidationException($"It is not your turn to play, current player is {nextPlayer.Id}");
                }

                game.Cells[request.CellIndex] = new TicTacToe.CellData()
                {
                    Number = game.TickedCellsCount + 1
                };
                var won = game.HasWon();

                game.Status = won || game.AllCellsTicked
                    ? GameStatus.Finished
                    : GameStatus.InGame;

                if (game.Status != GameStatus.InGame)
                {
                    foreach (var player in game.Players)
                    {
                        bool isMe = player.Id == _playerIdentity.Id;
                        player.Status = (won, isMe) switch {
                            (true, true) => player.Status  = PlayerGameStatus.Won,
                            (true, false) => player.Status = PlayerGameStatus.Lost,
                            _ => PlayerGameStatus.Draw
                        };
                    }
                }

                await _ticTacToeRepository.SetTicTacToeStepAsync(game, request.CellIndex);

                // remark: we should probably use a transaction as we update both Collections
                if (game.Status != GameStatus.InGame)
                {
                    foreach (var player in game.Players)
                    {
                        // since game status changed we want to reflect that in Player collection
                        await _gameRepository.AddOrUpdatePlayerGameAsync(player.Id, Player.Game.From(player.Id, game));
                    }
                }

                await _gameHub.CustomAsync <TicTacToe, TransferObjects.TicTacToe>("GameStepAdded", game);

                return(game);
            }