mirror of
https://github.com/eclipse-sailing-analytics/sailing-analytics.git
synced 2026-10-06 12:23:55 +00:00
Merge remote-tracking branch 'origin/master'
This commit is contained in:
commit
3e7a89ef23
4 files changed
+65
-61
No files matched your search
+4
-4
@@ -42,7 +42,7 @@ public class LeaderboardScoringAndRankingTest extends AbstractLeaderboardTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testOneStartedRaceWithDifferentScores() {
|
public void testOneStartedRaceWithDifferentScores() throws NoWindException {
|
||||||
List<Competitor> competitors = createCompetitors(10);
|
List<Competitor> competitors = createCompetitors(10);
|
||||||
Regatta regatta = createRegatta(/* qualifying */0, new String[] { "Default" }, /* final */1,
|
Regatta regatta = createRegatta(/* qualifying */0, new String[] { "Default" }, /* final */1,
|
||||||
new String[] { "Default" },
|
new String[] { "Default" },
|
||||||
@@ -97,7 +97,7 @@ public class LeaderboardScoringAndRankingTest extends AbstractLeaderboardTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testDistributionAcrossQualifyingFleetsWithDifferentScores() {
|
public void testDistributionAcrossQualifyingFleetsWithDifferentScores() throws NoWindException {
|
||||||
List<Competitor> competitors = createCompetitors(10);
|
List<Competitor> competitors = createCompetitors(10);
|
||||||
List<Competitor> yellow = new ArrayList<Competitor>();
|
List<Competitor> yellow = new ArrayList<Competitor>();
|
||||||
List<Competitor> blue = new ArrayList<Competitor>();
|
List<Competitor> blue = new ArrayList<Competitor>();
|
||||||
@@ -127,7 +127,7 @@ public class LeaderboardScoringAndRankingTest extends AbstractLeaderboardTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testDistributionAcrossFinalFleetsWithDifferentScores() {
|
public void testDistributionAcrossFinalFleetsWithDifferentScores() throws NoWindException {
|
||||||
List<Competitor> competitors = createCompetitors(10);
|
List<Competitor> competitors = createCompetitors(10);
|
||||||
List<Competitor> gold = new ArrayList<Competitor>();
|
List<Competitor> gold = new ArrayList<Competitor>();
|
||||||
List<Competitor> silver = new ArrayList<Competitor>();
|
List<Competitor> silver = new ArrayList<Competitor>();
|
||||||
@@ -155,7 +155,7 @@ public class LeaderboardScoringAndRankingTest extends AbstractLeaderboardTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testMedalTakesPrecedence() {
|
public void testMedalTakesPrecedence() throws NoWindException {
|
||||||
final int firstMedalCompetitorIndex = 3;
|
final int firstMedalCompetitorIndex = 3;
|
||||||
List<Competitor> competitors = createCompetitors(20);
|
List<Competitor> competitors = createCompetitors(20);
|
||||||
List<Competitor> medal = competitors.subList(firstMedalCompetitorIndex, firstMedalCompetitorIndex+10);
|
List<Competitor> medal = competitors.subList(firstMedalCompetitorIndex, firstMedalCompetitorIndex+10);
|
||||||
|
|||||||
@@ -159,8 +159,9 @@ public interface Leaderboard extends Named {
|
|||||||
/**
|
/**
|
||||||
* Sorts the competitors according to the overall regatta standings, considering the sorting rules for
|
* Sorts the competitors according to the overall regatta standings, considering the sorting rules for
|
||||||
* {@link Series}, {@link Fleet}s, medal races, discarding rules and score corrections.
|
* {@link Series}, {@link Fleet}s, medal races, discarding rules and score corrections.
|
||||||
|
* @throws NoWindException
|
||||||
*/
|
*/
|
||||||
List<Competitor> getCompetitorsFromBestToWorst(TimePoint timePoint);
|
List<Competitor> getCompetitorsFromBestToWorst(TimePoint timePoint) throws NoWindException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Fetches all entries for all competitors of all races tracked by this leaderboard in one sweep. This saves some
|
* Fetches all entries for all competitors of all races tracked by this leaderboard in one sweep. This saves some
|
||||||
|
|||||||
+2
-2
@@ -459,7 +459,7 @@ public abstract class AbstractLeaderboardImpl implements Leaderboard, RaceColumn
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<Competitor> getCompetitorsFromBestToWorst(TimePoint timePoint) {
|
public List<Competitor> getCompetitorsFromBestToWorst(TimePoint timePoint) throws NoWindException {
|
||||||
List<Competitor> result = new ArrayList<Competitor>();
|
List<Competitor> result = new ArrayList<Competitor>();
|
||||||
for (Competitor competitor : getCompetitors()) {
|
for (Competitor competitor : getCompetitors()) {
|
||||||
result.add(competitor);
|
result.add(competitor);
|
||||||
@@ -468,7 +468,7 @@ public abstract class AbstractLeaderboardImpl implements Leaderboard, RaceColumn
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected Comparator<? super Competitor> getTotalRankComparator(TimePoint timePoint) {
|
protected Comparator<? super Competitor> getTotalRankComparator(TimePoint timePoint) throws NoWindException {
|
||||||
return new LeaderboardTotalRankComparator(this, timePoint, scoreComparator);
|
return new LeaderboardTotalRankComparator(this, timePoint, scoreComparator);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+57
-54
@@ -3,15 +3,17 @@ package com.sap.sailing.domain.leaderboard.impl;
|
|||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.Comparator;
|
import java.util.Comparator;
|
||||||
|
import java.util.HashMap;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
import com.sap.sailing.domain.base.Competitor;
|
import com.sap.sailing.domain.base.Competitor;
|
||||||
import com.sap.sailing.domain.base.Fleet;
|
import com.sap.sailing.domain.base.Fleet;
|
||||||
import com.sap.sailing.domain.base.RaceColumn;
|
import com.sap.sailing.domain.base.RaceColumn;
|
||||||
import com.sap.sailing.domain.common.NoWindError;
|
|
||||||
import com.sap.sailing.domain.common.NoWindException;
|
import com.sap.sailing.domain.common.NoWindException;
|
||||||
import com.sap.sailing.domain.common.TimePoint;
|
import com.sap.sailing.domain.common.TimePoint;
|
||||||
|
import com.sap.sailing.domain.common.impl.Util.Pair;
|
||||||
import com.sap.sailing.domain.leaderboard.Leaderboard;
|
import com.sap.sailing.domain.leaderboard.Leaderboard;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -45,75 +47,76 @@ import com.sap.sailing.domain.leaderboard.Leaderboard;
|
|||||||
*/
|
*/
|
||||||
public class LeaderboardTotalRankComparator implements Comparator<Competitor> {
|
public class LeaderboardTotalRankComparator implements Comparator<Competitor> {
|
||||||
private final Leaderboard leaderboard;
|
private final Leaderboard leaderboard;
|
||||||
private final TimePoint timePoint;
|
|
||||||
private final Comparator<Integer> scoreComparator;
|
private final Comparator<Integer> scoreComparator;
|
||||||
|
private final Map<Pair<Competitor, RaceColumn>, Integer> totalPointsCache;
|
||||||
|
|
||||||
public LeaderboardTotalRankComparator(Leaderboard leaderboard, TimePoint timePoint, Comparator<Integer> scoreComparator) {
|
public LeaderboardTotalRankComparator(Leaderboard leaderboard, TimePoint timePoint, Comparator<Integer> scoreComparator) throws NoWindException {
|
||||||
super();
|
super();
|
||||||
this.leaderboard = leaderboard;
|
this.leaderboard = leaderboard;
|
||||||
this.timePoint = timePoint;
|
|
||||||
this.scoreComparator = scoreComparator;
|
this.scoreComparator = scoreComparator;
|
||||||
|
totalPointsCache = new HashMap<Pair<Competitor, RaceColumn>, Integer>();
|
||||||
|
for (Competitor competitor : leaderboard.getCompetitors()) {
|
||||||
|
for (RaceColumn raceColumn : leaderboard.getRaceColumns()) {
|
||||||
|
totalPointsCache.put(new Pair<Competitor, RaceColumn>(competitor, raceColumn),
|
||||||
|
leaderboard.getTotalPoints(competitor, raceColumn, timePoint));
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected Leaderboard getLeaderboard() {
|
protected Leaderboard getLeaderboard() {
|
||||||
return leaderboard;
|
return leaderboard;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected TimePoint getTimePoint() {
|
|
||||||
return timePoint;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int compare(Competitor o1, Competitor o2) {
|
public int compare(Competitor o1, Competitor o2) {
|
||||||
try {
|
List<Integer> o1Scores = new ArrayList<Integer>();
|
||||||
List<Integer> o1Scores = new ArrayList<Integer>();
|
List<Integer> o2Scores = new ArrayList<Integer>();
|
||||||
List<Integer> o2Scores = new ArrayList<Integer>();
|
int o1ScoreSum = 0;
|
||||||
int o1ScoreSum = 0;
|
int o2ScoreSum = 0;
|
||||||
int o2ScoreSum = 0;
|
int o1MedalRaceScore = 0;
|
||||||
int o1MedalRaceScore = 0;
|
int o2MedalRaceScore = 0;
|
||||||
int o2MedalRaceScore = 0;
|
for (RaceColumn raceColumn : getLeaderboard().getRaceColumns()) {
|
||||||
for (RaceColumn raceColumn : getLeaderboard().getRaceColumns()) {
|
int preemptiveColumnResult = 0;
|
||||||
int preemptiveColumnResult = 0;
|
final int o1Score = totalPointsCache.get(new Pair<Competitor, RaceColumn>(o1, raceColumn));
|
||||||
final int o1Score = getLeaderboard().getTotalPoints(o1, raceColumn, timePoint);
|
if (o1Score != 0) {
|
||||||
if (o1Score != 0) {
|
o1Scores.add(o1Score);
|
||||||
o1Scores.add(o1Score);
|
o1ScoreSum += o1Score;
|
||||||
o1ScoreSum += o1Score;
|
|
||||||
}
|
|
||||||
final int o2Score = getLeaderboard().getTotalPoints(o2, raceColumn, timePoint);
|
|
||||||
if (o2Score != 0) {
|
|
||||||
o2Scores.add(o2Score);
|
|
||||||
o2ScoreSum += o2Score;
|
|
||||||
}
|
|
||||||
if (raceColumn.isMedalRace()) {
|
|
||||||
o1MedalRaceScore = o1Score;
|
|
||||||
o2MedalRaceScore = o2Score;
|
|
||||||
// similar to compareByFleet, however, tracking is not required; having medal race column points (tracked or manual) is sufficient
|
|
||||||
preemptiveColumnResult = compareByMedalRaceParticipation(o1Score, o2Score);
|
|
||||||
}
|
|
||||||
if (preemptiveColumnResult == 0) {
|
|
||||||
preemptiveColumnResult = compareByFleet(raceColumn, o1, o2);
|
|
||||||
}
|
|
||||||
if (preemptiveColumnResult != 0) {
|
|
||||||
return preemptiveColumnResult;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
// now count the races in which they scored; if they scored in a different number of races, prefer the competitor
|
final int o2Score = totalPointsCache.get(new Pair<Competitor, RaceColumn>(o2, raceColumn));
|
||||||
// who scored more often; otherwise, prefer the competitor who has a better score sum; if score sums are equal, break
|
if (o2Score != 0) {
|
||||||
// tie by sorting scores and looking for the first score difference.
|
o2Scores.add(o2Score);
|
||||||
int result = compareByNumberOfRacesScored(o1Scores.size(), o2Scores.size());
|
o2ScoreSum += o2Score;
|
||||||
if (result == 0) {
|
}
|
||||||
result = compareByScoreSum(o1ScoreSum, o2ScoreSum);
|
if (raceColumn.isMedalRace()) {
|
||||||
if (result == 0) {
|
o1MedalRaceScore = o1Score;
|
||||||
result = compareByMedalRaceScore(o1MedalRaceScore, o2MedalRaceScore);
|
o2MedalRaceScore = o2Score;
|
||||||
if (result == 0) {
|
// similar to compareByFleet, however, tracking is not required; having medal race column points
|
||||||
result = compareByBetterScore(o1Scores, o2Scores);
|
// (tracked or manual) is sufficient
|
||||||
}
|
preemptiveColumnResult = compareByMedalRaceParticipation(o1Score, o2Score);
|
||||||
}
|
}
|
||||||
|
if (preemptiveColumnResult == 0) {
|
||||||
|
preemptiveColumnResult = compareByFleet(raceColumn, o1, o2);
|
||||||
|
}
|
||||||
|
if (preemptiveColumnResult != 0) {
|
||||||
|
return preemptiveColumnResult;
|
||||||
}
|
}
|
||||||
return result;
|
|
||||||
} catch (NoWindException e) {
|
|
||||||
throw new NoWindError(e);
|
|
||||||
}
|
}
|
||||||
|
// now count the races in which they scored; if they scored in a different number of races, prefer the
|
||||||
|
// competitor
|
||||||
|
// who scored more often; otherwise, prefer the competitor who has a better score sum; if score sums are equal,
|
||||||
|
// break
|
||||||
|
// tie by sorting scores and looking for the first score difference.
|
||||||
|
int result = compareByNumberOfRacesScored(o1Scores.size(), o2Scores.size());
|
||||||
|
if (result == 0) {
|
||||||
|
result = compareByScoreSum(o1ScoreSum, o2ScoreSum);
|
||||||
|
if (result == 0) {
|
||||||
|
result = compareByMedalRaceScore(o1MedalRaceScore, o2MedalRaceScore);
|
||||||
|
if (result == 0) {
|
||||||
|
result = compareByBetterScore(o1Scores, o2Scores);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
Reference in new issue
Block a user