java/com.sap.sailing.domain.test/src/com/sap/sailing/domain/test/LeaderboardScoringAndRankingForLowPointsTest.java
... ...
@@ -2,6 +2,7 @@ package com.sap.sailing.domain.test;
2 2
3 3
import static org.junit.jupiter.api.Assertions.assertEquals;
4 4
import static org.junit.jupiter.api.Assertions.assertSame;
5
+import static org.junit.jupiter.api.Assertions.assertTrue;
5 6
6 7
import java.util.ArrayList;
7 8
import java.util.Arrays;
... ...
@@ -172,6 +173,79 @@ public class LeaderboardScoringAndRankingForLowPointsTest extends LeaderboardSco
172 173
}
173 174
174 175
@Test
176
+ public void testA8TieBreakForMulitpleMedalRacesWithCarryColumn() {
177
+ final TimePoint now = TimePoint.now();
178
+ series = new ArrayList<>();
179
+ final List<Fleet> fleets = new ArrayList<>();
180
+ final Fleet defaultFleet = new FleetImpl("Default");
181
+ fleets.add(defaultFleet);
182
+ final List<String> raceColumnNames = Arrays.asList("R1", "R2", "R3");
183
+ Series openingSeries = new SeriesImpl("Opening", /* isMedal */ false,
184
+ /* isFleetsCanRunInParallel */ true, fleets, raceColumnNames,
185
+ /* trackedRegattaRegistry */ null);
186
+ series.add(openingSeries);
187
+ final List<Fleet> medalFleet = new ArrayList<>();
188
+ final Fleet medalDefaultFleet = new FleetImpl("Default");
189
+ medalFleet.add(medalDefaultFleet);
190
+ final List<String> medalRaceColumnNames = Arrays.asList("Carry", "F1", "F2");
191
+ final Series medalSeries = new SeriesImpl("Medal", /* isMedal */ true, /* isFleetsCanRunInParallel */ true,
192
+ medalFleet, medalRaceColumnNames, /* trackedRegattaRegistry */ null);
193
+ medalSeries.setFirstColumnIsNonDiscardableCarryForward(true);
194
+ medalSeries.setStartsWithZeroScore(true);
195
+ series.add(medalSeries);
196
+ final Regatta regatta = setupRegatta(/* use first two wins */ false); // regular LowPoint
197
+ final List<Competitor> competitors = createCompetitors(20);
198
+ openingSeries.getRaceColumnByName("R1").setTrackedRace(defaultFleet, new MockedTrackedRaceWithStartTimeAndRanks(now, competitors));
199
+ openingSeries.getRaceColumnByName("R2").setTrackedRace(defaultFleet, new MockedTrackedRaceWithStartTimeAndRanks(now, competitors));
200
+ openingSeries.getRaceColumnByName("R3").setTrackedRace(defaultFleet, new MockedTrackedRaceWithStartTimeAndRanks(now, competitors));
201
+ final Leaderboard leaderboard = createLeaderboard(regatta, /* discarding thresholds */ new int[0]);
202
+ final RaceColumn carryColumn = leaderboard.getRaceColumnByName("Carry");
203
+ for (int medalRaceCompetitorIndex=0; medalRaceCompetitorIndex<10; medalRaceCompetitorIndex++) {
204
+ final double regularScore = 3*(medalRaceCompetitorIndex+1); // 3, 6, 9, ...
205
+ leaderboard.getScoreCorrection().correctScore(competitors.get(medalRaceCompetitorIndex), carryColumn, Math.min(regularScore, 3*3+18));
206
+ }
207
+ final RaceColumn f1 = leaderboard.getRaceColumnByName("F1");
208
+ final RaceColumn f2 = leaderboard.getRaceColumnByName("F2");
209
+ carryColumn.setFactor(1.0);
210
+ f1.setFactor(1.0);
211
+ f2.setFactor(1.0);
212
+ // construct a tie between C1 and C2 (index 0 and 1, respectively); the tie is expected to be broken
213
+ // in favor of C2 because C2 must have performed better in the medal races F1/F2 due to the worse
214
+ // carried score
215
+ assertEquals(3.0, leaderboard.getNetPoints(competitors.get(0), carryColumn, now), EPSILON);
216
+ leaderboard.getScoreCorrection().correctScore(competitors.get(0), f1, 5.0);
217
+ leaderboard.getScoreCorrection().correctScore(competitors.get(0), f2, 3.0); // medal series: 3 (Carry) + 5 + 3 = 11
218
+ assertEquals(6.0, leaderboard.getNetPoints(competitors.get(1), carryColumn, now), EPSILON);
219
+ leaderboard.getScoreCorrection().correctScore(competitors.get(1), f1, 1.0);
220
+ leaderboard.getScoreCorrection().correctScore(competitors.get(1), f2, 4.0); // medal series: 6 (Carry) + 1 + 4 = 11
221
+ // construct a tie between C9 and C10 (index 8 and 9, respectively); the tie is expected to be broken
222
+ // in favor of C9 because although both carried the same number of points from the open series due
223
+ // to the "reduced points" rule, and both scores equal points in total in F1 and F2, C9 had the better
224
+ // best score.
225
+ assertEquals(leaderboard.getNetPoints(competitors.get(8), carryColumn, now), leaderboard.getNetPoints(competitors.get(9), carryColumn, now), EPSILON);
226
+ leaderboard.getScoreCorrection().correctScore(competitors.get(8), f1, 6.0);
227
+ leaderboard.getScoreCorrection().correctScore(competitors.get(8), f1, 8.0);
228
+ leaderboard.getScoreCorrection().correctScore(competitors.get(9), f1, 7.0);
229
+ leaderboard.getScoreCorrection().correctScore(competitors.get(9), f1, 7.0);
230
+ // construct scores for the remaining competitors C3..C8
231
+ leaderboard.getScoreCorrection().correctScore(competitors.get(2), f1, 2.0);
232
+ leaderboard.getScoreCorrection().correctScore(competitors.get(3), f1, 3.0);
233
+ leaderboard.getScoreCorrection().correctScore(competitors.get(4), f1, 4.0);
234
+ leaderboard.getScoreCorrection().correctScore(competitors.get(5), f1, 8.0);
235
+ leaderboard.getScoreCorrection().correctScore(competitors.get(6), f1, 9.0);
236
+ leaderboard.getScoreCorrection().correctScore(competitors.get(7), f1, 10.0);
237
+ leaderboard.getScoreCorrection().correctScore(competitors.get(2), f2, 1.0);
238
+ leaderboard.getScoreCorrection().correctScore(competitors.get(3), f2, 2.0);
239
+ leaderboard.getScoreCorrection().correctScore(competitors.get(4), f2, 5.0);
240
+ leaderboard.getScoreCorrection().correctScore(competitors.get(5), f2, 6.0);
241
+ leaderboard.getScoreCorrection().correctScore(competitors.get(6), f2, 9.0);
242
+ leaderboard.getScoreCorrection().correctScore(competitors.get(7), f2, 10.0);
243
+ final Iterable<Competitor> ranking = leaderboard.getCompetitorsFromBestToWorst(now);
244
+ assertTrue(Util.indexOf(ranking, competitors.get(1)) < Util.indexOf(ranking, competitors.get(0)));
245
+ assertTrue(Util.indexOf(ranking, competitors.get(8)) < Util.indexOf(ranking, competitors.get(9)));
246
+ }
247
+
248
+ @Test
175 249
public void testMultipleRDGsAndSCAs() {
176 250
final TimePoint now = TimePoint.now();
177 251
final TimePoint later = now.plus(Duration.ONE_MINUTE);