public void AttachRiderProcessors(RaceProcessor rp, Race race) { try { _rideProcessLock.EnterUpgradeableReadLock(); // Is the user connection foreach (Race.Participant p in race.Participants) { if (p.Status == @"Started") { RideProcessor rideProcessor = null; if (_RideProcessors.ContainsKey(p.UserId)) { rideProcessor = _RideProcessors[p.UserId]; // Just update the timeout rideProcessor.UpdateTimeout(); } else { // Already in write lock rideProcessor = ActivateUserRider(p.UserId); } // Add the event handler rideProcessor.SpotDataEvent += rp.UpdateSpotData; rideProcessor.RiderInactiveEvent += rp.AbandonRider; } } } finally { _rideProcessLock.ExitUpgradeableReadLock(); } }
public BreakTactic(string userId, Motor m, double aggression, Race r) : base(userId, m, aggression, r) { TacticName = @"Breaking"; _Rnd = new Random(); // An aggressive rider =1 will always fancy a break // A weedy rider =0 won't try any break _LikelihoodPoints.Add(new TacticPoint { PercentCompleted = 0, Value = 0.01 * aggression }); _LikelihoodPoints.Add(new TacticPoint { PercentCompleted = 80, Value = 0.01 * aggression }); _LikelihoodPoints.Add(new TacticPoint { PercentCompleted = 90, Value = 0 }); _LikelihoodPoints.Add(new TacticPoint { PercentCompleted = 100, Value = 0 }); }
public static Race LoadLastRace(string userId) { Race[] rs = new Race[] { }; SQLiteDatabase db = new SQLiteDatabase(); string lastSql = "select r.raceId from cycli_race_riders rr, cycli_races r " + "where rr.userId = @u " + "and rr.raceId = r.raceId " + "and (r.Status = 'Finished' or r.Status = 'Abandoned') " + "order by r.StartDateTime desc limit 1"; string raceId = db.ExecuteScalar(lastSql, "@u", userId); if (!string.IsNullOrEmpty(raceId)) { string sql = "select r.RaceId as RaceId, r.Name as Name, r.Description as Description, " + "r.StartDateTime as StartDateTime, r.TargetType as TargetType, r.Configuration as Configuration , r.RaceDirectorId as RaceDirectorId, " + "r.PNS as PNS, r.Drafting as Drafting, r.HandicapType as HandicapType, r.ProfileId as ProfileId, r.ProfileType as ProfileType, " + "r.Minimum as Minimum, r.Maximum as Maximum,r.Status as RaceStatus, u.UserId as UserId , u.UserName as UserName, " + "u.ThresholdPower as ThresholdPower,rr1.Status as Status, rr1.Position as Position, rr1.Distance as Distance, rr1.Time as Time, rr1.Energy as Energy, " + "rr1.PedalStrokes as PedalStrokes, rr1.Heartbeats as Heartbeats, rr1.TSS as TSS, " + "rr1.RiderType as RiderType, rr1.Handicap as Handicap " + "From cycli_races r, cycli_race_riders rr1, cycli_riders u " + "where u.UserId = rr1.UserId " + "and r.RaceId = rr1.RaceId " + "and r.RaceId = @r " + "and not rr1.Status ='Invited' " + "union " + "select r.RaceId as RaceId, r.Name as Name, r.Description as Description, " + "r.StartDateTime as StartDateTime, r.TargetType as TargetType, r.Configuration as Configuration , r.RaceDirectorId as RaceDirectorId, " + "r.PNS as PNS, r.Drafting as Drafting, r.HandicapType as HandicapType, r.ProfileId as ProfileId, r.ProfileType as ProfileType, " + "r.Minimum as Minimum, r.Maximum as Maximum,r.Status as RaceStatus, u.UserId as UserId , u.UserName as UserName, " + "u.Power1Hr as ThresholdPower,rr1.Status as Status, rr1.Position as Position, rr1.Distance as Distance, rr1.Time as Time, rr1.Energy as Energy, " + "rr1.PedalStrokes as PedalStrokes, rr1.Heartbeats as Heartbeats, rr1.TSS as TSS, " + "rr1.RiderType as RiderType, rr1.Handicap as Handicap " + "From cycli_races r, cycli_race_riders rr1, " + "cycli_virtual_riders u " + "where u.UserId = rr1.UserId " + "and r.RaceId = rr1.RaceId " + "and r.RaceId = @r " + " order by Position"; DataTable dtRaces = db.GetDataTable(sql, "@r", raceId); rs = BuildRaceArray(dtRaces); } db.Close(); return rs.Length > 0 ? rs[0] : null; }
public WheelsuckTactic(string userId, Motor m, double aggression, Race r) : base(userId, m, aggression, r) { TacticName = @"Wheelsucking"; }
public TimetrialTactic(string userId, Motor m, double aggression, Race r) : base(userId, m, aggression, r) { TacticName = @"Time-trialling"; // A less agreesive rider will be happy to timetrial _LikelihoodPoints.Add(new TacticPoint { PercentCompleted = 0, Value = 1.0 - 0.01 * aggression }); // We will always consider chasing at the end _LikelihoodPoints.Add(new TacticPoint { PercentCompleted = 100, Value = 1 }); }
public Tactic(string userId, Motor m, double aggression, Race r) { _UserId = userId; _Motor = m; _Race = r; _Aggression = 0.01 * aggression; // scale between 0 and 1 _LikelihoodPoints = new List<TacticPoint>(); TacticName = @"Undefined"; }
public RecoverTactic(string userId, Motor m, double aggression, Race r) : base(userId, m, aggression, r) { TacticName = @"Recovering"; }
public CooperateTactic(string userId, Motor m, double aggression, Race r) : base(userId, m, aggression, r) { TacticName = @"Cooperating"; }
public ChaseTactic(string userId, Motor m, double aggression, Race r) : base(userId, m, aggression, r) { TacticName = @"Chasing"; // Depending on aggression - don't chase at the start put always // chase at the end of the race // An aggressive rider =1 will always try to chase down at the start // A weedy rider =0 won't try at all at the start _LikelihoodPoints.Add(new TacticPoint { PercentCompleted = 0, Value = 0.01 * aggression }); // We will always consider chasing at the end _LikelihoodPoints.Add(new TacticPoint { PercentCompleted = 90, Value = 1 }); _LikelihoodPoints.Add(new TacticPoint { PercentCompleted = 100, Value = 1 }); }
public void StartRiding(Race race, RaceProcessor rp) { _CurrentTacticIdx = -1; _messageCounter = 0; _ReviewTacticsTime = DateTime.MinValue; // Force full tactics review on first update int seed = (this.UserId + DateTime.UtcNow.Ticks.ToString()).GetHashCode(); Random rnd = new Random(seed); _RaceProcessor = rp; _Race = race; _Motor = new Motor(); double[] powerBands = new double[]{this.Power1Hr, this.Power5Min,this.Power1Min, this.Power5Sec}; double[] alphaBands = new double[]{3600, 300, 60, 5}; _Motor.Initialise(this.PowerMin, powerBands, alphaBands); // Initialise the spot _lastMessageTime = (ulong)DateTime.UtcNow.Subtract(new DateTime(1970,1,1)).TotalMilliseconds-1000; // Load up the tactics _TacticsCompendium.Clear(); // If more than one tactic has the highest score, then they'll be chosen in the order // added to the compendium // Recover is really the last thing we want to consider _TacticsCompendium.Add(new ChaseTactic(UserId, _Motor, Aggression, race)); _TacticsCompendium.Add(new WheelsuckTactic(UserId, _Motor, Aggression, race)); _TacticsCompendium.Add(new BreakTactic(UserId, _Motor, Aggression, race)); _TacticsCompendium.Add(new TimetrialTactic(UserId, _Motor, Aggression, race)); _TacticsCompendium.Add(new RecoverTactic(UserId, _Motor, Aggression, race)); _MessageTimer = new Timer(UpdateSpotData, null, 0, UPDATE_SPOT_INTERVAL_MS); }
public void SendStartRace(Race race) { try { _ConnectionProcessLock.EnterReadLock(); foreach (Race.Participant p in race.UserParticipants) { if (p.Status == @"Started") { string connectionId; if (_connections.TryGetValue(p.UserId, out connectionId)) { Context.Clients.Client(connectionId).receiveStartRace(race.RaceId); } } } } finally { _ConnectionProcessLock.ExitReadLock(); } }
public void SendRiderMessages(Race race, RiderMessage[] rms) { try { _ConnectionProcessLock.EnterReadLock(); // Is the user connection foreach (Race.Participant p in race.UserParticipants) { string connectionId; if (_connections.TryGetValue(p.UserId, out connectionId)) { Context.Clients.Client(connectionId).receiveMessages(rms); } } } finally { _ConnectionProcessLock.ExitReadLock(); } }
public void SendCountdown(Race race, long countdown) { try { _ConnectionProcessLock.EnterReadLock(); // Is the user connection foreach (Race.Participant p in race.UserParticipants) { string connectionId; if (_connections.TryGetValue(p.UserId, out connectionId)) { Context.Clients.Client(connectionId).receiveCountdown(race.RaceId, countdown); } } } finally { _ConnectionProcessLock.ExitReadLock(); } }
public void Reschedule(Race race) { _rideProcessLock.EnterWriteLock(); // Ride processors can manage themselves - just deal with the race RaceProcessor rp; if (_RaceProcessors.TryGetValue(race.RaceId, out rp)) { _RescheduledProcessors.Push(rp); // Force a dispose } _rideProcessLock.ExitWriteLock(); }
public void SetRaceDetails(Race race) { string userId = Context.User.Identity.Name; race.Save(userId); }
private int GetTargetValue(Race race, RaceSpot rs) { int v = int.MinValue; float x = (float)this.Race.RaceType.PercentComplete(rs); // scan the profile until we find the between float y = _RaceProfile.GetYValue(x); if (!float.IsNaN(y)) { v = race.ProfileMin + (int)(0.01 * (float)(race.ProfileMax - race.ProfileMin) * y); } return v; }