/// <summary> /// Gets a collection of <see cref="EditionPivot"/> to compute the ranking at a specified date. /// </summary> /// <param name="rankingVersion"><see cref="RankingVersionPivot"/></param> /// <param name="date">Ranking date; if not a monday, no results returned.</param> /// <param name="involvedPlayers">Out; involved <see cref="PlayerPivot"/> for the collection of <see cref="EditionPivot"/> returned.</param> /// <returns>Collection of <see cref="EditionPivot"/>.</returns> internal static List <EditionPivot> EditionsForRankingAtDate(RankingVersionPivot rankingVersion, DateTime date, out List <PlayerPivot> involvedPlayers) { if (date.DayOfWeek != DayOfWeek.Monday) { involvedPlayers = new List <PlayerPivot>(); return(new List <EditionPivot>()); } var editionsRollingYear = GetList <EditionPivot>().Where(edition => edition.DateEnd < date && edition.DateEnd >= date.AddDays(-1 * ConfigurationPivot.Default.RankingWeeksCount * 7) && GridPointPivot.GetRankableLevelList(rankingVersion).Contains(edition.Level)).ToList(); if (rankingVersion.ContainsRule(RankingRulePivot.ExcludingRedundantTournaments)) { // No redundant tournament, when slot is unknown (take the latest). // No redundant slot, regarding of the tournament (take the latest). editionsRollingYear = editionsRollingYear.Where(edition => !editionsRollingYear.Any(otherEdition => otherEdition.Slot == edition.Slot && (otherEdition.Slot != null || (otherEdition.Tournament == edition.Tournament)) && otherEdition.DateEnd > edition.DateEnd ) ).ToList(); } involvedPlayers = editionsRollingYear .SelectMany(edition => edition.Matches.SelectMany(match => match.Players)) .Distinct() .Where(player => !player.IsJohnDoe) .ToList(); return(editionsRollingYear); }
/// <summary> /// Collection of <see cref="LevelPivot"/> which can be used to compute the specified <see cref="RankingVersionPivot"/>. /// </summary> internal static List <LevelPivot> GetRankableLevelList(RankingVersionPivot rankingVersion) { return(GetList <GridPointPivot>() .Select(gridPoint => gridPoint.Level) .Distinct() .Where(level => rankingVersion.ContainsRule(RankingRulePivot.IncludingOlympicGames) || !level.IsOlympicGames) .ToList()); }
/// <summary> /// Gets the number of points gained by a specified player for this edition. The gain might vary regarding of the ruleset. /// </summary> /// <param name="player">A <see cref="PlayerPivot"/></param> /// <param name="rankingVersion">A <see cref="RankingRulePivot"/> (ruleset of current ranking).</param> /// <returns>Number of points for this player at this edition; 0 if any argument is <c>Null</c>.</returns> internal uint GetPlayerPoints(PlayerPivot player, RankingVersionPivot rankingVersion) { uint points = 0; if (player == null || rankingVersion == null) { return(points); } // If qualifcation rule applies and player comes from qualifications for this edition. if (rankingVersion.ContainsRule(RankingRulePivot.IncludingQualificationBonus) && PlayerIsQualified(player)) { points = QualificationPointPivot.GetByLevelAndDrawSize(Level.Id, DrawSize)?.Points ?? 0; } // Cumulable points (round robin). points += (uint)Matches .Where(match => match.Winner == player && match.Round.IsRoundRobin) .Sum(match => match.PointGrid?.Points ?? 0); var bestWin = Matches .Where(match => match.Winner == player && !match.Round.IsRoundRobin && !match.Round.IsBronzeReward) .OrderBy(match => match.Round.Importance) .FirstOrDefault(); var bestLose = Matches .Where(match => match.Loser == player && !match.Round.IsRoundRobin && !match.Round.IsBronzeReward) .OrderBy(match => match.Round.Importance) .FirstOrDefault(); if (Matches.Any(match => match.Round.IsBronzeReward && match.Players.Contains(player))) { if (Matches.Any(match => match.Winner == player && match.Round.IsBronzeReward)) { // Third place points. points += Matches .First(match => match.Winner == player && match.Round.IsBronzeReward) .PointGrid?.Points ?? 0; } else { // Fourth place points. points += GridPointPivot.GetByLevelAndRound(Level.Id, RoundPivot.GetQuarterFinal().Id)?.Points ?? 0; } } else { // Unable to detect a lose by walkover the next round than a win by walkover. // In that case, points from the win by walkover are ignored. if (bestLose == null) { points += bestWin?.PointGrid?.Points ?? 0; } else if (bestWin != null) { var lastWinRound = RoundPivot.GetByImportance(bestLose.Round.Importance + 1); var grid = bestWin.PointGrid; if (bestWin.Round.Importance > lastWinRound.Importance) { grid = GridPointPivot.GetByLevelAndRound(Level.Id, lastWinRound.Id); } points += grid?.Points ?? 0; } else { points += bestLose.PointGrid?.ParticipationPoints ?? 0; } } return(points); }