public void Append(Checkpoint cp) { Checkpoints.Add(cp); if (finishForced) { return; } var position = positions.GetOrAdd(cp.RiderId, x => RoundPosition.FromStartTime(x, RoundStartTime)); if (position.Finished) { return; } position.Append(cp); if (Track.Count < position.LapCount) { Track.Add(new List <Checkpoint>()); } Track[position.LapCount - 1].Add(cp); if (FinishCriteria?.HasFinished(position, GetSequence(), false) == true) { position.Finish(); } rating = null; }
public RoundPosition GetLeader(IEnumerable <RoundPosition> sequence, bool finishForced) { RoundPosition first = null; foreach (var position in sequence) { if (!finishForced || position.Finished) { return(position); } // The sequence is ordered by lap count and checkpoint sequence // Finish may have to be forced if the leader by laps, have fallen from race // and will not going to finish. When finish is forced, we look for // the first rider who have completed main time and chose him as leader if (first == null) { first = position; } if (position.Duration >= Duration) { return(position); } } return(first); }
public bool HasFinished(RoundPosition current, IEnumerable <RoundPosition> sequence, bool finishForced) { if (ForceFinishOnly && !finishForced) { return(false); } if (current.Finished) { return(true); } var leader = GetLeader(sequence, finishForced); if (current.RiderId == leader.RiderId) { if (TotalLaps.HasValue) { var startingLap = SkipStartingCheckpoint ? 1 : 0; if (current.LapCount - startingLap >= TotalLaps) { return(true); } return(current.LapCount > startingLap && current.Duration >= Duration); } var mainDurationComplete = current.Duration >= Duration; var additionalLapsComplete = LapsAfterDuration == 0 || current.Laps.Count(x => x.AggDuration >= Duration) > LapsAfterDuration; return(mainDurationComplete && additionalLapsComplete); } if (!leader.Finished) { return(false); } return(current.EndSequence > leader.EndSequence); }
private void UpdateSequence(RoundPosition position) { // if (positionsInRating.TryGetValue(position.RiderId, out var currentIndex)) var currentIndex = Rating.FindIndex(x => x.RiderId == position.RiderId); if (currentIndex >= 0) { Rating.RemoveAt(currentIndex); } var newIndex = Rating.Count - 1; while (newIndex >= 0 && RoundPosition.LapsCountFinishedComparer.Compare(Rating[newIndex], position) > 0) { newIndex--; } newIndex++; Rating.Insert(newIndex, position); }