示例#1
0
文件: Tactic.cs 项目: Cycli/Cycli
        public override void Evaluate(RaceSpot myRs, RaceSpot[] rs)
        {
            Likelihood = 0;
            double thisProgress = _Race.RaceType.PercentComplete(myRs);
            double deltaProgress = thisProgress - _LastProgress;
            // This is a proactive tactic, so we same the likelihood

            double l = GetLikelihood(myRs);
            double scaledLikelihood = l * (1.0 - Math.Exp(-AGGRESSIVE_ATTACKS_PER_RACE * 0.04 * deltaProgress));
            // Use the score as a monte-carlo distribution
            if (_Rnd.NextDouble() < scaledLikelihood)
            {

                    // Am I in any sort of group and is that group going at less than my 5 minute pace
                double breakSpeed = TurboTrainer.PowerNormalisedSpeed(_Motor.PowerBands[1]);
                if (InGroup(myRs, rs) && myRs.s > 0 && myRs.s < breakSpeed)
                {
                    // initial target speed = 15-30% of existing speed
                    // Target break - between 30 secs and 2.5 minutes
                    _StopTime = myRs.t + 30000 + (ulong)(120000 * _Rnd.NextDouble());
                    RequestedPower = _Motor.PowerBands[1];      // Break at 5 minute
                    Likelihood = l;
                }
            }
            _LastProgress = thisProgress;
        }
示例#2
0
 public override double EstimatedTimeToFinish(RaceSpot rs, double atSpeed)
 {
     // Simple - no need for speed
     if (atSpeed > 0.0) {
     // Speed is KM per Hr
     return (_Target -rs.d) / (atSpeed * KMPH_TO_M_PER_SEC);
     }
     return double.MaxValue;
 }
示例#3
0
文件: Rider.cs 项目: Cycli/Cycli
        private void ChooseTactic(RaceSpot myRs, RaceSpot[] rs)
        {
            double maxLikelihood = 0;
             _CurrentTacticIdx = 0; // Default time trial tactic
             for (int idx = 0; idx < _TacticsCompendium.Count; idx++)
             {
               _TacticsCompendium[idx].Evaluate(myRs, rs);

               if (_TacticsCompendium[idx].Likelihood > maxLikelihood)
               {
             maxLikelihood = _TacticsCompendium[idx].Likelihood;
             _CurrentTacticIdx = idx;
               }
             }
             _ReviewTacticsTime = _TacticsCompendium[_CurrentTacticIdx].ReviewTime();
        }
示例#4
0
 public override double PercentComplete(RaceSpot rs)
 {
     return rs.t / (double)(600*_Target);
 }
示例#5
0
文件: RaceType.cs 项目: Cycli/Cycli
 public abstract long Result(RaceSpot rs);
示例#6
0
文件: RaceType.cs 项目: Cycli/Cycli
 public abstract double EstimatedTimeToFinish(RaceSpot rs, double atSpeed);
示例#7
0
文件: Tactic.cs 项目: Cycli/Cycli
 public override void Update(RaceSpot myRs, RaceSpot[] rs)
 {
     if (myRs.t > _StopTime)
     {
         // I'm knackered - call it off;
         Likelihood = 0;
     }
 }
示例#8
0
文件: Tactic.cs 项目: Cycli/Cycli
 public override void Update(RaceSpot myRs, RaceSpot[] rs)
 {
     // Nothing to do here
 }
示例#9
0
文件: Tactic.cs 项目: Cycli/Cycli
 public override void Update(RaceSpot myRs, RaceSpot[] rs)
 {
     // I'm in the lead!
     if (rs[0].id == _UserId)
     {
         Likelihood = 0;    // Force cancellation
     }
 }
示例#10
0
文件: Tactic.cs 项目: Cycli/Cycli
        public override void Evaluate(RaceSpot myRs, RaceSpot[] rs)
        {
            Likelihood = 0;    // Do not use unless it's going to work
            int chasedIdx = 0;
            while (rs[chasedIdx].id != _UserId && Likelihood == 0 && chasedIdx < rs.Length) // Last condition shouldn't be needed but is a backstop
            {
                if (!rs[chasedIdx].f && !rs[chasedIdx].a)
                {
                    // Only go throgh the chase routine if the lead rider is outside the drafting region
                    double gap = rs[chasedIdx].d - myRs.d;
                    if (gap > GROUP_DISTANCE_MTR)
                    {
                        double speedDiff = myRs.s - rs[chasedIdx].s;
                        double speedDiffMPerSec = speedDiff * RaceType.KMPH_TO_M_PER_SEC;
                        double timeToFinish = _Race.RaceType.EstimatedTimeToFinish(rs[chasedIdx], rs[chasedIdx].s);
                        // Are we going to catch them anyway?
                        if (speedDiffMPerSec * timeToFinish < gap)
                        {
                            // No we're not - do something about it!
                            if (timeToFinish > 0)
                            {

                                double[] powers = _Motor.AvailablePower();
                                int bandIdx = _Motor.AlphaBands.Select(alpha => timeToFinish <= alpha).Count(p => p) - 1;
                                if (bandIdx < 0)
                                {
                                    // Longer than 1 hour - scale the power
                                    RequestedPower = _Motor.RecoverPower + _Motor.AlphaBands[0] * (powers[0] - _Motor.RecoverPower) / timeToFinish;
                                }
                                else
                                {
                                    RequestedPower = powers[bandIdx];
                                }

                                // What speed will this give?
                                double maxSpeed = TurboTrainer.PowerNormalisedSpeed(RequestedPower);
                                double maxSpeedMPerSec = (maxSpeed - rs[chasedIdx].s) * RaceType.KMPH_TO_M_PER_SEC;
                                // Will this catch them?
                                if (speedDiffMPerSec * timeToFinish >= gap)
                                    // Yes!  Give it a go then
                                    Likelihood = GetLikelihood(myRs);
                            }
                        }

                    }
                }
                chasedIdx++;
            }
        }
示例#11
0
 public override double PercentComplete(RaceSpot rs)
 {
     return 0.01* (double)rs.d;  // Pursuit fixed distance is 10000m
 }
示例#12
0
 public override long Result(RaceSpot rs)
 {
     return (long)rs.t;
 }
示例#13
0
 public override double PercentComplete(RaceSpot rs)
 {
     return 100.0 * (double)rs.d / (double) _Target;
 }
示例#14
0
文件: Rider.cs 项目: Cycli/Cycli
        private double ExecuteTactics(RaceSpot myRs, RaceSpot[] rs)
        {
            DateTime timeNow = DateTime.UtcNow;
             if (_CurrentTacticIdx < 0 ||_ReviewTacticsTime < timeNow)
             {
               // Time to review
               ChooseTactic(myRs, rs);
             }
             else
             {
               _TacticsCompendium[_CurrentTacticIdx].Update(myRs, rs);
               // Some condition has been met in a simple update that forces a full review
               if (_TacticsCompendium[_CurrentTacticIdx].Likelihood < 0.05)  // We really should be looking again at this score
               {
            ChooseTactic(myRs, rs);
               }
             }
             System.Diagnostics.Debug.WriteLine(string.Format("Virtual {0}  {1}  {2}   {3}   {4}   {5}",
             myRs.t,
             this.UserName,
               myRs.pos,
               _TacticsCompendium[_CurrentTacticIdx].TacticName,
               _TacticsCompendium[_CurrentTacticIdx].RequestedPower,
               _Motor.Tank()));

             return _TacticsCompendium[_CurrentTacticIdx].RequestedPower;
        }
示例#15
0
文件: Tactic.cs 项目: Cycli/Cycli
 protected bool InGroup(RaceSpot myRs, RaceSpot[] rs)
 {
     // Are we in a group to break out?
     int inGroup = 0;
     foreach (RaceSpot r in rs)
     {
         if (Math.Abs(r.d - myRs.d) <= 10)
         {
             inGroup++;
         }
     }
     return (inGroup >= 2);
 }
示例#16
0
文件: Tactic.cs 项目: Cycli/Cycli
 public override void Update(RaceSpot myRs, RaceSpot[] rs)
 {
     throw new NotImplementedException();
 }
示例#17
0
文件: Tactic.cs 项目: Cycli/Cycli
 public override void Evaluate(RaceSpot myRs, RaceSpot[] rs)
 {
     // Look at the available power band speeds to estimate
     double[] powers = _Motor.AvailablePower();
     double[] speeds = powers.Select(p => TurboTrainer.PowerNormalisedSpeed(p)).ToArray();
     double[] timesToFinish = speeds.Select(s => _Race.RaceType.EstimatedTimeToFinish(myRs, s)).ToArray();
     int bandIdx = _Motor.AlphaBands.Zip(timesToFinish, (alpha, t) => t <= alpha).Count(p => p)-1;
     for (int j = 0; j < timesToFinish.Length; j++)
     {
         System.Diagnostics.Debug.WriteLine(string.Format("Timetrialing time to finish {0}  {1:N2}    {2:N2}   {3:N2}     {4:N2}", myRs.id, _Motor.AlphaBands[j], powers[j], speeds[j], timesToFinish[j]));
     }
     System.Diagnostics.Debug.WriteLine(string.Format("Timetrialing power index {0}   {1} ", myRs.id, bandIdx));
     double timeToFinish = timesToFinish[0];
     if (bandIdx < 0)
     {
         // Longer than 1 hour - scale the power
         RequestedPower = _Motor.RecoverPower + _Motor.AlphaBands[0] * (powers[0] -_Motor.RecoverPower)  / timesToFinish[0];
     }
     else
     {
         timeToFinish = timesToFinish[bandIdx];
         RequestedPower = powers[bandIdx];
     }
     if (timeToFinish < _goTime)
     {
         Likelihood = 1.0;    // Force the final sprint
     }
     else
     {
         Likelihood = 0.1;  // Low score - this is the default
     }
 }
示例#18
0
文件: Tactic.cs 项目: Cycli/Cycli
 public override void Evaluate(RaceSpot myRs, RaceSpot[] rs)
 {
     RequestedPower = _Motor.RecoverPower;
     // Lowest likelihood
     Likelihood = 0.1;
 }
示例#19
0
文件: Tactic.cs 项目: Cycli/Cycli
        public override void Evaluate(RaceSpot myRs, RaceSpot[] rs)
        {
            // Nothing to do here - wheelsucking is an update by update action
            Likelihood = 0.0;
            RaceSpot hasLeader = GroupLeader(myRs, rs);
            if (hasLeader != null)
            {
                // What's my optimum power
                double leaderSpeed = hasLeader.s;
                double leaderPower = TurboTrainer.StandardPower(leaderSpeed);
                // For wheel sucking - only consider using 1hr power unless we're in the last 5 minutes
                // Use the leader speed to judge
                double timeToFinish = _Race.RaceType.EstimatedTimeToFinish(myRs, leaderSpeed);

                double[] powers = _Motor.AvailablePower();
                double optimalPower = 0;
                int bandIdx = _Motor.AlphaBands.Select(alpha => timeToFinish <= alpha).Count(p => p) - 1;
                if (bandIdx < 0)
                {
                    // Longer than 1 hour - scale the power
                    RequestedPower = _Motor.RecoverPower + _Motor.AlphaBands[0] * (powers[0] - _Motor.RecoverPower) / timeToFinish;
                }
                else
                {
                    optimalPower = powers[bandIdx];
                }
                // Not 1.0 as we may need to go for a sprint, or be condering a break
                double wheelsuckPower = WHEELSUCK_POWER_FRAC * leaderPower;
                if (wheelsuckPower <= optimalPower)
                {
                    // An aggressive rider be
                    // (a) less likely to wheel suck
                    Likelihood = (1 - _Aggression);
                    // (b) break earlier
                    if (timeToFinish < _offTime)
                    {
                        Likelihood = 0;
                    }
                    RequestedPower = wheelsuckPower;
                    _leader = hasLeader;
                }
            }
        }
示例#20
0
文件: Tactic.cs 项目: Cycli/Cycli
 public override void Update(RaceSpot myRs, RaceSpot[] rs)
 {
     // Not used
 }
示例#21
0
文件: Tactic.cs 项目: Cycli/Cycli
 public override void Update(RaceSpot myRs, RaceSpot[] rs)
 {
     if (_leader != null)
     {
         double leaderPower = TurboTrainer.StandardPower(_leader.s);
         RequestedPower = WHEELSUCK_POWER_FRAC * leaderPower;
     }
 }
示例#22
0
文件: Tactic.cs 项目: Cycli/Cycli
 /// <summary>
 /// </summary>
 /// <param name="rs"></param>
 /// <returns></returns>
 public abstract void Evaluate(RaceSpot myRs, RaceSpot[] rs);
示例#23
0
文件: Race.cs 项目: Cycli/Cycli
        public void Finish(RaceSpot[] rss, Dictionary<string, Stack<RaceSpot>> history)
        {
            string sqlRiderUpdate = @"update cycli_race_riders set Position=@p, Distance=@d, Time=@t, Energy=@e, PedalStrokes=@k, Heartbeats=@b, TSS=@i " +
            "where RaceId=@r and UserId=@u";
            string sqlRaceUpdate = @"update cycli_races set Status='Finished' " +
              "where RaceId=@r and Status='Started'";

            SQLiteDatabase db = new SQLiteDatabase(true);
            try
            {
                db.ExecuteNonQuery(sqlRaceUpdate, "@r", this.RaceId);
                foreach (RaceSpot rs in rss)
                {
                    db.ExecuteNonQuery(sqlRiderUpdate, "@p", rs.pos, "@d", rs.d, "@t", rs.t, "@e", (int)rs.e, "@k", (int)rs.k, "@b", (int)rs.b, "@i", (int)rs.i, "@r", this.RaceId, "@u", rs.id);
                }
                db.CommitTransaction();
            }
            catch (Exception ex)
            {
                try
                {
                    db.RollbackTransaction();
                }
                catch (Exception ex1)
                {
                }
            }
            finally
            {
                // Don't need to close on a transaction
            }
            // Do points as a separate transaction
            string raceSpotSql = @"insert into cycli_race_spots (UserId, RaceId, Time, Distance, Speed, Cadence, HR, Power) " +
                            "values (@u, @r, @t, @d, @s, @c, @h, @p)";

            db = new SQLiteDatabase(true);
            try
            {
                foreach (string userId in history.Keys)
                {
                    Stack<RaceSpot> userHistory = history[userId];
                    foreach (RaceSpot rs in userHistory)
                    {
                        db.ExecuteNonQuery(raceSpotSql, "@r", this.RaceId, "@u", userId, "@t", rs.t, "@d", rs.d, "@s", rs.s, "@c", rs.c, "@h", rs.h, "@p", rs.p);
                    }
                }
                db.CommitTransaction();
            }
            catch (Exception ex)
            {
                try
                {
                    db.RollbackTransaction();
                }
                catch (Exception ex1)
                {
                }
            }
            finally
            {
            }
            // Mark the race as Finished
            this.Status = @"Finished";
        }
示例#24
0
文件: Tactic.cs 项目: Cycli/Cycli
 public abstract void Update(RaceSpot myRs, RaceSpot[] rs);
示例#25
0
文件: RaceType.cs 项目: Cycli/Cycli
 public abstract double PercentComplete(RaceSpot rs);
示例#26
0
文件: Tactic.cs 项目: Cycli/Cycli
        protected double GetLikelihood(RaceSpot rs)
        {
            double likelihood = 0;
            if (_LikelihoodPoints.Count > 0)
            {

                double pcnt = _Race.RaceType.PercentComplete(rs);
                // Find two points that surround this percentage
                TacticPoint before = _LikelihoodPoints.Where(p => p.PercentCompleted <= pcnt).OrderBy(p => p.PercentCompleted).LastOrDefault();
                TacticPoint after = _LikelihoodPoints.Where(p => p.PercentCompleted > pcnt).OrderBy(p => p.PercentCompleted).FirstOrDefault();
                if (after == null)
                {
                    likelihood = before.Value;
                }
                else
                {
                    double denom = (after.PercentCompleted - before.PercentCompleted);
                    double s = 0.5;
                    if (denom > 0.0)
                    {
                        s = (pcnt - before.PercentCompleted) * after.Value / denom;
                    }
                    likelihood = (1 - s) * before.Value + s * after.Value;
                }
            }
            return likelihood;
        }
示例#27
0
 public override double EstimatedTimeToFinish(RaceSpot rs, double atSpeed)
 {
     // Simple - no need for speed
     return 60000 * _Target - rs.t;
 }
示例#28
0
文件: Tactic.cs 项目: Cycli/Cycli
 protected RaceSpot GroupLeader(RaceSpot myRs, RaceSpot[] rs)
 {
     RaceSpot leader = rs.Where(p => !p.f && !p.a && (p.d - myRs.d) > 0 && (p.d - myRs.d) < GROUP_DISTANCE_MTR).OrderByDescending(p => p.d).FirstOrDefault();
     return leader;
 }
示例#29
0
 public override long Result(RaceSpot rs)
 {
     return (long)(rs.d);
 }
示例#30
0
 public void SendLeaderboard(string raceId, RaceSpot[] rs)
 {
     try
       {
     _ConnectionProcessLock.EnterReadLock();
     // Is the user connection
     foreach (RaceSpot r in rs)
     {
       string connectionId;
       if (_connections.TryGetValue(r.id, out connectionId))
       {
     Context.Clients.Client(connectionId).receiveLeaderboard(raceId, rs);
       }
     }
       }
       finally
       {
     _ConnectionProcessLock.ExitReadLock();
       }
 }