예제 #1
0
        private void ValidateGameAndRules(GameRules rules)
        {
            if (_currentGame != null && !_currentGame.IsCompleted)
            {
                throw new InvalidOperationException("The current game hasn't been completed yet.");
            }

            var playersCount = Players.Count;

            if (playersCount == 0)
            {
                throw new InvalidOperationException("The game cannot be started without players.");
            }

            if (playersCount > MaxPlayersQuantity)
            {
                throw new InvalidOperationException($"Too much players. Maximum quantity is {MaxPlayersQuantity}");
            }

            if (playersCount < MinPlayersQuantity)
            {
                throw new InvalidOperationException(
                          $"There is no enough players. Minimum quantity is {MinPlayersQuantity}");
            }

            rules.Validate();
        }
예제 #2
0
        private void PrepareForStart(GameRules rules)
        {
            _commonAttempts.Clear();
            _gameRules = rules;

            foreach (var player in Players)
            {
                player.PrepareForTheNextGame();
            }
        }
예제 #3
0
        private Task <GameResult> StartGame(GameRules gameRules)
        {
            try
            {
                ValidateGameAndRules(gameRules);
            }
            catch (Exception e)
            {
                return(Task.FromResult(new GameResult
                {
                    Status = GameStatus.Failed,
                    ErrorMessage = e.Message
                }));
            }

            PrepareForStart(gameRules);

            _currentGame = Task.Run(async() =>
            {
                using (CancellationToken = new CancellationTokenSource())
                {
                    CancellationToken.CancelAfter(_gameRules.Timeout);

                    var plays = new List <Task>();

                    foreach (var player in Players)
                    {
                        var play = Task.Run(async() =>
                        {
                            while (!CancellationToken.IsCancellationRequested)
                            {
                                var delay = await MakeTurn(player);

                                await Task.Delay(TimeSpan.FromMilliseconds(delay));
                            }
                        }, CancellationToken.Token)
                                   .ContinueWith(task => { });

                        plays.Add(play);
                    }

                    await Task.WhenAll(plays);

                    return(GetGameResults());
                }
            });

            return(_currentGame);
        }
예제 #4
0
 public Task <GameResult> Start(GameRules gameRules)
 {
     return(StartGame(gameRules));
 }