mirror of
https://github.com/eclipse-sailing-analytics/sailing-analytics.git
synced 2026-11-12 05:35:31 +00:00
bug5715: interims (backup) commit, starting test for hand-crafted semi-finals
This commit is contained in:
1 parent
ae92945b21
commit
d8bebee97c
4 files changed
+119
-40
No files matched your search
+114
-25
@@ -22,12 +22,14 @@ import com.sap.sailing.domain.base.Competitor;
|
||||
import com.sap.sailing.domain.base.DomainFactory;
|
||||
import com.sap.sailing.domain.base.Fleet;
|
||||
import com.sap.sailing.domain.base.RaceColumn;
|
||||
import com.sap.sailing.domain.base.RaceColumnInSeries;
|
||||
import com.sap.sailing.domain.base.Regatta;
|
||||
import com.sap.sailing.domain.base.Series;
|
||||
import com.sap.sailing.domain.base.impl.FleetImpl;
|
||||
import com.sap.sailing.domain.base.impl.RegattaImpl;
|
||||
import com.sap.sailing.domain.base.impl.SeriesImpl;
|
||||
import com.sap.sailing.domain.common.CompetitorRegistrationType;
|
||||
import com.sap.sailing.domain.common.MaxPointsReason;
|
||||
import com.sap.sailing.domain.common.NoWindException;
|
||||
import com.sap.sailing.domain.common.ScoringSchemeType;
|
||||
import com.sap.sailing.domain.leaderboard.Leaderboard;
|
||||
@@ -62,22 +64,6 @@ public class LeaderboardScoringAndRankingTestForLowPointThreeMedalWins extends L
|
||||
private Regatta regatta;
|
||||
private RegattaLeaderboard leaderboard;
|
||||
|
||||
/**
|
||||
* The competitor orders provided in the lists define the points scored in the respective race, one-based
|
||||
*/
|
||||
private void executePreSeries(List<Competitor> yellowR1, List<Competitor> blueR1, List<Competitor> goldR2, List<Competitor> silverR2, TimePoint now) {
|
||||
final RaceColumn qColumnR1 = series.get(0).getRaceColumnByName("R1");
|
||||
final TrackedRace qYellowR1 = new MockedTrackedRaceWithStartTimeAndRanks(now, yellowR1);
|
||||
qColumnR1.setTrackedRace(qColumnR1.getFleetByName("Yellow"), qYellowR1);
|
||||
final TrackedRace qBlueR1 = new MockedTrackedRaceWithStartTimeAndRanks(now, blueR1);
|
||||
qColumnR1.setTrackedRace(qColumnR1.getFleetByName("Blue"), qBlueR1);
|
||||
final RaceColumn fColumnR2 = series.get(1).getRaceColumnByName("R2");
|
||||
final TrackedRace fGoldR2 = new MockedTrackedRaceWithStartTimeAndRanks(now, goldR2);
|
||||
fColumnR2.setTrackedRace(fColumnR2.getFleetByName("Gold"), fGoldR2);
|
||||
final TrackedRace fSilverR2 = new MockedTrackedRaceWithStartTimeAndRanks(now, silverR2);
|
||||
fColumnR2.setTrackedRace(fColumnR2.getFleetByName("Silver"), fSilverR2);
|
||||
}
|
||||
|
||||
private Regatta setupRegatta() {
|
||||
final BoatClass boatClass = DomainFactory.INSTANCE.getOrCreateBoatClass("Kite", /* typicallyStartsUpwind */ true);
|
||||
Regatta regatta = new RegattaImpl(RegattaImpl.getDefaultName("Test Regatta", boatClass.getName()), boatClass,
|
||||
@@ -186,16 +172,8 @@ public class LeaderboardScoringAndRankingTestForLowPointThreeMedalWins extends L
|
||||
private void testWithRandomRaceOutcomes(final int numberOfCompetitors) {
|
||||
TimePoint now = MillisecondsTimePoint.now();
|
||||
TimePoint later = new MillisecondsTimePoint(now.asMillis() + 1000);
|
||||
createCompetitorsAndRunAndAssertOpeningSeries(now, later, numberOfCompetitors);
|
||||
final List<Competitor> openingSeriesRankResult = leaderboard.getCompetitorsFromBestToWorst(later);
|
||||
final Util.Pair<List<Competitor>, List<Competitor>> semiFinalists = assignCarryForwardWinsToSemiFinalistsAndGrandFinalists(later);
|
||||
// lottery for semi-final races until we have three wins:
|
||||
runRacesInFinalUntilThreeWins(semiFinalists.getA(), regatta.getSeriesByName(SEMIFINAL_SERIES_NAME), SEMIFINAL_FLEET_A_NAME, now);
|
||||
runRacesInFinalUntilThreeWins(semiFinalists.getB(), regatta.getSeriesByName(SEMIFINAL_SERIES_NAME), SEMIFINAL_FLEET_B_NAME, now);
|
||||
// check that the semi-final winners took three wins (including carried wins) each:
|
||||
final List<Competitor> openingSeriesRankResult = raceAndAssertOpeningSeriesAndRandomSemiFinals(now, later, numberOfCompetitors);
|
||||
final List<Competitor> rankResultsAfterSemifinals = leaderboard.getCompetitorsFromBestToWorst(later);
|
||||
assertEquals(3.0, leaderboard.getNetPoints(rankResultsAfterSemifinals.get(2), later), EPSILON);
|
||||
assertEquals(3.0, leaderboard.getNetPoints(rankResultsAfterSemifinals.get(3), later), EPSILON);
|
||||
// assemble final fleet:
|
||||
final List<Competitor> finalists = new ArrayList<>();
|
||||
finalists.add(openingSeriesRankResult.get(0));
|
||||
@@ -213,6 +191,78 @@ public class LeaderboardScoringAndRankingTestForLowPointThreeMedalWins extends L
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* In this test the opening series winner will win the first race, and should get a score of 2, all other finalists
|
||||
* should be scored with Low_Points restarting at 0 for the medal series. The non finalists score should not change
|
||||
* during the medalseries.
|
||||
*/
|
||||
@Test
|
||||
public void testWithTiesInFinal() {
|
||||
TimePoint now = MillisecondsTimePoint.now();
|
||||
TimePoint later = new MillisecondsTimePoint(now.asMillis() + 1000);
|
||||
final List<Competitor> openingSeriesRankResult = raceAndAssertOpeningSeriesAndRandomSemiFinals(now, later, /* numberOfCompetitors */ 100);
|
||||
final List<Competitor> rankResultsAfterSemifinals = leaderboard.getCompetitorsFromBestToWorst(later);
|
||||
// assemble final fleet:
|
||||
final List<Competitor> finalists = new ArrayList<>();
|
||||
finalists.add(openingSeriesRankResult.get(0));
|
||||
finalists.add(openingSeriesRankResult.get(1));
|
||||
finalists.add(rankResultsAfterSemifinals.get(2));
|
||||
finalists.add(rankResultsAfterSemifinals.get(3));
|
||||
// the two promoted semi-finalists have no carried wins; if they don't win they are tied on their zero wins;
|
||||
// if they score equal, e.g., both DNF (5), the tie has to be broken by their opening series rank:
|
||||
final TrackedRace finalRace = new MockedTrackedRaceWithStartTimeAndRanks(now, finalists); // (0) wins, with two carried wins has three wins
|
||||
final Series grandFinalSeries = regatta.getSeriesByName(GRANDFINAL_SERIES_NAME);
|
||||
final RaceColumnInSeries f1Column = grandFinalSeries.getRaceColumnByName("F1");
|
||||
f1Column.setTrackedRace(grandFinalSeries.getFleetByName(GRANDFINAL_DEFAULT_FLEET_NAME), finalRace);
|
||||
leaderboard.getScoreCorrection().correctScore(finalists.get(2), f1Column, 5.0);
|
||||
leaderboard.getScoreCorrection().setMaxPointsReason(finalists.get(2), f1Column, MaxPointsReason.DNC);
|
||||
leaderboard.getScoreCorrection().correctScore(finalists.get(3), f1Column, 5.0);
|
||||
leaderboard.getScoreCorrection().setMaxPointsReason(finalists.get(3), f1Column, MaxPointsReason.DNF);
|
||||
// check total results:
|
||||
final List<Competitor> rankResultsAfterGrandFinal = leaderboard.getCompetitorsFromBestToWorst(later);
|
||||
assertSame(finalists.get(0), rankResultsAfterGrandFinal.get(0)); // winner of last race wins the regatta
|
||||
assertEquals(3.0, leaderboard.getNetPoints(rankResultsAfterGrandFinal.get(0), later), EPSILON);
|
||||
assertSame(finalists.get(2), rankResultsAfterGrandFinal.get(2));
|
||||
assertSame(finalists.get(3), rankResultsAfterGrandFinal.get(3));
|
||||
}
|
||||
|
||||
/**
|
||||
* In this test A races one race, B two. The semi-finals are crafted such that there are ties on wins
|
||||
* between competitors from A and B, so checking the last race's rank shall break the tie.
|
||||
*/
|
||||
@Test
|
||||
public void testWithTiesInSemiFinalWithDifferentNumbersOfSemifinalRaces() {
|
||||
TimePoint now = MillisecondsTimePoint.now();
|
||||
TimePoint later = new MillisecondsTimePoint(now.asMillis() + 1000);
|
||||
createCompetitorsAndRunAndAssertOpeningSeries(now, later, /* numberOfCompetitors */ 100);
|
||||
final List<Competitor> openingSeriesRankResult = leaderboard.getCompetitorsFromBestToWorst(later);
|
||||
final Util.Pair<List<Competitor>, List<Competitor>> semiFinalists = assignCarryForwardWinsToSemiFinalistsAndGrandFinalists(later);
|
||||
|
||||
// TODO
|
||||
|
||||
final List<Competitor> rankResultsAfterSemifinals = leaderboard.getCompetitorsFromBestToWorst(later);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the ranking results after the opening series and before adding the carried wins
|
||||
*/
|
||||
private List<Competitor> raceAndAssertOpeningSeriesAndRandomSemiFinals(TimePoint now, TimePoint later, int numberOfCompetitors) {
|
||||
createCompetitorsAndRunAndAssertOpeningSeries(now, later, numberOfCompetitors);
|
||||
final List<Competitor> openingSeriesRankResult = leaderboard.getCompetitorsFromBestToWorst(later);
|
||||
final Util.Pair<List<Competitor>, List<Competitor>> semiFinalists = assignCarryForwardWinsToSemiFinalistsAndGrandFinalists(later);
|
||||
// lottery for semi-final races until we have three wins:
|
||||
final Series semiFinalSeries = regatta.getSeriesByName(SEMIFINAL_SERIES_NAME);
|
||||
runRacesInFinalUntilThreeWins(semiFinalists.getA(), semiFinalSeries, SEMIFINAL_FLEET_A_NAME, now);
|
||||
runRacesInFinalUntilThreeWins(semiFinalists.getB(), semiFinalSeries, SEMIFINAL_FLEET_B_NAME, now);
|
||||
// check that the semi-final winners took three wins (including carried wins) each:
|
||||
final List<Competitor> rankResultsAfterSemifinals = leaderboard.getCompetitorsFromBestToWorst(later);
|
||||
assertEquals(3.0, leaderboard.getNetPoints(rankResultsAfterSemifinals.get(2), later), EPSILON);
|
||||
assertEquals(3.0, leaderboard.getNetPoints(rankResultsAfterSemifinals.get(3), later), EPSILON);
|
||||
assertSemiFinalistRanks(leaderboard, semiFinalSeries, semiFinalists, leaderboard.getCompetitorsFromBestToWorst(later), openingSeriesRankResult, later);
|
||||
return openingSeriesRankResult;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param numberOfCompetitors
|
||||
* must be evenly divisible by four, so we can have two opening series fleets and promote the better half
|
||||
@@ -281,6 +331,45 @@ public class LeaderboardScoringAndRankingTestForLowPointThreeMedalWins extends L
|
||||
}
|
||||
return new Util.Pair<>(sfACompetitors, sfBCompetitors);
|
||||
}
|
||||
|
||||
/**
|
||||
* The competitor orders provided in the lists define the points scored in the respective race, one-based
|
||||
*/
|
||||
private void executePreSeries(List<Competitor> yellowR1, List<Competitor> blueR1, List<Competitor> goldR2, List<Competitor> silverR2, TimePoint now) {
|
||||
final RaceColumn qColumnR1 = series.get(0).getRaceColumnByName("R1");
|
||||
final TrackedRace qYellowR1 = new MockedTrackedRaceWithStartTimeAndRanks(now, yellowR1);
|
||||
qColumnR1.setTrackedRace(qColumnR1.getFleetByName("Yellow"), qYellowR1);
|
||||
final TrackedRace qBlueR1 = new MockedTrackedRaceWithStartTimeAndRanks(now, blueR1);
|
||||
qColumnR1.setTrackedRace(qColumnR1.getFleetByName("Blue"), qBlueR1);
|
||||
final RaceColumn fColumnR2 = series.get(1).getRaceColumnByName("R2");
|
||||
final TrackedRace fGoldR2 = new MockedTrackedRaceWithStartTimeAndRanks(now, goldR2);
|
||||
fColumnR2.setTrackedRace(fColumnR2.getFleetByName("Gold"), fGoldR2);
|
||||
final TrackedRace fSilverR2 = new MockedTrackedRaceWithStartTimeAndRanks(now, silverR2);
|
||||
fColumnR2.setTrackedRace(fColumnR2.getFleetByName("Silver"), fSilverR2);
|
||||
}
|
||||
|
||||
/**
|
||||
* For all finalists adjacent in the {@code rankResultsAfterGrandFinal} checks that the competitor ranked better
|
||||
* has more or equal wins; if equal wins, scored better in the last race; if scored equal in the last race had
|
||||
* better rank in {@code openingSeriesRankResult}.
|
||||
*/
|
||||
private void assertSemiFinalistRanks(Leaderboard leaderboard, Series semiFinalSeries, Pair<List<Competitor>, List<Competitor>> semiFinalists,
|
||||
List<Competitor> rankResultsAfterSemiFinal, List<Competitor> openingSeriesRankResult, TimePoint timePoint) {
|
||||
assertTrue(semiFinalSeries.isMedal());
|
||||
// assert that all finalists form the top overall ranks
|
||||
final List<Competitor> semiFinalistsInRankedOrder = rankResultsAfterSemiFinal.subList(2, 2+semiFinalists.getA().size()+semiFinalists.getB().size());
|
||||
final Set<Competitor> allSemifinalists = new HashSet<>();
|
||||
allSemifinalists.addAll(semiFinalists.getA());
|
||||
allSemifinalists.addAll(semiFinalists.getB());
|
||||
assertEquals(allSemifinalists, new HashSet<>(semiFinalistsInRankedOrder));
|
||||
Competitor previous = null;
|
||||
for (final Competitor next : semiFinalistsInRankedOrder) {
|
||||
if (previous != null) {
|
||||
assertCorrectMedalSeriesSequence(leaderboard, semiFinalSeries, previous, next, openingSeriesRankResult, timePoint);
|
||||
}
|
||||
previous = next;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* For all finalists adjacent in the {@code rankResultsAfterGrandFinal} checks that the competitor ranked better
|
||||
|
||||
@@ -175,14 +175,6 @@ public interface ScoringScheme extends Serializable {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* If {@link #isMedalWinAmountCriteria()} returns {@code true}, this will be the amount of races that must be won,
|
||||
* in order to win the medal series instantly
|
||||
*/
|
||||
default int getTargetAmountOfMedalRaceWins() {
|
||||
throw new IllegalStateException("This call is not valid for this scoringSheme");
|
||||
}
|
||||
|
||||
/**
|
||||
* Usually, the scores in each leaderboard column count as they are for the overall score. However, if a column is a
|
||||
* medal race column it usually counts double. Under certain circumstances, columns may also count with factors
|
||||
|
||||
-5
@@ -88,11 +88,6 @@ public class LowPointFirstToWinThreeRaces extends LowPoint {
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getTargetAmountOfMedalRaceWins() {
|
||||
return 3;
|
||||
}
|
||||
|
||||
/**
|
||||
* In equal-weighted semifinal fleets A/B a different number of races may be sailed until any one competitor
|
||||
* in that fleet has reached {@link #getTargetAmountOfMedalRaceWins()} wins. Therefore, the number of races
|
||||
|
||||
+5
-2
@@ -44,8 +44,11 @@ public class LowPointFirstToWinTwoRaces extends LowPoint {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getTargetAmountOfMedalRaceWins() {
|
||||
/**
|
||||
* If {@link #isMedalWinAmountCriteria()} returns {@code true}, this will be the amount of races that must be won,
|
||||
* in order to win the medal series instantly
|
||||
*/
|
||||
private int getTargetAmountOfMedalRaceWins() {
|
||||
return 2;
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user