public static IPlayer CreateCompetitor(StrikeInfo strikeModel, Ball ball, Hole hole, User player, ExperimentHistory history, IBallKickPhysics ballKick)
        {
            if (history == null)
                throw new NullReferenceException("history");

            IPlayer competitor;

            var competitorModel = strikeModel.CompetitorModel;

            if (competitorModel == null)
                throw new NullReferenceException("Модель соперника не задана");

            if (competitorModel is UniformCompetitorModel)
            {
                competitor = new UniformCompetitor(ball, hole, strikeModel.CompetitorModel as UniformCompetitorModel, player, ballKick);
            }
            else if (competitorModel is NormalAdaptiveCompetitorModel)
            {
                var errorGenerator = new NormalAdaptiveCompetitorRandom(strikeModel.CompetitorModel as NormalAdaptiveCompetitorModel, history);

                competitor = new Competitor(ball.Position.X, hole.Position.X, errorGenerator, ballKick);
            }
            else if (competitorModel is UniformAdaptiveCompetitorModel)
            {
                var errorGenerator = new UniformAdaptiveCompetitorRandom(strikeModel.CompetitorModel as UniformAdaptiveCompetitorModel, history, strikeModel.Hole.Size, strikeModel.Ball.Size);

                competitor = new Competitor(ball.Position.X, hole.Position.X, errorGenerator, ballKick);
            }
            else
            {
                throw new InvalidOperationException($"Модель соперника \"{competitorModel.GetType().Name}\" не поддерживается");
            }

            return competitor;
        }
        public void Sample()
        {
            #region Конфигурирование
            var adaptiveCompetitorModel = new UniformAdaptiveCompetitorModel
            {
                HitProbabilityFactorIfPlayerHit = 1.2,
                HitProbabilityFactorIfPlayerMissed = 1,
                PlayerHistorySamples = new List<PlayerHistorySample>
                {
                    new PlayerHistorySample
                    {
                        GameTitle = "Game"
                    }
                }
            };

            var history = CreateHistory(hitCount: 50, size: 100, lastStrikeHit: true);

            var holeSize = 2;
            var ballSize = 1;

            #endregion

            var newSamples = new List<double>();

            var generator = new UniformAdaptiveCompetitorRandom(adaptiveCompetitorModel, history, holeSize, ballSize);

            var sampesSize = 1000;

            for (var j = 0; j < sampesSize; j++)
            {
                newSamples.Add(generator.Sample());
            }

            #region Оценка ошибки

            var a = (holeSize - ballSize)/2.0;

            double hitCounts = newSamples.Count(newSample => Math.Abs(newSample) < a);

            #endregion

            Assert.IsTrue(Math.Abs(hitCounts/sampesSize - 0.6) < 0.05);
        }
        public void Sample3()
        {
            #region Конфигурирование
            var adaptiveCompetitorModel = new UniformAdaptiveCompetitorModel
            {
                HitProbabilityFactorIfPlayerHit = 1,
                HitProbabilityFactorIfPlayerMissed = 0,
                PlayerHistorySamples = new List<PlayerHistorySample>
                {
                    new PlayerHistorySample
                    {
                        GameTitle = "Game"
                    }
                }
            };

            var history = CreateHistory(hitCount: 50, size: 100, lastStrikeHit: false);

            var holeSize = 2;
            var ballSize = 1;

            #endregion

            var newSamples = new List<double>();

            var generator = new UniformAdaptiveCompetitorRandom(adaptiveCompetitorModel, history, holeSize, ballSize);

            generator.Sample();
        }