mirror of
https://github.com/eclipse-sailing-analytics/sailing-analytics.git
synced 2026-09-23 14:08:40 +00:00
bug5877: started with refactorings and comments; started new scoring scheme
This commit is contained in:
@@ -116,6 +116,15 @@ public interface ScoringScheme extends Serializable {
|
||||
*/
|
||||
int compareByNumberOfRacesScored(int competitor1NumberOfRacesScored, int competitor2NumberOfRacesScored);
|
||||
|
||||
/**
|
||||
* Having scored in a later medal series than the other is considered better. -1 means no medal series score at all.
|
||||
* With a lesser result encoding "better" the direction of default integer comparison between the two parameters is
|
||||
* reversed.
|
||||
*/
|
||||
default int compareByMedalRaceParticipation(int zeroBasedIndexOfLastMedalSeriesInWhichO1Scored, int zeroBasedIndexOfLastMedalSeriesInWhichO2Scored) {
|
||||
return -Integer.compare(zeroBasedIndexOfLastMedalSeriesInWhichO1Scored, zeroBasedIndexOfLastMedalSeriesInWhichO2Scored);
|
||||
}
|
||||
|
||||
ScoringSchemeType getType();
|
||||
|
||||
/**
|
||||
|
||||
+20
@@ -175,6 +175,26 @@ public abstract class AbstractScoringSchemeImpl implements ScoringScheme {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a filtered view on the {@link Leaderboard#getRaceColumns() leaderboard's race columns}, removing
|
||||
* all {@link RaceColumn#isMedalRace() medal races} from the filtered view.
|
||||
*/
|
||||
protected Iterable<RaceColumn> getOpeningSeriesRaceColumns(Leaderboard leaderboard) {
|
||||
return Util.filter(leaderboard.getRaceColumns(), rc->!rc.isMedalRace());
|
||||
}
|
||||
|
||||
protected LeaderboardTotalRankComparator getOpeningSeriesRankComparator(boolean nullScoresAreBetter,
|
||||
TimePoint timePoint, Leaderboard leaderboard,
|
||||
BiFunction<Competitor, RaceColumn, Double> totalPointsSupplier,
|
||||
WindLegTypeAndLegBearingAndORCPerformanceCurveCache cache) {
|
||||
final Iterable<RaceColumn> openingSeriesRaceColumns = getOpeningSeriesRaceColumns(leaderboard);
|
||||
// pass on the totalPointsSupplier coming from the caller, most likely a LeaderboardTotalRankComparator,
|
||||
// to speed up / save the total points (re-)calculation
|
||||
final LeaderboardTotalRankComparator openingSeriesRankComparator =
|
||||
new LeaderboardTotalRankComparator(leaderboard, timePoint, this, nullScoresAreBetter, openingSeriesRaceColumns, totalPointsSupplier, cache);
|
||||
return openingSeriesRankComparator;
|
||||
}
|
||||
|
||||
/**
|
||||
* Looks backwards starting at the last race until the first score difference is found, including the discarded
|
||||
* scored. This implements Racing Rules of Sailing (RRS) section A8.2:
|
||||
|
||||
+2
-10
@@ -249,7 +249,8 @@ public class LeaderboardTotalRankComparator implements Comparator<Competitor> {
|
||||
}
|
||||
}
|
||||
}
|
||||
int result = compareByMedalRaceParticipation(zeroBasedIndexOfLastMedalSeriesInWhichO1Scored, zeroBasedIndexOfLastMedalSeriesInWhichO2Scored);
|
||||
// TODO bug5877: pass leaderboard and competitors and a totalPointsSupplier (based on totalPointsCache, see call to compareByBetterScore below) to allow for identifying competitors promoted through to later medal race
|
||||
int result = scoringScheme.compareByMedalRaceParticipation(zeroBasedIndexOfLastMedalSeriesInWhichO1Scored, zeroBasedIndexOfLastMedalSeriesInWhichO2Scored);
|
||||
if (result == 0) {
|
||||
result = defaultFleetBasedComparisonResult;
|
||||
if (result == 0) {
|
||||
@@ -466,15 +467,6 @@ public class LeaderboardTotalRankComparator implements Comparator<Competitor> {
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Having scored in a later medal series than the other is considered better. -1 means no medal series score at all.
|
||||
* With a lesser result encoding "better" the direction of default integer comparison between the two parameters is
|
||||
* reversed.
|
||||
*/
|
||||
private int compareByMedalRaceParticipation(int zeroBasedIndexOfLastMedalSeriesInWhichO1Scored, int zeroBasedIndexOfLastMedalSeriesInWhichO2Scored) {
|
||||
return -Integer.compare(zeroBasedIndexOfLastMedalSeriesInWhichO1Scored, zeroBasedIndexOfLastMedalSeriesInWhichO2Scored);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a comparator for comparing individual scores. This implementation returns a comparator for the usual ISAF
|
||||
* scheme where lesser scores compare "better" which again means "lesser." Therefore, the comparator retunred compares
|
||||
|
||||
+3
-12
@@ -392,11 +392,9 @@ public class LowPointFirstToWinThreeRaces extends LowPoint {
|
||||
result = compareByA81TieBreak(o1, o1Scores, o2, o2Scores, nullScoresAreBetter, timePoint, leaderboard,
|
||||
discardedRaceColumnsPerCompetitor, totalPointsSupplier, cache);
|
||||
} else {
|
||||
final Iterable<RaceColumn> openingSeriesRaceColumns = getOpeningSeriesRaceColumns(leaderboard);
|
||||
// pass on the totalPointsSupplier coming from the caller, most likely a LeaderboardTotalRankComparator,
|
||||
// to speed up / save the total points (re-)calculation
|
||||
result = new LeaderboardTotalRankComparator(leaderboard, timePoint, this, nullScoresAreBetter, openingSeriesRaceColumns, totalPointsSupplier, cache)
|
||||
.compare(o1, o2);
|
||||
final LeaderboardTotalRankComparator openingSeriesRankComparator = getOpeningSeriesRankComparator(
|
||||
nullScoresAreBetter, timePoint, leaderboard, totalPointsSupplier, cache);
|
||||
result = openingSeriesRankComparator.compare(o1, o2);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
@@ -418,13 +416,6 @@ public class LowPointFirstToWinThreeRaces extends LowPoint {
|
||||
discardedRaceColumnsPerCompetitor, totalPointsSupplier, cache);
|
||||
}
|
||||
|
||||
/**
|
||||
* Merge non-medal series columns, preserving order across {@code raceColumnsO1} and {@code raceColumnsO2}.
|
||||
*/
|
||||
private Iterable<RaceColumn> getOpeningSeriesRaceColumns(Leaderboard leaderboard) {
|
||||
return Util.filter(leaderboard.getRaceColumns(), rc->!rc.isMedalRace());
|
||||
}
|
||||
|
||||
private boolean hasMedalScores(List<Pair<RaceColumn, Double>> o1Scores) {
|
||||
return o1Scores.stream().anyMatch(p->p.getA().isMedalRace() && p.getB() != null);
|
||||
}
|
||||
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
package com.sap.sailing.domain.leaderboard.impl;
|
||||
|
||||
public class LowPointWithEliminatingMedalSeriesPromotingOneToFinalAndTwoToSemifinal
|
||||
extends LowPointWithEliminatingMedalSeriesWithPromotions {
|
||||
private static final long serialVersionUID = -6753499035563730886L;
|
||||
|
||||
public LowPointWithEliminatingMedalSeriesPromotingOneToFinalAndTwoToSemifinal() {
|
||||
super(new int[] { 2, 1 });
|
||||
}
|
||||
}
|
||||
+57
@@ -0,0 +1,57 @@
|
||||
package com.sap.sailing.domain.leaderboard.impl;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.ListIterator;
|
||||
|
||||
import com.sap.sailing.domain.base.RaceColumnInSeries;
|
||||
import com.sap.sse.common.Util;
|
||||
|
||||
public abstract class LowPointWithEliminatingMedalSeriesWithPromotions extends LowPoint {
|
||||
private static final long serialVersionUID = 7759999270911627798L;
|
||||
|
||||
/**
|
||||
* The last index for this array refers to the last medal race; e.g., the "Grand Final" race
|
||||
* in an iQFOil regatta with the medal series consisting of a "Quarter Final," a "Semi Final"
|
||||
* and a "Grand Final". The last-but-one index in the example would then refer to the Semi Final,
|
||||
* and so on. The array may be empty, meaning that no competitor is promoted into any medal
|
||||
* race. The field always has to refer to a valid array.
|
||||
*/
|
||||
private final int[] numberOfPromotedCompetitorsIntoLastMedalRaces;
|
||||
|
||||
/**
|
||||
*
|
||||
* @param numberOfPromotedCompetitorsIntoLastMedalRaces
|
||||
* The last index for this array refers to the last medal race; e.g., the "Grand Final" race in an iQFOil
|
||||
* regatta with the medal series consisting of a "Quarter Final," a "Semi Final" and a "Grand Final". The
|
||||
* last-but-one index in the example would then refer to the Semi Final, and so on. The array may be
|
||||
* empty, meaning that no competitor is promoted into any medal race. The field always has to refer to a
|
||||
* valid array.
|
||||
*/
|
||||
public LowPointWithEliminatingMedalSeriesWithPromotions(int[] numberOfPromotedCompetitorsIntoLastMedalRaces) {
|
||||
super();
|
||||
this.numberOfPromotedCompetitorsIntoLastMedalRaces = numberOfPromotedCompetitorsIntoLastMedalRaces;
|
||||
}
|
||||
|
||||
public int getNumberOfCompetitorsBetterThanThoseSailingInRace(RaceColumnInSeries medalRace) {
|
||||
final List<? extends RaceColumnInSeries> allMedalRacesInSeries = Util.asList(medalRace.getSeries().getRaceColumns());
|
||||
int result = 0;
|
||||
int indexInNumberOfPromotedCompetitorsIntoLastMedalRaces = numberOfPromotedCompetitorsIntoLastMedalRaces.length-1;
|
||||
if (allMedalRacesInSeries.size() > 1) {
|
||||
for (final ListIterator<? extends RaceColumnInSeries> i=allMedalRacesInSeries.listIterator(allMedalRacesInSeries.size()); i.hasPrevious() && i.previous() != medalRace; ) {
|
||||
result += numberOfPromotedCompetitorsIntoLastMedalRaces[indexInNumberOfPromotedCompetitorsIntoLastMedalRaces--];
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compareByMedalRaceParticipation(int zeroBasedIndexOfLastMedalSeriesInWhichO1Scored,
|
||||
int zeroBasedIndexOfLastMedalSeriesInWhichO2Scored) {
|
||||
// TODO We'd like to consider those as "having participated" in a medal race that may not have a score but have been promoted already to a later medal race based on their opening series result;
|
||||
// For that we need to check all medal race columns and need to know the two competitors.
|
||||
// If promoted to a later medal race but not sailed in the one currently considered, consider as "has participated."
|
||||
// If both participated, move on to next medal race column, if any. If last medal race column, return 0.
|
||||
// If one competitor is considered as "has participated" and the other one not, prefer the one that "has participated" over the one that has not.
|
||||
return super.compareByMedalRaceParticipation(zeroBasedIndexOfLastMedalSeriesInWhichO1Scored, zeroBasedIndexOfLastMedalSeriesInWhichO2Scored);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user