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;
        }
Пример #2
0
        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);
        }
Пример #3
0
        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);
        }
Пример #4
0
        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);
        }