示例#1
0
        public static double NextGaussian(double mu = 0, double sigma = 1)
        {
            double x, u, v, s;

            if (isStored)
            {
                isStored = !isStored;
                return(prevGauss * sigma + mu);
            }
            do
            {
                u = 2 * StaticRandom.NextDouble() - 1;
                v = 2 * StaticRandom.NextDouble() - 1;
                s = u * u + v * v;
            } while (s >= 1 || s == 0);
            x         = Math.Sqrt(-2 * Math.Log(s) / s);
            prevGauss = x * u;
            isStored  = !isStored;
            return(x * v * sigma + mu);
        }
示例#2
0
        /// <summary>
        /// Вычисляет время прохождения отсечки k биатлонистом под номером curAthlete
        /// </summary>
        /// <param name="curSection">Текущая отсечка</param>
        /// <param name="curAthlete">Номер биатлониста</param>
        /// <returns>Возвращает время в формате TimeSpan</returns>
        private TimeSpan sectionPassTime(int curAthlete, int lap, int k)
        {
            double curSection  = course.Sections[k];
            double prevSection = course.Sections[k - 1];
            int    j           = 1;
            int    stamina;
            int    gStamina = athletes[curAthlete].Stamina;
            double result   = 0.0;

            double[] points = new double[course.Profile.Count];

            course.Profile.Keys.CopyTo(points, 0);
            while (points[j] <= prevSection)
            {
                j++;
            }
            do
            {
                stamina = athletes[curAthlete].CurStamina;
                double speed  = 0.0;
                double height = course.Profile[points[j]] - course.Profile[points[j - 1]]; // Вычисление коэффициента
                double tg     = height / (points[j] - points[j - 1]);                      // наклона участка
                double length = Math.Min(points[j], curSection) -
                                Math.Max(points[j - 1], prevSection);

                double rand = StaticRandom.RandGaussian(stamina / (double)gStamina * 0.12 +
                                                        0.94 + (lap - Laps / 2.0) / 50.0, 0.02);
                speed = rand * calcSpeed(athletes[curAthlete], tg) / 60;
                var time = results[curAthlete].TimeStamps[lap, k - 1].Value.TotalMinutes;

                if (stamina < 5)
                {
                    speed -= speed / 10.0;
                }
                if (weather.Type.ToString().Contains("Frost"))
                {
                    if (Type == RaceTypes.Individual || Type == RaceTypes.Sprint)
                    {
                        speed += (speed / 20.0) * (time + curAthlete * 0.5) / 100;
                    }
                    else
                    {
                        speed += (speed / 20.0) * time / 100;
                    }
                }
                else if (weather.Type.ToString().Contains("Sun"))
                {
                    if (Type == RaceTypes.Individual || Type == RaceTypes.Sprint)
                    {
                        speed -= (speed / 25.0) * (time + curAthlete * 0.5) / 100;
                    }
                    else
                    {
                        speed -= (speed / 25.0) * time / 100;
                    }
                }
                else if (weather.Type.ToString().Contains("Rain"))
                {
                    speed -= speed / 15.0;
                }
                speed *= StaticRandom.RandDouble(1, athletes[curAthlete].Skis.Quality / 100.0 + 1);

                athletes[curAthlete].Attributes.calculateStamina(tg, rand, length);

                /*
                 * if (tg < -0.02)                                                             //
                 * {                                                                           //
                 * speed = StaticRandom.NextDouble(0.99, 1.01) *                             //
                 *        athletes[curAthlete].Attributes.DescentSpeed / 60.0;              // Вычисление скорости в км/мин
                 * if ((2 * rand < stamina) && (stamina > 30))                               //
                 * {
                 *  //speedup = '+';//
                 *  rand = StaticRandom.NextDouble();
                 *  speed += rand * speed / 20.0;                                           // Ускорение с потерей
                 *  athletes[curAthlete].Attributes.Tired(rand * (-1 / tg) / 200, 0.1);     // выносливости
                 * }                                                                         //
                 * else                                                                      //
                 *  athletes[curAthlete].Attributes.Rest(length);                           // Восстановление выносливости
                 * if (stamina < 5)                                                          //
                 *  speed -= speed / 10.0;                                                  // При низкой выносливости -
                 * }                                                                           // снижение скорости
                 * else                                                                        //
                 * if (tg > 0.02)                                                            //
                 * {                                                                         //
                 *  speed = StaticRandom.NextDouble(0.99, 1.01) *                           //
                 *          athletes[curAthlete].Attributes.AscentSpeed / 60.0;             // Вычисление скорости в км/мин
                 *  if (2 * rand < stamina)                                                 //
                 *  {
                 *    //speedup = '+';//
                 *    rand = StaticRandom.NextDouble();
                 *    speed += rand*speed / 20.0;                                           // Ускорение с потерей
                 *    athletes[curAthlete].Attributes.Tired(rand * 2 * tg, length);         // выносливости
                 *  }                                                                       //
                 *  else                                                                    // Стандартная потеря
                 *    athletes[curAthlete].Attributes.Tired(tg, length);                    //    выносливости при подъеме
                 *  if (stamina < 5)                                                        // При низкой выносливости -
                 *    speed -= speed / 10.0;                                                //    снижение скорости
                 * }                                                                         //
                 * else                                                                      //
                 * {                                                                         //
                 *  speed = StaticRandom.NextDouble(0.99, 1.01) *                           //
                 *          athletes[curAthlete].Attributes.PlainSpeed / 60.0;              // Вычисление скорости в км/мин
                 *  if (2 * rand < stamina)                                                 //
                 *  {
                 *    //speedup = '+';//
                 *    rand = StaticRandom.NextDouble();
                 *    speed += rand * speed / 20.0;                                         // Ускорение с потерей
                 *    athletes[curAthlete].Attributes.Tired(rand * tg, length);             // выносливости
                 *  }                                                                       //
                 *  if (stamina < 5)                                                        // При низкой выносливости -
                 *    speed -= speed / 10.0;                                                // снижение скорости
                 * }                                                                         //*/

                result += length / speed;                                           // Вычисление времени
                                                                                    // прохождения участка
            } while (points[j++] < curSection);
            delay(result * 1000);
            staminas.stamina[curAthlete, lap *(course.Sections.Length - 1) + k - 1] = athletes[curAthlete].CurStamina;
            return(TimeSpan.FromMinutes(result));
        }
示例#3
0
        /// <summary>
        /// Вычисляет результат стрельбы и затраченное на неё время
        /// </summary>
        /// <param name="curLap">Текущий круг</param>
        /// <param name="curAthlete">Номер биатлониста</param>
        /// <returns>Возвращает время в формате TimeSpan</returns>
        private TimeSpan range(int curAthlete, int curLap)
        {
            int    penaltyLaps   = 0;
            double curAcc        = 0.0;
            double curPrep       = 0.0;
            double shootingSpeed = 0.0;
            double result        = 0.0;
            double windVelocity  = 0.0;
            double time          = results[curAthlete].TimeStamps.Last(curLap).Value.TotalMinutes;

            if (type.Type == RaceTypes.Individual)
            {
                time -= results[curAthlete].Range.Misses(curLap);
            }
            if (RangeDistr[curLap] == 'p')
            {
                curAcc        = athletes[curAthlete].ProneAccuracy;                 // Точность, скорость стрельбы
                curPrep       = athletes[curAthlete].PronePreparation / 60.0;       // (в секундах)
                shootingSpeed = athletes[curAthlete].ProneSpeed;                    // и время подготовки
            }                                                                       // (в минутах)
            else                                                                    // в зависимости от типа стрельбы
            {                                                                       //
                curAcc        = athletes[curAthlete].StandingAccuracy;              //
                curPrep       = athletes[curAthlete].StandingPreparation / 60.0;    //
                shootingSpeed = athletes[curAthlete].StandingSpeed;                 //
            }
            result += curPrep;
            delay(curPrep * 1000 / 2);
            if (Type == RaceTypes.Individual || Type == RaceTypes.Sprint)           // Вычисление силы ветра
            {
                time += curAthlete * 0.5;                                           // в данный момент времени
            }
            for (int i = 0; i < 5; i++)
            {
                windVelocity =                                                                            // Сила ветра во время
                               weather.WindSpeed[(int)Math.Floor(time / 100 * weather.WindSpeed.Length)]; // выстрела

                double shotTime = (shootingSpeed / 5 + windVelocity * 0.5 *                               // Вычисление времени,
                                   (StaticRandom.RandDouble() - 0.25)) / 60.0;                            // затраченного на выстрел

                delay(shotTime * 1000);
                time += shotTime;

                double shotAcc = curAcc - Math.Pow(windVelocity / 10.0, 2) *        // Вычисление точности стрельбы
                                 (1 - athletes[curAthlete].WindResistance / 100.0); // при данных ветровых условиях

                double a = StaticRandom.RandDouble();                               // Вычисление попадания
                if (a < shotAcc)                                                    // и количества штрафных
                {
                    results[curAthlete].Hit(curLap, i);                             // кругов
                }
                else                                                                //
                {
                    penaltyLaps++;                                                  //
                }
                result += shotTime;
            }
            delay(curPrep * 1000 / 2);
            if (Type == RaceTypes.Individual)
            {
                time = penaltyLaps;
            }
            else
            {
                athletes[curAthlete].Attributes.calculateStamina(0, 1,
                                                                 penaltyLaps * penaltyLap / 1000);
                time = penaltyLaps * (penaltyLap / 1000 /
                                      (athletes[curAthlete].PlainSpeed / 60.0));
                delay(time * 1000);
            }
            athletes[curAthlete].Attributes.Rest(0.2);
            result += time;
            return(TimeSpan.FromMinutes(result));
        }