From c615b2f9068ab812de8eba8736b027e89b6959f5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kai=20B=C3=B6rnert?= Date: Fri, 13 Jul 2018 13:59:40 +0200 Subject: [PATCH 01/43] bug4661 initial approach for new scoring scheme --- .../domain/common/ScoringSchemeType.java | 2 +- .../domain/base/impl/DomainFactoryImpl.java | 5 +++ .../domain/leaderboard/ScoringScheme.java | 12 ++++++ .../impl/AbstractSimpleLeaderboardImpl.java | 16 ++++++++ .../impl/LeaderboardTotalRankComparator.java | 41 +++++++++++++++---- .../impl/LowPointFirstToWinTwoRaces.java | 34 +++++++++++++++ .../sailing/gwt/ui/client/StringMessages.java | 1 + .../gwt/ui/client/StringMessages.properties | 1 + .../ScoringSchemeTypeFormatter.java | 2 + 9 files changed, 106 insertions(+), 8 deletions(-) create mode 100644 java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/impl/LowPointFirstToWinTwoRaces.java diff --git a/java/com.sap.sailing.domain.common/src/com/sap/sailing/domain/common/ScoringSchemeType.java b/java/com.sap.sailing.domain.common/src/com/sap/sailing/domain/common/ScoringSchemeType.java index c419b8d1bd1..c90803d5eda 100755 --- a/java/com.sap.sailing.domain.common/src/com/sap/sailing/domain/common/ScoringSchemeType.java +++ b/java/com.sap.sailing.domain.common/src/com/sap/sailing/domain/common/ScoringSchemeType.java @@ -5,5 +5,5 @@ public enum ScoringSchemeType { LOW_POINT, LOW_POINT_WITH_AUTOMATIC_RDG, HIGH_POINT, HIGH_POINT_ESS_OVERALL,HIGH_POINT_ESS_OVERALL_12, HIGH_POINT_LAST_BREAKS_TIE, HIGH_POINT_FIRST_GETS_TEN, HIGH_POINT_FIRST_GETS_ONE, LOW_POINT_WINNER_GETS_ZERO, HIGH_POINT_WINNER_GETS_SIX, HIGH_POINT_WINNER_GETS_FIVE, HIGH_POINT_WINNER_GETS_EIGHT, HIGH_POINT_WINNER_GETS_EIGHT_AND_INTERPOLATION, HIGH_POINT_FIRST_GETS_TEN_OR_EIGHT, HIGH_POINT_FIRST_GETS_TWELVE_OR_EIGHT, HIGH_POINT_FIRST_GETS_TWELVE_OR_EIGHT_2017, LOW_POINT_WITH_ELIMINATIONS_AND_ROUNDS_WINNER_GETS_07, - LOW_POINT_LEAGUE_OVERALL, HIGH_POINT_MATCH_RACING, LOW_POINT_TIE_BREAK_BASED_ON_LAST_SERIES_ONLY + LOW_POINT_LEAGUE_OVERALL, HIGH_POINT_MATCH_RACING, LOW_POINT_TIE_BREAK_BASED_ON_LAST_SERIES_ONLY, LOW_POINT_FIRST_TO_WIN_TWO_RACES } diff --git a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/base/impl/DomainFactoryImpl.java b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/base/impl/DomainFactoryImpl.java index f86247656d9..01e73aeacfe 100755 --- a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/base/impl/DomainFactoryImpl.java +++ b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/base/impl/DomainFactoryImpl.java @@ -58,6 +58,7 @@ import com.sap.sailing.domain.leaderboard.impl.HighPointWinnerGetsEightAndInterp import com.sap.sailing.domain.leaderboard.impl.HighPointWinnerGetsFive; import com.sap.sailing.domain.leaderboard.impl.HighPointWinnerGetsSix; import com.sap.sailing.domain.leaderboard.impl.LowPoint; +import com.sap.sailing.domain.leaderboard.impl.LowPointFirstToWinTwoRaces; import com.sap.sailing.domain.leaderboard.impl.LowPointForLeagueOverallLeaderboard; import com.sap.sailing.domain.leaderboard.impl.LowPointTieBreakBasedOnLastSeriesOnly; import com.sap.sailing.domain.leaderboard.impl.LowPointWinnerGetsZero; @@ -144,6 +145,10 @@ public class DomainFactoryImpl extends SharedDomainFactoryImpl implements Domain return new LowPointTieBreakBasedOnLastSeriesOnly(); case LOW_POINT_WITH_AUTOMATIC_RDG: return new LowPointWithAutomaticRDG(); + case LOW_POINT_FIRST_TO_WIN_TWO_RACES: + return new LowPointFirstToWinTwoRaces(); + default: + break; } throw new RuntimeException("Unknown scoring scheme type "+scoringSchemeType.name()); } diff --git a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/ScoringScheme.java b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/ScoringScheme.java index ec65a4d43be..a40e464b828 100755 --- a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/ScoringScheme.java +++ b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/ScoringScheme.java @@ -119,4 +119,16 @@ public interface ScoringScheme extends Serializable { * @throws NoWindException */ int compareByLatestRegattaInMetaLeaderboard(Leaderboard leaderboard, Competitor o1, Competitor o2, TimePoint timePoint); + + default boolean isMedalWinAmountCriteria() { + return false; + } + + default int getTargetAmountOfMedalRaceWins() { + throw new IllegalStateException("This call is not valid for this scoringSheme"); + } + + default boolean doesCountAsWinInMedalRace(Double o1Score, RaceColumn raceColumn) { + throw new IllegalStateException("This call is not valid for this scoringSheme"); + } } diff --git a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/impl/AbstractSimpleLeaderboardImpl.java b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/impl/AbstractSimpleLeaderboardImpl.java index d9577814e88..0a492966fd7 100644 --- a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/impl/AbstractSimpleLeaderboardImpl.java +++ b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/impl/AbstractSimpleLeaderboardImpl.java @@ -493,6 +493,7 @@ public abstract class AbstractSimpleLeaderboardImpl extends AbstractLeaderboardW // from there on boolean needToResetScoreUponNextNonEmptyEntry = false; double result = getCarriedPoints(competitor); + double wonRaces = 0; final Set discardedRaceColumns = getResultDiscardingRule().getDiscardedRaceColumns(competitor, this, raceColumnsToConsider, timePoint); for (RaceColumn raceColumn : raceColumnsToConsider) { @@ -501,15 +502,30 @@ public abstract class AbstractSimpleLeaderboardImpl extends AbstractLeaderboardW } if (getScoringScheme().isValidInNetScore(this, raceColumn, competitor, timePoint)) { final Double netPoints = getNetPoints(competitor, raceColumn, timePoint, discardedRaceColumns); + if(getScoringScheme().isMedalWinAmountCriteria()) { + wonRaces += getScoringScheme().doesCountAsWinInMedalRace(netPoints, raceColumn) ? 1 : 0; + } + if(true){ + System.out.println("Check " + competitor.getName() + " " + raceColumn.getName() + " " + netPoints + " " + wonRaces); + }else { + System.out.println("remove stuff"); + } if (netPoints != null) { if (needToResetScoreUponNextNonEmptyEntry) { result = 0; + //FIXME if medal amount, use carry column here instead of 0? + wonRaces = 0; needToResetScoreUponNextNonEmptyEntry = false; } result += netPoints; } } } + if(getScoringScheme().isMedalWinAmountCriteria()) { + if(wonRaces == getScoringScheme().getTargetAmountOfMedalRaceWins()) { + return 2.0; + } + } return result; } diff --git a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/impl/LeaderboardTotalRankComparator.java b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/impl/LeaderboardTotalRankComparator.java index b6e1e2af35c..76b116bc44e 100755 --- a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/impl/LeaderboardTotalRankComparator.java +++ b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/impl/LeaderboardTotalRankComparator.java @@ -124,6 +124,8 @@ public class LeaderboardTotalRankComparator implements Comparator { // it is guaranteed to have equal ordering as all fleets that the competitor is assigned to within the key series. final Map> fleetWithCorrectOrderingForCompetitorBySeries = new HashMap<>(); int defaultFleetBasedComparisonResult = 0; // relevant if no authoritative fleet-based comparison result was determined; based on extreme fleet vs. no fleet comparison + int numberOfMedalRacesWonO1 = 0; + int numberOfMedalRacesWonO2 = 0; for (RaceColumn raceColumn : getLeaderboard().getRaceColumns()) { needToResetO1ScoreUponNextValidResult = raceColumn.isStartsWithZeroScore(); needToResetO2ScoreUponNextValidResult = raceColumn.isStartsWithZeroScore(); @@ -182,6 +184,10 @@ public class LeaderboardTotalRankComparator implements Comparator { // similar to compareByFleet, however, tracking is not required; having medal race column points // (tracked or manual) is sufficient preemptiveColumnResult = compareByMedalRaceParticipation(o1Score, o2Score); + if(scoringScheme.isMedalWinAmountCriteria()) { + numberOfMedalRacesWonO1+= scoringScheme.doesCountAsWinInMedalRace(o1Score, raceColumn) ? 1:0; + numberOfMedalRacesWonO2+= scoringScheme.doesCountAsWinInMedalRace(o2Score, raceColumn) ? 1:0; + } } if (preemptiveColumnResult == 0 && raceColumn.isTotalOrderDefinedByFleet()) { final FleetComparisonResult compareByFleetResult = compareByFleet(raceColumn, o1, o2, fleetWithCorrectOrderingForCompetitorBySeries); @@ -205,27 +211,48 @@ public class LeaderboardTotalRankComparator implements Comparator { // 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(scoringScheme.isMedalWinAmountCriteria()) { + //FIXME somehere carry values must be obtained and added here, if compeitor was in carry + result = compareByMedalRacesWon(numberOfMedalRacesWonO1, numberOfMedalRacesWonO2); + } if (result == 0) { - result = compareByMedalRaceScore(o1MedalRaceScore, o2MedalRaceScore); + result = compareByScoreSum(o1ScoreSum, o2ScoreSum); if (result == 0) { - result = compareByBetterScore(o1, Collections.unmodifiableList(o1Scores), o2, Collections.unmodifiableList(o2Scores), timePoint); + result = compareByMedalRaceScore(o1MedalRaceScore, o2MedalRaceScore); if (result == 0) { - // compare by last race: - result = scoringScheme.compareByLastRace(o1TotalPoints, o2TotalPoints, nullScoresAreBetter, o1, o2); + result = compareByBetterScore(o1, Collections.unmodifiableList(o1Scores), o2, Collections.unmodifiableList(o2Scores), timePoint); if (result == 0) { - result = scoringScheme.compareByLatestRegattaInMetaLeaderboard(getLeaderboard(), o1, o2, timePoint); + // compare by last race: + result = scoringScheme.compareByLastRace(o1TotalPoints, o2TotalPoints, nullScoresAreBetter, o1, o2); if (result == 0) { - result = compareByArbitraryButStableCriteria(o1, o2); + result = scoringScheme.compareByLatestRegattaInMetaLeaderboard(getLeaderboard(), o1, o2, timePoint); + if (result == 0) { + result = compareByArbitraryButStableCriteria(o1, o2); + } } } } } + }else { + System.out.println("chjeck me"); } + } return result; } + private int compareByMedalRacesWon(int numberOfMedalRacesWonO1, int numberOfMedalRacesWonO2) { + int targetAmount = scoringScheme.getTargetAmountOfMedalRaceWins(); + //if one reaches the targetamount, this has precendece, else proceed with normal low points scoring (eg not enough races yet) + if(numberOfMedalRacesWonO1 == targetAmount) { + return -1; + } + if(numberOfMedalRacesWonO2 == targetAmount) { + return 1; + } + return 0; + } + private int compareByArbitraryButStableCriteria(Competitor o1, Competitor o2) { return o1.getName().compareTo(o2.getName()); } diff --git a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/impl/LowPointFirstToWinTwoRaces.java b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/impl/LowPointFirstToWinTwoRaces.java new file mode 100644 index 00000000000..56ad2c98bb2 --- /dev/null +++ b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/impl/LowPointFirstToWinTwoRaces.java @@ -0,0 +1,34 @@ +package com.sap.sailing.domain.leaderboard.impl; + +import com.sap.sailing.domain.base.RaceColumn; +import com.sap.sailing.domain.common.ScoringSchemeType; + +public class LowPointFirstToWinTwoRaces extends LowPoint { + private static final long serialVersionUID = 7072175334160798617L; + + @Override + public ScoringSchemeType getType() { + return ScoringSchemeType.LOW_POINT_FIRST_TO_WIN_TWO_RACES; + } + + @Override + public boolean isMedalWinAmountCriteria() { + return true; + } + + @Override + public int getTargetAmountOfMedalRaceWins() { + return 2; + } + + @Override + public boolean doesCountAsWinInMedalRace(Double score, RaceColumn raceColumn) { + if(score != null) { + double minScore = 1 * raceColumn.getFactor(); + return score == minScore; + } else { + return false; + } + } + +} diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/StringMessages.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/StringMessages.java index b82c8f5e2cc..6e86ff570e1 100755 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/StringMessages.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/StringMessages.java @@ -434,6 +434,7 @@ public interface StringMessages extends com.sap.sse.gwt.client.StringMessages, String insertWaypointAfterSelected(); String addGate(); String scoringSchemeLowPointSystem(); + String scoringSchemeLowPointSystemFirstTwoWins(); String scoringSchemeHighPointSystem(); String scoringSchemeLowPointWinnerGetsZero(); String scoringSchemeWinnerGetsFive(); diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/StringMessages.properties b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/StringMessages.properties index 58d845eff16..de4510c4480 100755 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/StringMessages.properties +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/StringMessages.properties @@ -484,6 +484,7 @@ scoringSchemeHighPointFirstGetsTwelveOrEight=High Point, winner gets 12 points ( scoringSchemeHighPointFirstGetsTwelveOrEightDescription=Score in points. Winner scores 12 points, 2nd - 11 points, .... A tie is broken in favour of the competitor with the highest score, if tie remains then tie is broken by the rank in the last race scored. scoringSchemeHighPointFirstGetsTwelveOrEight2017=High Point ESS 2017, winner gets 12 points (or 8) scoringSchemeHighPointFirstGetsTwelveOrEight2017Description=Score in points. Winner scores 12 points, 2nd - 11 points, .... A tie is broken in favour of the competitor with the highest score, if tie remains then tie is broken by the rank in the last race scored. +scoringSchemeLowPointSystemFirstTwoWins=Low Point System, First two wins scoringSystem=Scoring system createFlexibleLeaderboard=Create flexible leaderboard createRegattaLeaderboard=Create regatta leaderboard diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/leaderboard/ScoringSchemeTypeFormatter.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/leaderboard/ScoringSchemeTypeFormatter.java index d0d295a59d9..57bb7c5b241 100644 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/leaderboard/ScoringSchemeTypeFormatter.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/leaderboard/ScoringSchemeTypeFormatter.java @@ -46,6 +46,8 @@ public class ScoringSchemeTypeFormatter { return stringMessages.scoringSchemeLowPointTieBreakBasedOnLastSeriesOnly(); case LOW_POINT_WITH_AUTOMATIC_RDG: return stringMessages.scoringSchemeLowPointWithAutomaticRdg(); + case LOW_POINT_FIRST_TO_WIN_TWO_RACES: + return stringMessages.scoringSchemeLowPointSystemFirstTwoWins(); } return null; } From 879c0c350410ba6abeb53e20fbbc6e7a8bf60e25 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kai=20B=C3=B6rnert?= Date: Fri, 13 Jul 2018 14:38:06 +0200 Subject: [PATCH 02/43] move score factor calculation to ScoringScheme if not explizitly set --- .../domain/test/OfflineSerializationTest.java | 4 ++-- .../sap/sailing/domain/base/RaceColumn.java | 8 ------- .../base/impl/SimpleAbstractRaceColumn.java | 12 ----------- .../domain/leaderboard/ScoringScheme.java | 21 +++++++++++++++++++ ...tHighPointExtremeSailingSeriesOverall.java | 2 +- ...ointFirstGetsFixedOr8AndLastBreaksTie.java | 4 ++-- .../impl/AbstractLeaderboardWithCache.java | 2 +- .../impl/AbstractScoringSchemeImpl.java | 4 ++-- .../impl/AbstractSimpleLeaderboardImpl.java | 6 +++--- .../impl/LowPointFirstToWinTwoRaces.java | 2 +- .../gwt/ui/server/SailingServiceImpl.java | 2 +- .../TestStoringAndRetrievingLeaderboards.java | 6 +++--- .../gateway/impl/rc/RaceGroupFactory.java | 12 ++++++----- .../jaxrs/api/LeaderboardsResource.java | 2 +- .../server/test/MasterDataImportTest.java | 8 +++---- 15 files changed, 49 insertions(+), 46 deletions(-) diff --git a/java/com.sap.sailing.domain.test/src/com/sap/sailing/domain/test/OfflineSerializationTest.java b/java/com.sap.sailing.domain.test/src/com/sap/sailing/domain/test/OfflineSerializationTest.java index c9b8983bc9e..214b0952b15 100755 --- a/java/com.sap.sailing.domain.test/src/com/sap/sailing/domain/test/OfflineSerializationTest.java +++ b/java/com.sap.sailing.domain.test/src/com/sap/sailing/domain/test/OfflineSerializationTest.java @@ -137,8 +137,8 @@ public class OfflineSerializationTest extends AbstractSerializationTest { DomainFactory receiverDomainFactory = new DomainFactoryImpl((srlid)->null); LeaderboardGroup clone = cloneBySerialization(leaderboardGroup, receiverDomainFactory); - assertEquals(FACTOR, overallLeaderboard.getRaceColumnByName("Test Leaderboard").getFactor(), 0.00000001); - assertEquals(FACTOR, clone.getOverallLeaderboard().getRaceColumnByName("Test Leaderboard").getFactor(), 0.00000001); + assertEquals(FACTOR, overallLeaderboard.getScoringScheme().getScoreFactor(overallLeaderboard.getRaceColumnByName("Test Leaderboard")), 0.00000001); + assertEquals(FACTOR, clone.getOverallLeaderboard().getScoringScheme().getScoreFactor(clone.getOverallLeaderboard().getRaceColumnByName("Test Leaderboard")), 0.00000001); } @Test diff --git a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/base/RaceColumn.java b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/base/RaceColumn.java index 8f6c1afbf14..253ab268a12 100644 --- a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/base/RaceColumn.java +++ b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/base/RaceColumn.java @@ -162,14 +162,6 @@ public interface RaceColumn extends Named { */ void releaseTrackedRace(Fleet fleet); - /** - * 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 different - * from 1 or 2. For example, we've seen cases in the Extreme Sailing Series where the race committee defined that in the - * overall series leaderboard the last two columns each count 1.5 times their scores. - */ - double getFactor(); - /** * By default, a competitor's total score is computed by summing up the non-discarded total points of each race * across the leaderboard, considering the {@link RaceColumn#getFactor() column factors}. Some race columns, diff --git a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/base/impl/SimpleAbstractRaceColumn.java b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/base/impl/SimpleAbstractRaceColumn.java index e76b1f77ca8..19966720fd0 100755 --- a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/base/impl/SimpleAbstractRaceColumn.java +++ b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/base/impl/SimpleAbstractRaceColumn.java @@ -20,13 +20,6 @@ public abstract class SimpleAbstractRaceColumn implements RaceColumn { private static final long serialVersionUID = -3590156714385187908L; private final RaceColumnListeners raceColumnListeners; - /** - * The factor by which a medal race score is multiplied by default in the overall point scheme. - * - * @see #getFactor() - */ - private static final double DEFAULT_MEDAL_RACE_FACTOR = 2.0; - /** * If null, the {@link #getFactor() factor} defaults to 1 for non-medal and {@link #DEFAULT_MEDAL_RACE_FACTOR} for * medal races. Otherwise, the explicit factor is used. @@ -66,11 +59,6 @@ public abstract class SimpleAbstractRaceColumn implements RaceColumn { return result; } - @Override - public double getFactor() { - return explicitFactor == null ? (isMedalRace() ? DEFAULT_MEDAL_RACE_FACTOR : 1.) : explicitFactor; - } - @Override public void setFactor(Double factor) { Double oldExplicitFactor = getExplicitFactor(); diff --git a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/ScoringScheme.java b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/ScoringScheme.java index a40e464b828..0c9a4a468ce 100755 --- a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/ScoringScheme.java +++ b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/ScoringScheme.java @@ -25,6 +25,13 @@ import com.sap.sse.common.Util; * */ public interface ScoringScheme extends Serializable { + /** + * The factor by which a medal race score is multiplied by default in the overall point scheme. + * + * @see #getFactor() + */ + static final double DEFAULT_MEDAL_RACE_FACTOR = 2.0; + /** * If this returns true, a higher score is better. For example, the Extreme Sailing Series uses this * scoring scheme, as opposed to the olympic sailing classes which use a low-point system. @@ -131,4 +138,18 @@ public interface ScoringScheme extends Serializable { default boolean doesCountAsWinInMedalRace(Double o1Score, RaceColumn raceColumn) { 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 different + * from 1 or 2. For example, we've seen cases in the Extreme Sailing Series where the race committee defined that in the + * overall series leaderboard the last two columns each count 1.5 times their scores. + */ + default double getScoreFactor(RaceColumn a) { + Double factor = a.getExplicitFactor(); + if(factor == null) { + factor = a.isMedalRace() ? DEFAULT_MEDAL_RACE_FACTOR : 1.0; + } + return factor; + } } diff --git a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/impl/AbstractHighPointExtremeSailingSeriesOverall.java b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/impl/AbstractHighPointExtremeSailingSeriesOverall.java index 36237e81bf8..48d0964a3b9 100644 --- a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/impl/AbstractHighPointExtremeSailingSeriesOverall.java +++ b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/impl/AbstractHighPointExtremeSailingSeriesOverall.java @@ -72,7 +72,7 @@ public abstract class AbstractHighPointExtremeSailingSeriesOverall extends HighP private int getWins(List> scores) { int wins = 0; for (com.sap.sse.common.Util.Pair score : scores) { - if (Math.abs(score.getB() - maxPoints * score.getA().getFactor()) < 0.0000001) { + if (Math.abs(score.getB() - maxPoints * getScoreFactor(score.getA())) < 0.0000001) { wins++; } } diff --git a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/impl/AbstractHighPointFirstGetsFixedOr8AndLastBreaksTie.java b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/impl/AbstractHighPointFirstGetsFixedOr8AndLastBreaksTie.java index ff804e487f6..800f4125459 100644 --- a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/impl/AbstractHighPointFirstGetsFixedOr8AndLastBreaksTie.java +++ b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/impl/AbstractHighPointFirstGetsFixedOr8AndLastBreaksTie.java @@ -46,8 +46,8 @@ public abstract class AbstractHighPointFirstGetsFixedOr8AndLastBreaksTie extends private double getHighestScore(List> scores) { double highestScore = 0; for (com.sap.sse.common.Util.Pair score : scores) { - if ((score.getB() * score.getA().getFactor()) > highestScore) { - highestScore = score.getB() * score.getA().getFactor(); + if ((score.getB() * getScoreFactor(score.getA())) > highestScore) { + highestScore = score.getB() * getScoreFactor(score.getA()); } } return highestScore; diff --git a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/impl/AbstractLeaderboardWithCache.java b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/impl/AbstractLeaderboardWithCache.java index bf8bbf41983..a6a8b82c6d0 100755 --- a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/impl/AbstractLeaderboardWithCache.java +++ b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/impl/AbstractLeaderboardWithCache.java @@ -406,7 +406,7 @@ public abstract class AbstractLeaderboardWithCache implements Leaderboard { } // Note: the RaceColumnDTO won't be created by the following addRace call because it has been created // above by the result.createEmptyRaceColumn call - result.addRace(raceColumn.getName(), raceColumn.getExplicitFactor(), raceColumn.getFactor(), + result.addRace(raceColumn.getName(), raceColumn.getExplicitFactor(), getScoringScheme().getScoreFactor(raceColumn), raceColumn instanceof RaceColumnInSeries ? ((RaceColumnInSeries) raceColumn).getRegatta().getName() : null, raceColumn instanceof RaceColumnInSeries ? ((RaceColumnInSeries) raceColumn).getSeries().getName() : null, fleetDTO, raceColumn.isMedalRace(), raceIdentifier, race, isMetaLeaderboardColumn); diff --git a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/impl/AbstractScoringSchemeImpl.java b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/impl/AbstractScoringSchemeImpl.java index cc53f6ebf81..718fa625fa8 100755 --- a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/impl/AbstractScoringSchemeImpl.java +++ b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/impl/AbstractScoringSchemeImpl.java @@ -129,11 +129,11 @@ public abstract class AbstractScoringSchemeImpl implements ScoringScheme { // needs to compare net points; therefore, divide the total points by the column factor for comparison: List o1NetScores = new ArrayList<>(); for (com.sap.sse.common.Util.Pair o1ColumnAndScore : o1Scores) { - o1NetScores.add(o1ColumnAndScore.getB()/o1ColumnAndScore.getA().getFactor()); + o1NetScores.add(o1ColumnAndScore.getB()/getScoreFactor(o1ColumnAndScore.getA())); } List o2NetScores = new ArrayList<>(); for (com.sap.sse.common.Util.Pair o2ColumnAndScore : o2Scores) { - o2NetScores.add(o2ColumnAndScore.getB()/o2ColumnAndScore.getA().getFactor()); + o2NetScores.add(o2ColumnAndScore.getB()/getScoreFactor(o2ColumnAndScore.getA())); } Collections.sort(o1NetScores, pureScoreComparator); Collections.sort(o2NetScores, pureScoreComparator); diff --git a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/impl/AbstractSimpleLeaderboardImpl.java b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/impl/AbstractSimpleLeaderboardImpl.java index 0a492966fd7..174cee13638 100644 --- a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/impl/AbstractSimpleLeaderboardImpl.java +++ b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/impl/AbstractSimpleLeaderboardImpl.java @@ -475,7 +475,7 @@ public abstract class AbstractSimpleLeaderboardImpl extends AbstractLeaderboardW if (totalPoints == null) { result = null; } else { - result = raceColumn.getFactor() * totalPoints; + result = getScoringScheme().getScoreFactor(raceColumn) * totalPoints; } } return result; @@ -679,7 +679,7 @@ public abstract class AbstractSimpleLeaderboardImpl extends AbstractLeaderboardW return new EntryImpl(trackedRankProvider, correctedScore, () -> correctedResults.getUncorrectedScore(), correctedResults.isCorrected(), discarded ? DOUBLE_0 - : correctedScore == null ? null : Double.valueOf(correctedScore * race.getFactor()), + : correctedScore == null ? null : Double.valueOf(correctedScore * getScoringScheme().getScoreFactor(race)), correctedResults.getMaxPointsReason(), discarded, race.getFleetOfCompetitor(competitor)); } @@ -754,7 +754,7 @@ public abstract class AbstractSimpleLeaderboardImpl extends AbstractLeaderboardW () -> correctedResults.getUncorrectedScore(), correctedResults.isCorrected(), discarded ? DOUBLE_0 : (correctedScore == null ? null - : Double.valueOf((correctedScore * raceColumn.getFactor()))), + : Double.valueOf((correctedScore * getScoringScheme().getScoreFactor(raceColumn)))), correctedResults.getMaxPointsReason(), discarded, raceColumn.getFleetOfCompetitor(competitor)); result.put(new com.sap.sse.common.Util.Pair(competitor, raceColumn), entry); } diff --git a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/impl/LowPointFirstToWinTwoRaces.java b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/impl/LowPointFirstToWinTwoRaces.java index 56ad2c98bb2..ba31de0699c 100644 --- a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/impl/LowPointFirstToWinTwoRaces.java +++ b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/impl/LowPointFirstToWinTwoRaces.java @@ -24,7 +24,7 @@ public class LowPointFirstToWinTwoRaces extends LowPoint { @Override public boolean doesCountAsWinInMedalRace(Double score, RaceColumn raceColumn) { if(score != null) { - double minScore = 1 * raceColumn.getFactor(); + double minScore = 1 * getScoreFactor(raceColumn); return score == minScore; } else { return false; diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/server/SailingServiceImpl.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/server/SailingServiceImpl.java index ab22cfb7f1e..0d0d0842737 100755 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/server/SailingServiceImpl.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/server/SailingServiceImpl.java @@ -2602,7 +2602,7 @@ public class SailingServiceImpl extends ProxiedRemoteServiceServlet implements S } } final FleetDTO fleetDTO = baseDomainFactory.convertToFleetDTO(fleet); - RaceColumnDTO raceColumnDTO = leaderboardDTO.addRace(raceColumn.getName(), raceColumn.getExplicitFactor(), raceColumn.getFactor(), + RaceColumnDTO raceColumnDTO = leaderboardDTO.addRace(raceColumn.getName(), raceColumn.getExplicitFactor(), leaderboard.getScoringScheme().getScoreFactor(raceColumn), raceColumn instanceof RaceColumnInSeries ? ((RaceColumnInSeries) raceColumn).getRegatta().getName() : null, raceColumn instanceof RaceColumnInSeries ? ((RaceColumnInSeries) raceColumn).getSeries().getName() : null, fleetDTO, raceColumn.isMedalRace(), raceIdentifier, raceDTO, raceColumn instanceof MetaLeaderboardColumn); diff --git a/java/com.sap.sailing.mongodb.test/src/com/sap/sailing/mongodb/test/TestStoringAndRetrievingLeaderboards.java b/java/com.sap.sailing.mongodb.test/src/com/sap/sailing/mongodb/test/TestStoringAndRetrievingLeaderboards.java index 6e568a81c19..640f9d915f8 100755 --- a/java/com.sap.sailing.mongodb.test/src/com/sap/sailing/mongodb/test/TestStoringAndRetrievingLeaderboards.java +++ b/java/com.sap.sailing.mongodb.test/src/com/sap/sailing/mongodb/test/TestStoringAndRetrievingLeaderboards.java @@ -68,9 +68,9 @@ public class TestStoringAndRetrievingLeaderboards extends AbstractMongoDBTest { r3.setFactor(2.5); new MongoObjectFactoryImpl(db).storeLeaderboard(leaderboard); Leaderboard loadedLeaderboard = new DomainObjectFactoryImpl(db, DomainFactory.INSTANCE).loadLeaderboard(leaderboardName, /* regattaRegistry */ null, /* leaderboardRegistry */ null); - assertEquals(1.0, loadedLeaderboard.getRaceColumnByName("R1").getFactor(), 0.000000001); - assertEquals(1.5, loadedLeaderboard.getRaceColumnByName("R2").getFactor(), 0.000000001); - assertEquals(2.5, loadedLeaderboard.getRaceColumnByName("R3").getFactor(), 0.000000001); + assertEquals(1.0, loadedLeaderboard.getScoringScheme().getScoreFactor(loadedLeaderboard.getRaceColumnByName("R1")), 0.000000001); + assertEquals(1.5, loadedLeaderboard.getScoringScheme().getScoreFactor(loadedLeaderboard.getRaceColumnByName("R2")), 0.000000001); + assertEquals(2.5, loadedLeaderboard.getScoringScheme().getScoreFactor(loadedLeaderboard.getRaceColumnByName("R3")), 0.000000001); } @Test diff --git a/java/com.sap.sailing.server.gateway/src/com/sap/sailing/server/gateway/impl/rc/RaceGroupFactory.java b/java/com.sap.sailing.server.gateway/src/com/sap/sailing/server/gateway/impl/rc/RaceGroupFactory.java index 5909486602d..e020041083e 100644 --- a/java/com.sap.sailing.server.gateway/src/com/sap/sailing/server/gateway/impl/rc/RaceGroupFactory.java +++ b/java/com.sap.sailing.server.gateway/src/com/sap/sailing/server/gateway/impl/rc/RaceGroupFactory.java @@ -31,6 +31,7 @@ import com.sap.sailing.domain.common.TargetTimeInfo; import com.sap.sailing.domain.leaderboard.FlexibleLeaderboard; import com.sap.sailing.domain.leaderboard.Leaderboard; import com.sap.sailing.domain.leaderboard.RegattaLeaderboard; +import com.sap.sailing.domain.leaderboard.ScoringScheme; import com.sap.sailing.domain.polars.NotEnoughDataHasBeenAddedException; import com.sap.sailing.domain.tracking.TrackedRace; import com.sap.sse.common.TimePoint; @@ -75,7 +76,7 @@ public class RaceGroupFactory { Collection seriesWithRows = new ArrayList<>(); for (Series series : getSeriesIterable(leaderboard, seriesToRaceColumns)) { seriesWithRows.add(new SeriesWithRowsImpl(series.getName(), series.isMedal(), series.isFleetsCanRunInParallel(), getRows(series, - seriesToRaceColumns.get(series)))); + seriesToRaceColumns.get(series), leaderboard.getScoringScheme()))); } return seriesWithRows; } @@ -90,13 +91,14 @@ public class RaceGroupFactory { /** * @param raceColumns must be provided in the same order in which they appear in the series / leaderboard + * @param scoringScheme */ - private Collection getRows(Series series, List raceColumns) { + private Collection getRows(Series series, List raceColumns, ScoringScheme scoringScheme) { Collection rows = new ArrayList<>(); for (Fleet fleet : series.getFleets()) { // We are taking the fleet name because there might be several "default fleet" // objects when TrackedRaces are linked onto this Leaderboard - rows.add(new RaceRowImpl(fleet, getCells(fleet.getName(), raceColumns, isFirstRaceColumnVirtual(series)))); + rows.add(new RaceRowImpl(fleet, getCells(fleet.getName(), raceColumns, isFirstRaceColumnVirtual(series), scoringScheme))); } return rows; } @@ -111,7 +113,7 @@ public class RaceGroupFactory { * {@link TrackedRace#getEstimatedTimeToComplete(TimePoint) estimation} for the current point in time, when the * request is being made, using this time point to determine the wind speed and direction for each leg. */ - private List getCells(String fleetName, List raceColumns, boolean isFirstRaceColumnVirtual) { + private List getCells(String fleetName, List raceColumns, boolean isFirstRaceColumnVirtual, ScoringScheme scoringScheme) { boolean skippedFirst = false; List cells = new ArrayList<>(); if (raceColumns != null) { @@ -131,7 +133,7 @@ public class RaceGroupFactory { targetTime = null; } cells.add(new RaceCellImpl(raceColumn.getName(), raceColumn.getRaceLog(fleet), - raceColumn.getFactor(), raceColumn.getExplicitFactor(), zeroBasedIndexOfRaceInFleet++, targetTime)); + scoringScheme.getScoreFactor(raceColumn), raceColumn.getExplicitFactor(), zeroBasedIndexOfRaceInFleet++, targetTime)); } } } diff --git a/java/com.sap.sailing.server.gateway/src/com/sap/sailing/server/gateway/jaxrs/api/LeaderboardsResource.java b/java/com.sap.sailing.server.gateway/src/com/sap/sailing/server/gateway/jaxrs/api/LeaderboardsResource.java index 8c87df63b6f..e6fee705739 100644 --- a/java/com.sap.sailing.server.gateway/src/com/sap/sailing/server/gateway/jaxrs/api/LeaderboardsResource.java +++ b/java/com.sap.sailing.server.gateway/src/com/sap/sailing/server/gateway/jaxrs/api/LeaderboardsResource.java @@ -1200,7 +1200,7 @@ public class LeaderboardsResource extends AbstractLeaderboardsResource { raceColumnsAsJson.add(raceColumnAsJson); raceColumnAsJson.put(RaceColumnConstants.RACE_COLUMN_NAME, rc.getName()); raceColumnAsJson.put(RaceColumnConstants.EXPLICIT_FACTOR, rc.getExplicitFactor()); - raceColumnAsJson.put(RaceColumnConstants.FACTOR, rc.getFactor()); + raceColumnAsJson.put(RaceColumnConstants.FACTOR, leaderboard.getScoringScheme().getScoreFactor(rc)); } return json; } diff --git a/java/com.sap.sailing.server.test/src/com/sap/sailing/server/test/MasterDataImportTest.java b/java/com.sap.sailing.server.test/src/com/sap/sailing/server/test/MasterDataImportTest.java index eb84a8de7ab..ca21256b360 100644 --- a/java/com.sap.sailing.server.test/src/com/sap/sailing/server/test/MasterDataImportTest.java +++ b/java/com.sap.sailing.server.test/src/com/sap/sailing/server/test/MasterDataImportTest.java @@ -411,7 +411,7 @@ public class MasterDataImportTest { raceColumnOnTarget.setTrackedRace(fleet1OnTarget, trackedRaceForTarget); - Assert.assertEquals(factor, raceColumnOnTarget.getFactor()); + Assert.assertEquals(factor, leaderboard.getScoringScheme().getScoreFactor(raceColumnOnTarget)); Iterable competitorsOnTarget = leaderboardOnTarget.getAllCompetitors(); Iterator competitorIterator = competitorsOnTarget.iterator(); @@ -2093,7 +2093,7 @@ public class MasterDataImportTest { RaceColumn metaColumn = metaColumns.iterator().next(); Assert.assertNotNull(metaColumn); - Assert.assertEquals(factor, metaColumn.getFactor()); + Assert.assertEquals(factor, overallLeaderboard.getScoringScheme().getScoreFactor(metaColumn)); // Verify that overall leaderboard data has been persisted RacingEventService persistenceVerifier = new RacingEventServiceImplMock(){}; @@ -2115,7 +2115,7 @@ public class MasterDataImportTest { metaColumn = metaColumns.iterator().next(); Assert.assertNotNull(metaColumn); - Assert.assertEquals(factor, metaColumn.getFactor()); + Assert.assertEquals(factor, overallLeaderboard.getScoringScheme().getScoreFactor(metaColumn)); } @@ -2289,7 +2289,7 @@ public class MasterDataImportTest { raceColumnOnTarget.setTrackedRace(defaultFleetOnTarget, trackedRaceForTarget); - Assert.assertEquals(factor, raceColumnOnTarget.getFactor()); + Assert.assertEquals(factor, leaderboardOnTarget.getScoringScheme().getScoreFactor(raceColumnOnTarget)); // Check for score corrections Assert.assertEquals( From bab1ad94c126569636644e55e1d7e9f8030baa8b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kai=20B=C3=B6rnert?= Date: Fri, 13 Jul 2018 14:50:51 +0200 Subject: [PATCH 03/43] bug4661 do not double score for medal races with this scoringscheme --- .../leaderboard/impl/LowPointFirstToWinTwoRaces.java | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/impl/LowPointFirstToWinTwoRaces.java b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/impl/LowPointFirstToWinTwoRaces.java index ba31de0699c..1dac8f0f106 100644 --- a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/impl/LowPointFirstToWinTwoRaces.java +++ b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/impl/LowPointFirstToWinTwoRaces.java @@ -31,4 +31,13 @@ public class LowPointFirstToWinTwoRaces extends LowPoint { } } + @Override + public double getScoreFactor(RaceColumn a) { + Double factor = a.getExplicitFactor(); + if(factor == null) { + factor = 1.0; + } + return factor; + } + } From 0b025d3debbcd11d53dbf26c5fbd27d4087f11f2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kai=20B=C3=B6rnert?= Date: Mon, 16 Jul 2018 09:55:06 +0200 Subject: [PATCH 04/43] bug4661 ensure won races are only counted for medal races --- .../impl/AbstractSimpleLeaderboardImpl.java | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/impl/AbstractSimpleLeaderboardImpl.java b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/impl/AbstractSimpleLeaderboardImpl.java index 174cee13638..5012635f55c 100644 --- a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/impl/AbstractSimpleLeaderboardImpl.java +++ b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/impl/AbstractSimpleLeaderboardImpl.java @@ -493,7 +493,7 @@ public abstract class AbstractSimpleLeaderboardImpl extends AbstractLeaderboardW // from there on boolean needToResetScoreUponNextNonEmptyEntry = false; double result = getCarriedPoints(competitor); - double wonRaces = 0; + int wonRaces = 0; final Set discardedRaceColumns = getResultDiscardingRule().getDiscardedRaceColumns(competitor, this, raceColumnsToConsider, timePoint); for (RaceColumn raceColumn : raceColumnsToConsider) { @@ -502,12 +502,13 @@ public abstract class AbstractSimpleLeaderboardImpl extends AbstractLeaderboardW } if (getScoringScheme().isValidInNetScore(this, raceColumn, competitor, timePoint)) { final Double netPoints = getNetPoints(competitor, raceColumn, timePoint, discardedRaceColumns); - if(getScoringScheme().isMedalWinAmountCriteria()) { + if (getScoringScheme().isMedalWinAmountCriteria() && raceColumn.isMedalRace()) { wonRaces += getScoringScheme().doesCountAsWinInMedalRace(netPoints, raceColumn) ? 1 : 0; } - if(true){ - System.out.println("Check " + competitor.getName() + " " + raceColumn.getName() + " " + netPoints + " " + wonRaces); - }else { + if (true) { + System.out.println("Check " + competitor.getName() + " " + raceColumn.getName() + " " + netPoints + + " " + wonRaces); + } else { System.out.println("remove stuff"); } if (netPoints != null) { @@ -521,8 +522,8 @@ public abstract class AbstractSimpleLeaderboardImpl extends AbstractLeaderboardW } } } - if(getScoringScheme().isMedalWinAmountCriteria()) { - if(wonRaces == getScoringScheme().getTargetAmountOfMedalRaceWins()) { + if (getScoringScheme().isMedalWinAmountCriteria()) { + if (wonRaces == getScoringScheme().getTargetAmountOfMedalRaceWins()) { return 2.0; } } From 52a1ba9953b3ba2cc7e09815bbaf366cbb13edaf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kai=20B=C3=B6rnert?= Date: Mon, 16 Jul 2018 15:56:22 +0200 Subject: [PATCH 05/43] bug4661 ensure that 0 carry is also interpeted as a win --- .../domain/leaderboard/impl/LowPointFirstToWinTwoRaces.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/impl/LowPointFirstToWinTwoRaces.java b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/impl/LowPointFirstToWinTwoRaces.java index 1dac8f0f106..56138b13d0f 100644 --- a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/impl/LowPointFirstToWinTwoRaces.java +++ b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/impl/LowPointFirstToWinTwoRaces.java @@ -25,7 +25,7 @@ public class LowPointFirstToWinTwoRaces extends LowPoint { public boolean doesCountAsWinInMedalRace(Double score, RaceColumn raceColumn) { if(score != null) { double minScore = 1 * getScoreFactor(raceColumn); - return score == minScore; + return score == minScore || score == 0.0; } else { return false; } From 0b560b71f64ad68556c4e918e6490e4abd295cfd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kai=20B=C3=B6rnert?= Date: Mon, 16 Jul 2018 15:57:01 +0200 Subject: [PATCH 06/43] bug4661 fix for reset next score cleaning carry races --- .../impl/AbstractSimpleLeaderboardImpl.java | 13 +++---------- 1 file changed, 3 insertions(+), 10 deletions(-) diff --git a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/impl/AbstractSimpleLeaderboardImpl.java b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/impl/AbstractSimpleLeaderboardImpl.java index 5012635f55c..9fa4963779f 100644 --- a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/impl/AbstractSimpleLeaderboardImpl.java +++ b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/impl/AbstractSimpleLeaderboardImpl.java @@ -502,23 +502,16 @@ public abstract class AbstractSimpleLeaderboardImpl extends AbstractLeaderboardW } if (getScoringScheme().isValidInNetScore(this, raceColumn, competitor, timePoint)) { final Double netPoints = getNetPoints(competitor, raceColumn, timePoint, discardedRaceColumns); - if (getScoringScheme().isMedalWinAmountCriteria() && raceColumn.isMedalRace()) { - wonRaces += getScoringScheme().doesCountAsWinInMedalRace(netPoints, raceColumn) ? 1 : 0; - } - if (true) { - System.out.println("Check " + competitor.getName() + " " + raceColumn.getName() + " " + netPoints - + " " + wonRaces); - } else { - System.out.println("remove stuff"); - } if (netPoints != null) { if (needToResetScoreUponNextNonEmptyEntry) { result = 0; - //FIXME if medal amount, use carry column here instead of 0? wonRaces = 0; needToResetScoreUponNextNonEmptyEntry = false; } result += netPoints; + if (getScoringScheme().isMedalWinAmountCriteria() && raceColumn.isMedalRace()) { + wonRaces += getScoringScheme().doesCountAsWinInMedalRace(netPoints, raceColumn) ? 1 : 0; + } } } } From daeb320892c1929b9e57a53ffe94869de2f86e2e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kai=20B=C3=B6rnert?= Date: Mon, 16 Jul 2018 15:57:39 +0200 Subject: [PATCH 07/43] bug4661 initial tests --- ...oardScoringAndRankingTestForLowPoints.java | 718 ++++++++++++++++++ 1 file changed, 718 insertions(+) create mode 100644 java/com.sap.sailing.domain.test/src/com/sap/sailing/domain/test/LeaderboardScoringAndRankingTestForLowPoints.java diff --git a/java/com.sap.sailing.domain.test/src/com/sap/sailing/domain/test/LeaderboardScoringAndRankingTestForLowPoints.java b/java/com.sap.sailing.domain.test/src/com/sap/sailing/domain/test/LeaderboardScoringAndRankingTestForLowPoints.java new file mode 100644 index 00000000000..089f66af567 --- /dev/null +++ b/java/com.sap.sailing.domain.test/src/com/sap/sailing/domain/test/LeaderboardScoringAndRankingTestForLowPoints.java @@ -0,0 +1,718 @@ +package com.sap.sailing.domain.test; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.Set; + +import org.junit.Test; + +import com.sap.sailing.domain.base.BoatClass; +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.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.NoWindException; +import com.sap.sailing.domain.common.ScoringSchemeType; +import com.sap.sailing.domain.leaderboard.Leaderboard; +import com.sap.sailing.domain.leaderboard.impl.DelegatingRegattaLeaderboardWithCompetitorElimination; +import com.sap.sailing.domain.leaderboard.impl.ThresholdBasedResultDiscardingRuleImpl; +import com.sap.sailing.domain.ranking.OneDesignRankingMetric; +import com.sap.sailing.domain.test.mock.MockedTrackedRaceWithStartTimeAndRanks; +import com.sap.sailing.domain.tracking.TrackedRace; +import com.sap.sse.common.TimePoint; +import com.sap.sse.common.impl.MillisecondsTimePoint; + +import junit.framework.Assert; + +public class LeaderboardScoringAndRankingTestForLowPoints extends LeaderboardScoringAndRankingTestBase { + private static final double EPSILON = 0.000001; + + protected DelegatingRegattaLeaderboardWithCompetitorElimination createDelegatingRegattaLeaderboardWithCompetitorElimination( + Regatta regatta, String leaderboardName, int[] discardingThresholds) { + return new DelegatingRegattaLeaderboardWithCompetitorElimination( + () -> createLeaderboard(regatta, discardingThresholds), leaderboardName); + } + + private void executeRandomPreSeries(List yellow, List blue, TimePoint now) { + RaceColumn qColumn = series.get(0).getRaceColumnByName("Q"); + TrackedRace qYellow = new MockedTrackedRaceWithStartTimeAndRanks(now, yellow); + qColumn.setTrackedRace(qColumn.getFleetByName("Yellow"), qYellow); + TrackedRace qBlue = new MockedTrackedRaceWithStartTimeAndRanks(now, blue); + qColumn.setTrackedRace(qColumn.getFleetByName("Blue"), qBlue); + } + + private void manuallyTransferCarry(Leaderboard leaderboard, List medalCompetitors) { + double carryScore = 0; + for (Competitor medalCompetitor : medalCompetitors) { + leaderboard.getScoreCorrection().correctScore(medalCompetitor, leaderboard.getRaceColumnByName("Carry"), + carryScore); + carryScore += 0.0001; + } + } + + private Regatta setupRegatta(boolean useFirstTwoWins) { + final BoatClass boatClass = DomainFactory.INSTANCE.getOrCreateBoatClass("470", + /* typicallyStartsUpwind */ true); + Regatta regatta = new RegattaImpl(RegattaImpl.getDefaultName("Test Regatta", boatClass.getName()), boatClass, + /* canBoatsOfCompetitorsChangePerRace */ true, /* startDate */ null, /* endDate */ null, series, + /* persistent */false, + DomainFactory.INSTANCE + .createScoringScheme(useFirstTwoWins ? ScoringSchemeType.LOW_POINT_FIRST_TO_WIN_TWO_RACES + : ScoringSchemeType.LOW_POINT), + "123", /* course area */null, OneDesignRankingMetric::new); + return regatta; + } + + private void setupMedalSeries() { + // -------- medal series ------------ + { + Set medalFleets = Collections.singleton(new FleetImpl("Default")); + List medalRaceColumnNames = new ArrayList(); + medalRaceColumnNames.add("Carry"); + medalRaceColumnNames.add("M1"); + medalRaceColumnNames.add("M2"); + medalRaceColumnNames.add("M3"); + medalRaceColumnNames.add("M4"); + Series medalSeries = new SeriesImpl("Medal", /* isMedal */true, /* isFleetsCanRunInParallel */ true, + medalFleets, medalRaceColumnNames, /* trackedRegattaRegistry */ null); + series.add(medalSeries); + } + } + + private void setupPreSeries() { + { + List qualificationFleets = new ArrayList(); + for (String qualificationFleetName : new String[] { "Yellow", "Blue" }) { + qualificationFleets.add(new FleetImpl(qualificationFleetName)); + } + List qualificationRaceColumnNames = new ArrayList(); + qualificationRaceColumnNames.add("Q"); + Series qualificationSeries = new SeriesImpl("Qualification", /* isMedal */false, + /* isFleetsCanRunInParallel */ true, qualificationFleets, qualificationRaceColumnNames, + /* trackedRegattaRegistry */ null); + // discard the one and only qualification race; it doesn't score + qualificationSeries.setResultDiscardingRule(new ThresholdBasedResultDiscardingRuleImpl(new int[] { 1 })); + series.add(qualificationSeries); + } + } + + @Test + public void testFirstPreseriesWinsAgain() throws NoWindException { + series = new ArrayList(); + setupPreSeries(); + + setupMedalSeries(); + Regatta regatta = setupRegatta(true); + List competitors = createCompetitors(12); + List yellow = new ArrayList<>(competitors.subList(0, 6)); + List blue = new ArrayList<>(competitors); + blue.removeAll(yellow); + Collections.shuffle(yellow); + Collections.shuffle(blue); + + Leaderboard leaderboard = createLeaderboard(regatta, /* discarding thresholds */ new int[0]); + TimePoint now = MillisecondsTimePoint.now(); + TimePoint later = new MillisecondsTimePoint(now.asMillis() + 1000); + executeRandomPreSeries(yellow, blue, now); + + List bestQualifing = leaderboard.getCompetitorsFromBestToWorst(later); + List medalCompetitors = bestQualifing.subList(0, 4); + + manuallyTransferCarry(leaderboard, medalCompetitors); + + Competitor preFirst = medalCompetitors.get(0); + Competitor preSecond = medalCompetitors.get(1); + Competitor preThird = medalCompetitors.get(2); + Competitor preFourth = medalCompetitors.get(3); + + RaceColumn m1 = leaderboard.getRaceColumnByName("M1"); + + ArrayList m1Results = new ArrayList<>(); + m1Results.add(preFirst); + m1Results.add(preSecond); + m1Results.add(preThird); + m1Results.add(preFourth); + + TrackedRace mDefault = new MockedTrackedRaceWithStartTimeAndRanks(now, m1Results); + m1.setTrackedRace(m1.getFleetByName("Default"), mDefault); + + Assert.assertEquals(2.0, leaderboard.getNetPoints(medalCompetitors.get(0), later), EPSILON); + Assert.assertEquals(2.0001, leaderboard.getNetPoints(medalCompetitors.get(1), later), EPSILON); + Assert.assertEquals(3.0002, leaderboard.getNetPoints(medalCompetitors.get(2), later), EPSILON); + Assert.assertEquals(4.0003, leaderboard.getNetPoints(medalCompetitors.get(3), later), EPSILON); + } + + @Test + public void testSecondPreSeriesWinsTwice() throws NoWindException { + series = new ArrayList(); + // -------- qualification series ------------ + setupPreSeries(); + setupMedalSeries(); + Regatta regatta = setupRegatta(true); + List competitors = createCompetitors(12); + List yellow = new ArrayList<>(competitors.subList(0, 6)); + List blue = new ArrayList<>(competitors); + blue.removeAll(yellow); + Collections.shuffle(yellow); + Collections.shuffle(blue); + + Leaderboard leaderboard = createLeaderboard(regatta, /* discarding thresholds */ new int[0]); + TimePoint now = MillisecondsTimePoint.now(); + TimePoint later = new MillisecondsTimePoint(now.asMillis() + 1000); + executeRandomPreSeries(yellow, blue, now); + + List medalCompetitorsBestToWorst = leaderboard.getCompetitorsFromBestToWorst(later).subList(0, 4); + manuallyTransferCarry(leaderboard, medalCompetitorsBestToWorst); + + Competitor preFirst = medalCompetitorsBestToWorst.get(0); + Competitor preSecond = medalCompetitorsBestToWorst.get(1); + Competitor preThird = medalCompetitorsBestToWorst.get(2); + Competitor preFourth = medalCompetitorsBestToWorst.get(3); + + RaceColumn m1 = leaderboard.getRaceColumnByName("M1"); + + ArrayList m1Results = new ArrayList<>(); + m1Results.add(preSecond); + m1Results.add(preFirst); + m1Results.add(preThird); + m1Results.add(preFourth); + + TimePoint m1now = new MillisecondsTimePoint(later.asMillis() + 1000); + TimePoint m1later = new MillisecondsTimePoint(m1now.asMillis() + 1000); + + TrackedRace m1Default = new MockedTrackedRaceWithStartTimeAndRanks(now, m1Results); + m1.setTrackedRace(m1.getFleetByName("Default"), m1Default); + + Assert.assertEquals(1.0001, leaderboard.getNetPoints(preSecond, later), EPSILON); + Assert.assertEquals(2.0, leaderboard.getNetPoints(preFirst, later), EPSILON); + Assert.assertEquals(3.0002, leaderboard.getNetPoints(preThird, later), EPSILON); + Assert.assertEquals(4.0003, leaderboard.getNetPoints(preFourth, later), EPSILON); + + RaceColumn m2 = leaderboard.getRaceColumnByName("M2"); + + ArrayList m2Results = new ArrayList<>(); + m2Results.add(preSecond); + m2Results.add(preFirst); + m2Results.add(preThird); + m2Results.add(preFourth); + + TimePoint m2now = new MillisecondsTimePoint(m1later.asMillis() + 1000); + TimePoint m2later = new MillisecondsTimePoint(m2now.asMillis() + 1000); + TrackedRace m2Default = new MockedTrackedRaceWithStartTimeAndRanks(m2now, m2Results); + m2.setTrackedRace(m1.getFleetByName("Default"), m2Default); + + Assert.assertEquals(2.0, leaderboard.getNetPoints(preSecond, m2later), EPSILON); + Assert.assertEquals(4.0, leaderboard.getNetPoints(preFirst, m2later), EPSILON); + Assert.assertEquals(6.0002, leaderboard.getNetPoints(preThird, m2later), EPSILON); + Assert.assertEquals(8.0003, leaderboard.getNetPoints(preFourth, m2later), EPSILON); + } + + @Test + public void testFirstWinsSecondRace() throws NoWindException { + series = new ArrayList(); + // -------- qualification series ------------ + setupPreSeries(); + setupMedalSeries(); + Regatta regatta = setupRegatta(true); + List competitors = createCompetitors(12); + List yellow = new ArrayList<>(competitors.subList(0, 6)); + List blue = new ArrayList<>(competitors); + blue.removeAll(yellow); + Collections.shuffle(yellow); + Collections.shuffle(blue); + + Leaderboard leaderboard = createLeaderboard(regatta, /* discarding thresholds */ new int[0]); + TimePoint now = MillisecondsTimePoint.now(); + TimePoint later = new MillisecondsTimePoint(now.asMillis() + 1000); + executeRandomPreSeries(yellow, blue, now); + + List medalCompetitorsBestToWorst = leaderboard.getCompetitorsFromBestToWorst(later).subList(0, 4); + manuallyTransferCarry(leaderboard, medalCompetitorsBestToWorst); + + Competitor preFirst = medalCompetitorsBestToWorst.get(0); + Competitor preSecond = medalCompetitorsBestToWorst.get(1); + Competitor preThird = medalCompetitorsBestToWorst.get(2); + Competitor preFourth = medalCompetitorsBestToWorst.get(3); + + RaceColumn m1 = leaderboard.getRaceColumnByName("M1"); + + ArrayList m1Results = new ArrayList<>(); + m1Results.add(preSecond); + m1Results.add(preFirst); + m1Results.add(preThird); + m1Results.add(preFourth); + + TimePoint m1now = new MillisecondsTimePoint(later.asMillis() + 1000); + TimePoint m1later = new MillisecondsTimePoint(m1now.asMillis() + 1000); + + TrackedRace m1Default = new MockedTrackedRaceWithStartTimeAndRanks(now, m1Results); + m1.setTrackedRace(m1.getFleetByName("Default"), m1Default); + + Assert.assertEquals(1.0001, leaderboard.getNetPoints(preSecond, later), EPSILON); + Assert.assertEquals(2.0, leaderboard.getNetPoints(preFirst, later), EPSILON); + Assert.assertEquals(3.0002, leaderboard.getNetPoints(preThird, later), EPSILON); + Assert.assertEquals(4.0003, leaderboard.getNetPoints(preFourth, later), EPSILON); + + RaceColumn m2 = leaderboard.getRaceColumnByName("M2"); + + ArrayList m2Results = new ArrayList<>(); + m2Results.add(preFirst); + m2Results.add(preSecond); + m2Results.add(preThird); + m2Results.add(preFourth); + + TimePoint m2now = new MillisecondsTimePoint(m1later.asMillis() + 1000); + TimePoint m2later = new MillisecondsTimePoint(m2now.asMillis() + 1000); + TrackedRace m2Default = new MockedTrackedRaceWithStartTimeAndRanks(m2now, m2Results); + m2.setTrackedRace(m1.getFleetByName("Default"), m2Default); + + Assert.assertEquals(2.0, leaderboard.getNetPoints(preFirst, m2later), EPSILON); + Assert.assertEquals(3.0001, leaderboard.getNetPoints(preSecond, m2later), EPSILON); + Assert.assertEquals(6.0002, leaderboard.getNetPoints(preThird, m2later), EPSILON); + Assert.assertEquals(8.0003, leaderboard.getNetPoints(preFourth, m2later), EPSILON); + } + + @Test + public void testLastWinsTwoRaces() throws NoWindException { + series = new ArrayList(); + // -------- qualification series ------------ + setupPreSeries(); + setupMedalSeries(); + Regatta regatta = setupRegatta(true); + List competitors = createCompetitors(12); + List yellow = new ArrayList<>(competitors.subList(0, 6)); + List blue = new ArrayList<>(competitors); + blue.removeAll(yellow); + Collections.shuffle(yellow); + Collections.shuffle(blue); + + Leaderboard leaderboard = createLeaderboard(regatta, /* discarding thresholds */ new int[0]); + TimePoint now = MillisecondsTimePoint.now(); + TimePoint later = new MillisecondsTimePoint(now.asMillis() + 1000); + executeRandomPreSeries(yellow, blue, now); + + List medalCompetitorsBestToWorst = leaderboard.getCompetitorsFromBestToWorst(later).subList(0, 4); + manuallyTransferCarry(leaderboard, medalCompetitorsBestToWorst); + + Competitor preFirst = medalCompetitorsBestToWorst.get(0); + Competitor preSecond = medalCompetitorsBestToWorst.get(1); + Competitor preThird = medalCompetitorsBestToWorst.get(2); + Competitor preFourth = medalCompetitorsBestToWorst.get(3); + + RaceColumn m1 = leaderboard.getRaceColumnByName("M1"); + + ArrayList m1Results = new ArrayList<>(); + m1Results.add(preFourth); + m1Results.add(preFirst); + m1Results.add(preSecond); + m1Results.add(preThird); + + TimePoint m1now = new MillisecondsTimePoint(later.asMillis() + 1000); + TimePoint m1later = new MillisecondsTimePoint(m1now.asMillis() + 1000); + + TrackedRace m1Default = new MockedTrackedRaceWithStartTimeAndRanks(now, m1Results); + m1.setTrackedRace(m1.getFleetByName("Default"), m1Default); + + Assert.assertEquals(1.0003, leaderboard.getNetPoints(preFourth, later), EPSILON); + Assert.assertEquals(2.0, leaderboard.getNetPoints(preFirst, later), EPSILON); + Assert.assertEquals(3.0001, leaderboard.getNetPoints(preSecond, later), EPSILON); + Assert.assertEquals(4.0002, leaderboard.getNetPoints(preThird, later), EPSILON); + + RaceColumn m2 = leaderboard.getRaceColumnByName("M2"); + + ArrayList m2Results = new ArrayList<>(); + m2Results.add(preFourth); + m2Results.add(preFirst); + m2Results.add(preSecond); + m2Results.add(preThird); + + TimePoint m2now = new MillisecondsTimePoint(m1later.asMillis() + 1000); + TimePoint m2later = new MillisecondsTimePoint(m2now.asMillis() + 1000); + TrackedRace m2Default = new MockedTrackedRaceWithStartTimeAndRanks(m2now, m2Results); + m2.setTrackedRace(m1.getFleetByName("Default"), m2Default); + + Assert.assertEquals(2.0, leaderboard.getNetPoints(preFourth, m2later), EPSILON); + Assert.assertEquals(4.0, leaderboard.getNetPoints(preFirst, m2later), EPSILON); + Assert.assertEquals(6.0001, leaderboard.getNetPoints(preSecond, m2later), EPSILON); + Assert.assertEquals(8.0002, leaderboard.getNetPoints(preThird, m2later), EPSILON); + } + + @Test + public void noTwoWinsAbortAfterTwoRacesAndTieBraker() throws NoWindException { + series = new ArrayList(); + // -------- qualification series ------------ + setupPreSeries(); + setupMedalSeries(); + Regatta regatta = setupRegatta(true); + List competitors = createCompetitors(12); + List yellow = new ArrayList<>(competitors.subList(0, 6)); + List blue = new ArrayList<>(competitors); + blue.removeAll(yellow); + Collections.shuffle(yellow); + Collections.shuffle(blue); + + Leaderboard leaderboard = createLeaderboard(regatta, /* discarding thresholds */ new int[0]); + TimePoint now = MillisecondsTimePoint.now(); + TimePoint later = new MillisecondsTimePoint(now.asMillis() + 1000); + executeRandomPreSeries(yellow, blue, now); + + List medalCompetitorsBestToWorst = leaderboard.getCompetitorsFromBestToWorst(later).subList(0, 4); + manuallyTransferCarry(leaderboard, medalCompetitorsBestToWorst); + + Competitor preFirst = medalCompetitorsBestToWorst.get(0); + Competitor preSecond = medalCompetitorsBestToWorst.get(1); + Competitor preThird = medalCompetitorsBestToWorst.get(2); + Competitor preFourth = medalCompetitorsBestToWorst.get(3); + + RaceColumn m1 = leaderboard.getRaceColumnByName("M1"); + + ArrayList m1Results = new ArrayList<>(); + m1Results.add(preFourth); + m1Results.add(preFirst); + m1Results.add(preSecond); + m1Results.add(preThird); + + TimePoint m1now = new MillisecondsTimePoint(later.asMillis() + 1000); + TimePoint m1later = new MillisecondsTimePoint(m1now.asMillis() + 1000); + + TrackedRace m1Default = new MockedTrackedRaceWithStartTimeAndRanks(now, m1Results); + m1.setTrackedRace(m1.getFleetByName("Default"), m1Default); + + Assert.assertEquals(1.0003, leaderboard.getNetPoints(preFourth, later), EPSILON); + Assert.assertEquals(2.0, leaderboard.getNetPoints(preFirst, later), EPSILON); + Assert.assertEquals(3.0001, leaderboard.getNetPoints(preSecond, later), EPSILON); + Assert.assertEquals(4.0002, leaderboard.getNetPoints(preThird, later), EPSILON); + + RaceColumn m2 = leaderboard.getRaceColumnByName("M2"); + + ArrayList m2Results = new ArrayList<>(); + m2Results.add(preThird); + m2Results.add(preFirst); + m2Results.add(preSecond); + m2Results.add(preFourth); + + TimePoint m2now = new MillisecondsTimePoint(m1later.asMillis() + 1000); + TimePoint m2later = new MillisecondsTimePoint(m2now.asMillis() + 1000); + TrackedRace m2Default = new MockedTrackedRaceWithStartTimeAndRanks(m2now, m2Results); + m2.setTrackedRace(m1.getFleetByName("Default"), m2Default); + + Assert.assertEquals(5.0003, leaderboard.getNetPoints(preFourth, m2later), EPSILON); + Assert.assertEquals(4.0, leaderboard.getNetPoints(preFirst, m2later), EPSILON); + Assert.assertEquals(6.0001, leaderboard.getNetPoints(preSecond, m2later), EPSILON); + Assert.assertEquals(5.0002, leaderboard.getNetPoints(preThird, m2later), EPSILON); + } + + + @Test + public void negativeTestFirstPreseriesWinsAgain() throws NoWindException { + series = new ArrayList(); + setupPreSeries(); + + setupMedalSeries(); + Regatta regatta = setupRegatta(false); + List competitors = createCompetitors(12); + List yellow = new ArrayList<>(competitors.subList(0, 6)); + List blue = new ArrayList<>(competitors); + blue.removeAll(yellow); + Collections.shuffle(yellow); + Collections.shuffle(blue); + + Leaderboard leaderboard = createLeaderboard(regatta, /* discarding thresholds */ new int[0]); + TimePoint now = MillisecondsTimePoint.now(); + TimePoint later = new MillisecondsTimePoint(now.asMillis() + 1000); + executeRandomPreSeries(yellow, blue, now); + + List bestQualifing = leaderboard.getCompetitorsFromBestToWorst(later); + List medalCompetitors = bestQualifing.subList(0, 4); + + manuallyTransferCarry(leaderboard, medalCompetitors); + + Competitor preFirst = medalCompetitors.get(0); + Competitor preSecond = medalCompetitors.get(1); + Competitor preThird = medalCompetitors.get(2); + Competitor preFourth = medalCompetitors.get(3); + + RaceColumn m1 = leaderboard.getRaceColumnByName("M1"); + + ArrayList m1Results = new ArrayList<>(); + m1Results.add(preFirst); + m1Results.add(preSecond); + m1Results.add(preThird); + m1Results.add(preFourth); + + TrackedRace mDefault = new MockedTrackedRaceWithStartTimeAndRanks(now, m1Results); + m1.setTrackedRace(m1.getFleetByName("Default"), mDefault); + + Assert.assertEquals(2.0, leaderboard.getNetPoints(medalCompetitors.get(0), later), EPSILON); + Assert.assertEquals(4.0002, leaderboard.getNetPoints(medalCompetitors.get(1), later), EPSILON); + Assert.assertEquals(6.0004, leaderboard.getNetPoints(medalCompetitors.get(2), later), EPSILON); + Assert.assertEquals(8.0006, leaderboard.getNetPoints(medalCompetitors.get(3), later), EPSILON); + } + + @Test + public void negativeTestSecondPreSeriesWinsTwice() throws NoWindException { + series = new ArrayList(); + // -------- qualification series ------------ + setupPreSeries(); + setupMedalSeries(); + Regatta regatta = setupRegatta(false); + List competitors = createCompetitors(12); + List yellow = new ArrayList<>(competitors.subList(0, 6)); + List blue = new ArrayList<>(competitors); + blue.removeAll(yellow); + Collections.shuffle(yellow); + Collections.shuffle(blue); + + Leaderboard leaderboard = createLeaderboard(regatta, /* discarding thresholds */ new int[0]); + TimePoint now = MillisecondsTimePoint.now(); + TimePoint later = new MillisecondsTimePoint(now.asMillis() + 1000); + executeRandomPreSeries(yellow, blue, now); + + List medalCompetitorsBestToWorst = leaderboard.getCompetitorsFromBestToWorst(later).subList(0, 4); + manuallyTransferCarry(leaderboard, medalCompetitorsBestToWorst); + + Competitor preFirst = medalCompetitorsBestToWorst.get(0); + Competitor preSecond = medalCompetitorsBestToWorst.get(1); + Competitor preThird = medalCompetitorsBestToWorst.get(2); + Competitor preFourth = medalCompetitorsBestToWorst.get(3); + + RaceColumn m1 = leaderboard.getRaceColumnByName("M1"); + + ArrayList m1Results = new ArrayList<>(); + m1Results.add(preSecond); + m1Results.add(preFirst); + m1Results.add(preThird); + m1Results.add(preFourth); + + TimePoint m1now = new MillisecondsTimePoint(later.asMillis() + 1000); + TimePoint m1later = new MillisecondsTimePoint(m1now.asMillis() + 1000); + + TrackedRace m1Default = new MockedTrackedRaceWithStartTimeAndRanks(now, m1Results); + m1.setTrackedRace(m1.getFleetByName("Default"), m1Default); + + Assert.assertEquals(2.0002, leaderboard.getNetPoints(preSecond, later), EPSILON); + Assert.assertEquals(4.0, leaderboard.getNetPoints(preFirst, later), EPSILON); + Assert.assertEquals(6.0004, leaderboard.getNetPoints(preThird, later), EPSILON); + Assert.assertEquals(8.0006, leaderboard.getNetPoints(preFourth, later), EPSILON); + + RaceColumn m2 = leaderboard.getRaceColumnByName("M2"); + + ArrayList m2Results = new ArrayList<>(); + m2Results.add(preSecond); + m2Results.add(preFirst); + m2Results.add(preThird); + m2Results.add(preFourth); + + TimePoint m2now = new MillisecondsTimePoint(m1later.asMillis() + 1000); + TimePoint m2later = new MillisecondsTimePoint(m2now.asMillis() + 1000); + TrackedRace m2Default = new MockedTrackedRaceWithStartTimeAndRanks(m2now, m2Results); + m2.setTrackedRace(m1.getFleetByName("Default"), m2Default); + + Assert.assertEquals(4.0002, leaderboard.getNetPoints(preSecond, m2later), EPSILON); + Assert.assertEquals(8.0, leaderboard.getNetPoints(preFirst, m2later), EPSILON); + Assert.assertEquals(12.0004, leaderboard.getNetPoints(preThird, m2later), EPSILON); + Assert.assertEquals(16.0006, leaderboard.getNetPoints(preFourth, m2later), EPSILON); + } + + @Test + public void negativeTestFirstWinsSecondRace() throws NoWindException { + series = new ArrayList(); + // -------- qualification series ------------ + setupPreSeries(); + setupMedalSeries(); + Regatta regatta = setupRegatta(false); + List competitors = createCompetitors(12); + List yellow = new ArrayList<>(competitors.subList(0, 6)); + List blue = new ArrayList<>(competitors); + blue.removeAll(yellow); + Collections.shuffle(yellow); + Collections.shuffle(blue); + + Leaderboard leaderboard = createLeaderboard(regatta, /* discarding thresholds */ new int[0]); + TimePoint now = MillisecondsTimePoint.now(); + TimePoint later = new MillisecondsTimePoint(now.asMillis() + 1000); + executeRandomPreSeries(yellow, blue, now); + + List medalCompetitorsBestToWorst = leaderboard.getCompetitorsFromBestToWorst(later).subList(0, 4); + manuallyTransferCarry(leaderboard, medalCompetitorsBestToWorst); + + Competitor preFirst = medalCompetitorsBestToWorst.get(0); + Competitor preSecond = medalCompetitorsBestToWorst.get(1); + Competitor preThird = medalCompetitorsBestToWorst.get(2); + Competitor preFourth = medalCompetitorsBestToWorst.get(3); + + RaceColumn m1 = leaderboard.getRaceColumnByName("M1"); + + ArrayList m1Results = new ArrayList<>(); + m1Results.add(preSecond); + m1Results.add(preFirst); + m1Results.add(preThird); + m1Results.add(preFourth); + + TimePoint m1now = new MillisecondsTimePoint(later.asMillis() + 1000); + TimePoint m1later = new MillisecondsTimePoint(m1now.asMillis() + 1000); + + TrackedRace m1Default = new MockedTrackedRaceWithStartTimeAndRanks(now, m1Results); + m1.setTrackedRace(m1.getFleetByName("Default"), m1Default); + + Assert.assertEquals(2.0002, leaderboard.getNetPoints(preSecond, later), EPSILON); + Assert.assertEquals(4.0, leaderboard.getNetPoints(preFirst, later), EPSILON); + Assert.assertEquals(6.0004, leaderboard.getNetPoints(preThird, later), EPSILON); + Assert.assertEquals(8.0006, leaderboard.getNetPoints(preFourth, later), EPSILON); + + RaceColumn m2 = leaderboard.getRaceColumnByName("M2"); + + ArrayList m2Results = new ArrayList<>(); + m2Results.add(preFirst); + m2Results.add(preSecond); + m2Results.add(preThird); + m2Results.add(preFourth); + + TimePoint m2now = new MillisecondsTimePoint(m1later.asMillis() + 1000); + TimePoint m2later = new MillisecondsTimePoint(m2now.asMillis() + 1000); + TrackedRace m2Default = new MockedTrackedRaceWithStartTimeAndRanks(m2now, m2Results); + m2.setTrackedRace(m1.getFleetByName("Default"), m2Default); + + Assert.assertEquals(6.0, leaderboard.getNetPoints(preFirst, m2later), EPSILON); + Assert.assertEquals(6.0002, leaderboard.getNetPoints(preSecond, m2later), EPSILON); + Assert.assertEquals(12.0004, leaderboard.getNetPoints(preThird, m2later), EPSILON); + Assert.assertEquals(16.0006, leaderboard.getNetPoints(preFourth, m2later), EPSILON); + } + + @Test + public void negativeTestLastWinsTwoRaces() throws NoWindException { + series = new ArrayList(); + // -------- qualification series ------------ + setupPreSeries(); + setupMedalSeries(); + Regatta regatta = setupRegatta(false); + List competitors = createCompetitors(12); + List yellow = new ArrayList<>(competitors.subList(0, 6)); + List blue = new ArrayList<>(competitors); + blue.removeAll(yellow); + Collections.shuffle(yellow); + Collections.shuffle(blue); + + Leaderboard leaderboard = createLeaderboard(regatta, /* discarding thresholds */ new int[0]); + TimePoint now = MillisecondsTimePoint.now(); + TimePoint later = new MillisecondsTimePoint(now.asMillis() + 1000); + executeRandomPreSeries(yellow, blue, now); + + List medalCompetitorsBestToWorst = leaderboard.getCompetitorsFromBestToWorst(later).subList(0, 4); + manuallyTransferCarry(leaderboard, medalCompetitorsBestToWorst); + + Competitor preFirst = medalCompetitorsBestToWorst.get(0); + Competitor preSecond = medalCompetitorsBestToWorst.get(1); + Competitor preThird = medalCompetitorsBestToWorst.get(2); + Competitor preFourth = medalCompetitorsBestToWorst.get(3); + + RaceColumn m1 = leaderboard.getRaceColumnByName("M1"); + + ArrayList m1Results = new ArrayList<>(); + m1Results.add(preFourth); + m1Results.add(preFirst); + m1Results.add(preSecond); + m1Results.add(preThird); + + TimePoint m1now = new MillisecondsTimePoint(later.asMillis() + 1000); + TimePoint m1later = new MillisecondsTimePoint(m1now.asMillis() + 1000); + + TrackedRace m1Default = new MockedTrackedRaceWithStartTimeAndRanks(now, m1Results); + m1.setTrackedRace(m1.getFleetByName("Default"), m1Default); + + Assert.assertEquals(2.0006, leaderboard.getNetPoints(preFourth, later), EPSILON); + Assert.assertEquals(4.0, leaderboard.getNetPoints(preFirst, later), EPSILON); + Assert.assertEquals(6.0002, leaderboard.getNetPoints(preSecond, later), EPSILON); + Assert.assertEquals(8.0004, leaderboard.getNetPoints(preThird, later), EPSILON); + + RaceColumn m2 = leaderboard.getRaceColumnByName("M2"); + + ArrayList m2Results = new ArrayList<>(); + m2Results.add(preFourth); + m2Results.add(preFirst); + m2Results.add(preSecond); + m2Results.add(preThird); + + TimePoint m2now = new MillisecondsTimePoint(m1later.asMillis() + 1000); + TimePoint m2later = new MillisecondsTimePoint(m2now.asMillis() + 1000); + TrackedRace m2Default = new MockedTrackedRaceWithStartTimeAndRanks(m2now, m2Results); + m2.setTrackedRace(m1.getFleetByName("Default"), m2Default); + + Assert.assertEquals(4.0006, leaderboard.getNetPoints(preFourth, m2later), EPSILON); + Assert.assertEquals(8.0, leaderboard.getNetPoints(preFirst, m2later), EPSILON); + Assert.assertEquals(12.0002, leaderboard.getNetPoints(preSecond, m2later), EPSILON); + Assert.assertEquals(16.0004, leaderboard.getNetPoints(preThird, m2later), EPSILON); + } + + @Test + public void negativeNoTwoWinsAbortAfterTwoRacesAndTieBraker() throws NoWindException { + series = new ArrayList(); + // -------- qualification series ------------ + setupPreSeries(); + setupMedalSeries(); + Regatta regatta = setupRegatta(false); + List competitors = createCompetitors(12); + List yellow = new ArrayList<>(competitors.subList(0, 6)); + List blue = new ArrayList<>(competitors); + blue.removeAll(yellow); + Collections.shuffle(yellow); + Collections.shuffle(blue); + + Leaderboard leaderboard = createLeaderboard(regatta, /* discarding thresholds */ new int[0]); + TimePoint now = MillisecondsTimePoint.now(); + TimePoint later = new MillisecondsTimePoint(now.asMillis() + 1000); + executeRandomPreSeries(yellow, blue, now); + + List medalCompetitorsBestToWorst = leaderboard.getCompetitorsFromBestToWorst(later).subList(0, 4); + manuallyTransferCarry(leaderboard, medalCompetitorsBestToWorst); + + Competitor preFirst = medalCompetitorsBestToWorst.get(0); + Competitor preSecond = medalCompetitorsBestToWorst.get(1); + Competitor preThird = medalCompetitorsBestToWorst.get(2); + Competitor preFourth = medalCompetitorsBestToWorst.get(3); + + RaceColumn m1 = leaderboard.getRaceColumnByName("M1"); + + ArrayList m1Results = new ArrayList<>(); + m1Results.add(preFourth); + m1Results.add(preFirst); + m1Results.add(preSecond); + m1Results.add(preThird); + + TimePoint m1now = new MillisecondsTimePoint(later.asMillis() + 1000); + TimePoint m1later = new MillisecondsTimePoint(m1now.asMillis() + 1000); + + TrackedRace m1Default = new MockedTrackedRaceWithStartTimeAndRanks(now, m1Results); + m1.setTrackedRace(m1.getFleetByName("Default"), m1Default); + + Assert.assertEquals(2.0006, leaderboard.getNetPoints(preFourth, later), EPSILON); + Assert.assertEquals(4.0, leaderboard.getNetPoints(preFirst, later), EPSILON); + Assert.assertEquals(6.0002, leaderboard.getNetPoints(preSecond, later), EPSILON); + Assert.assertEquals(8.0004, leaderboard.getNetPoints(preThird, later), EPSILON); + + RaceColumn m2 = leaderboard.getRaceColumnByName("M2"); + + ArrayList m2Results = new ArrayList<>(); + m2Results.add(preThird); + m2Results.add(preFirst); + m2Results.add(preSecond); + m2Results.add(preFourth); + + TimePoint m2now = new MillisecondsTimePoint(m1later.asMillis() + 1000); + TimePoint m2later = new MillisecondsTimePoint(m2now.asMillis() + 1000); + TrackedRace m2Default = new MockedTrackedRaceWithStartTimeAndRanks(m2now, m2Results); + m2.setTrackedRace(m1.getFleetByName("Default"), m2Default); + + Assert.assertEquals(10.0006, leaderboard.getNetPoints(preFourth, m2later), EPSILON); + Assert.assertEquals(8.0, leaderboard.getNetPoints(preFirst, m2later), EPSILON); + Assert.assertEquals(12.0002, leaderboard.getNetPoints(preSecond, m2later), EPSILON); + Assert.assertEquals(10.0004, leaderboard.getNetPoints(preThird, m2later), EPSILON); + } + +} From aacf68948e17dea4000de63e995f1f7e9620f57e Mon Sep 17 00:00:00 2001 From: Steffen Schaefer Date: Mon, 16 Jul 2018 16:11:12 +0200 Subject: [PATCH 08/43] Bug 4661: Code cleanup and correct setup of medal series with non discardable carry forward --- ...oardScoringAndRankingTestForLowPoints.java | 92 +++++++++---------- 1 file changed, 44 insertions(+), 48 deletions(-) diff --git a/java/com.sap.sailing.domain.test/src/com/sap/sailing/domain/test/LeaderboardScoringAndRankingTestForLowPoints.java b/java/com.sap.sailing.domain.test/src/com/sap/sailing/domain/test/LeaderboardScoringAndRankingTestForLowPoints.java index 089f66af567..72fe22d92db 100644 --- a/java/com.sap.sailing.domain.test/src/com/sap/sailing/domain/test/LeaderboardScoringAndRankingTestForLowPoints.java +++ b/java/com.sap.sailing.domain.test/src/com/sap/sailing/domain/test/LeaderboardScoringAndRankingTestForLowPoints.java @@ -69,45 +69,41 @@ public class LeaderboardScoringAndRankingTestForLowPoints extends LeaderboardSco return regatta; } - private void setupMedalSeries() { - // -------- medal series ------------ - { - Set medalFleets = Collections.singleton(new FleetImpl("Default")); - List medalRaceColumnNames = new ArrayList(); - medalRaceColumnNames.add("Carry"); - medalRaceColumnNames.add("M1"); - medalRaceColumnNames.add("M2"); - medalRaceColumnNames.add("M3"); - medalRaceColumnNames.add("M4"); - Series medalSeries = new SeriesImpl("Medal", /* isMedal */true, /* isFleetsCanRunInParallel */ true, - medalFleets, medalRaceColumnNames, /* trackedRegattaRegistry */ null); - series.add(medalSeries); - } + private void setupMedalSeriesWithCarryOverAndFourRaceColumns() { + Set medalFleets = Collections.singleton(new FleetImpl("Default")); + List medalRaceColumnNames = new ArrayList(); + medalRaceColumnNames.add("Carry"); + medalRaceColumnNames.add("M1"); + medalRaceColumnNames.add("M2"); + medalRaceColumnNames.add("M3"); + medalRaceColumnNames.add("M4"); + Series medalSeries = new SeriesImpl("Medal", /* isMedal */true, /* isFleetsCanRunInParallel */ true, + medalFleets, medalRaceColumnNames, /* trackedRegattaRegistry */ null); + medalSeries.setFirstColumnIsNonDiscardableCarryForward(true); + series.add(medalSeries); } - private void setupPreSeries() { - { - List qualificationFleets = new ArrayList(); - for (String qualificationFleetName : new String[] { "Yellow", "Blue" }) { - qualificationFleets.add(new FleetImpl(qualificationFleetName)); - } - List qualificationRaceColumnNames = new ArrayList(); - qualificationRaceColumnNames.add("Q"); - Series qualificationSeries = new SeriesImpl("Qualification", /* isMedal */false, - /* isFleetsCanRunInParallel */ true, qualificationFleets, qualificationRaceColumnNames, - /* trackedRegattaRegistry */ null); - // discard the one and only qualification race; it doesn't score - qualificationSeries.setResultDiscardingRule(new ThresholdBasedResultDiscardingRuleImpl(new int[] { 1 })); - series.add(qualificationSeries); + private void setupQualificationSeriesWithOneRaceColumn() { + List qualificationFleets = new ArrayList(); + for (String qualificationFleetName : new String[] { "Yellow", "Blue" }) { + qualificationFleets.add(new FleetImpl(qualificationFleetName)); } + List qualificationRaceColumnNames = new ArrayList(); + qualificationRaceColumnNames.add("Q"); + Series qualificationSeries = new SeriesImpl("Qualification", /* isMedal */false, + /* isFleetsCanRunInParallel */ true, qualificationFleets, qualificationRaceColumnNames, + /* trackedRegattaRegistry */ null); + // discard the one and only qualification race; it doesn't score + qualificationSeries.setResultDiscardingRule(new ThresholdBasedResultDiscardingRuleImpl(new int[] { 1 })); + series.add(qualificationSeries); } @Test public void testFirstPreseriesWinsAgain() throws NoWindException { series = new ArrayList(); - setupPreSeries(); + setupQualificationSeriesWithOneRaceColumn(); - setupMedalSeries(); + setupMedalSeriesWithCarryOverAndFourRaceColumns(); Regatta regatta = setupRegatta(true); List competitors = createCompetitors(12); List yellow = new ArrayList<>(competitors.subList(0, 6)); @@ -152,8 +148,8 @@ public class LeaderboardScoringAndRankingTestForLowPoints extends LeaderboardSco public void testSecondPreSeriesWinsTwice() throws NoWindException { series = new ArrayList(); // -------- qualification series ------------ - setupPreSeries(); - setupMedalSeries(); + setupQualificationSeriesWithOneRaceColumn(); + setupMedalSeriesWithCarryOverAndFourRaceColumns(); Regatta regatta = setupRegatta(true); List competitors = createCompetitors(12); List yellow = new ArrayList<>(competitors.subList(0, 6)); @@ -217,8 +213,8 @@ public class LeaderboardScoringAndRankingTestForLowPoints extends LeaderboardSco public void testFirstWinsSecondRace() throws NoWindException { series = new ArrayList(); // -------- qualification series ------------ - setupPreSeries(); - setupMedalSeries(); + setupQualificationSeriesWithOneRaceColumn(); + setupMedalSeriesWithCarryOverAndFourRaceColumns(); Regatta regatta = setupRegatta(true); List competitors = createCompetitors(12); List yellow = new ArrayList<>(competitors.subList(0, 6)); @@ -282,8 +278,8 @@ public class LeaderboardScoringAndRankingTestForLowPoints extends LeaderboardSco public void testLastWinsTwoRaces() throws NoWindException { series = new ArrayList(); // -------- qualification series ------------ - setupPreSeries(); - setupMedalSeries(); + setupQualificationSeriesWithOneRaceColumn(); + setupMedalSeriesWithCarryOverAndFourRaceColumns(); Regatta regatta = setupRegatta(true); List competitors = createCompetitors(12); List yellow = new ArrayList<>(competitors.subList(0, 6)); @@ -347,8 +343,8 @@ public class LeaderboardScoringAndRankingTestForLowPoints extends LeaderboardSco public void noTwoWinsAbortAfterTwoRacesAndTieBraker() throws NoWindException { series = new ArrayList(); // -------- qualification series ------------ - setupPreSeries(); - setupMedalSeries(); + setupQualificationSeriesWithOneRaceColumn(); + setupMedalSeriesWithCarryOverAndFourRaceColumns(); Regatta regatta = setupRegatta(true); List competitors = createCompetitors(12); List yellow = new ArrayList<>(competitors.subList(0, 6)); @@ -412,9 +408,9 @@ public class LeaderboardScoringAndRankingTestForLowPoints extends LeaderboardSco @Test public void negativeTestFirstPreseriesWinsAgain() throws NoWindException { series = new ArrayList(); - setupPreSeries(); + setupQualificationSeriesWithOneRaceColumn(); - setupMedalSeries(); + setupMedalSeriesWithCarryOverAndFourRaceColumns(); Regatta regatta = setupRegatta(false); List competitors = createCompetitors(12); List yellow = new ArrayList<>(competitors.subList(0, 6)); @@ -459,8 +455,8 @@ public class LeaderboardScoringAndRankingTestForLowPoints extends LeaderboardSco public void negativeTestSecondPreSeriesWinsTwice() throws NoWindException { series = new ArrayList(); // -------- qualification series ------------ - setupPreSeries(); - setupMedalSeries(); + setupQualificationSeriesWithOneRaceColumn(); + setupMedalSeriesWithCarryOverAndFourRaceColumns(); Regatta regatta = setupRegatta(false); List competitors = createCompetitors(12); List yellow = new ArrayList<>(competitors.subList(0, 6)); @@ -524,8 +520,8 @@ public class LeaderboardScoringAndRankingTestForLowPoints extends LeaderboardSco public void negativeTestFirstWinsSecondRace() throws NoWindException { series = new ArrayList(); // -------- qualification series ------------ - setupPreSeries(); - setupMedalSeries(); + setupQualificationSeriesWithOneRaceColumn(); + setupMedalSeriesWithCarryOverAndFourRaceColumns(); Regatta regatta = setupRegatta(false); List competitors = createCompetitors(12); List yellow = new ArrayList<>(competitors.subList(0, 6)); @@ -589,8 +585,8 @@ public class LeaderboardScoringAndRankingTestForLowPoints extends LeaderboardSco public void negativeTestLastWinsTwoRaces() throws NoWindException { series = new ArrayList(); // -------- qualification series ------------ - setupPreSeries(); - setupMedalSeries(); + setupQualificationSeriesWithOneRaceColumn(); + setupMedalSeriesWithCarryOverAndFourRaceColumns(); Regatta regatta = setupRegatta(false); List competitors = createCompetitors(12); List yellow = new ArrayList<>(competitors.subList(0, 6)); @@ -654,8 +650,8 @@ public class LeaderboardScoringAndRankingTestForLowPoints extends LeaderboardSco public void negativeNoTwoWinsAbortAfterTwoRacesAndTieBraker() throws NoWindException { series = new ArrayList(); // -------- qualification series ------------ - setupPreSeries(); - setupMedalSeries(); + setupQualificationSeriesWithOneRaceColumn(); + setupMedalSeriesWithCarryOverAndFourRaceColumns(); Regatta regatta = setupRegatta(false); List competitors = createCompetitors(12); List yellow = new ArrayList<>(competitors.subList(0, 6)); From 14c48207a64701b0c364079c13b3286d4df618e4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kai=20B=C3=B6rnert?= Date: Mon, 16 Jul 2018 17:47:44 +0200 Subject: [PATCH 09/43] bug4661 fix for wrongly setup series --- ...oardScoringAndRankingTestForLowPoints.java | 99 ++++++++++++++++--- 1 file changed, 83 insertions(+), 16 deletions(-) diff --git a/java/com.sap.sailing.domain.test/src/com/sap/sailing/domain/test/LeaderboardScoringAndRankingTestForLowPoints.java b/java/com.sap.sailing.domain.test/src/com/sap/sailing/domain/test/LeaderboardScoringAndRankingTestForLowPoints.java index 72fe22d92db..27fb37b0c8e 100644 --- a/java/com.sap.sailing.domain.test/src/com/sap/sailing/domain/test/LeaderboardScoringAndRankingTestForLowPoints.java +++ b/java/com.sap.sailing.domain.test/src/com/sap/sailing/domain/test/LeaderboardScoringAndRankingTestForLowPoints.java @@ -21,11 +21,11 @@ import com.sap.sailing.domain.common.NoWindException; import com.sap.sailing.domain.common.ScoringSchemeType; import com.sap.sailing.domain.leaderboard.Leaderboard; import com.sap.sailing.domain.leaderboard.impl.DelegatingRegattaLeaderboardWithCompetitorElimination; -import com.sap.sailing.domain.leaderboard.impl.ThresholdBasedResultDiscardingRuleImpl; import com.sap.sailing.domain.ranking.OneDesignRankingMetric; import com.sap.sailing.domain.test.mock.MockedTrackedRaceWithStartTimeAndRanks; import com.sap.sailing.domain.tracking.TrackedRace; import com.sap.sse.common.TimePoint; +import com.sap.sse.common.Util.Pair; import com.sap.sse.common.impl.MillisecondsTimePoint; import junit.framework.Assert; @@ -60,7 +60,7 @@ public class LeaderboardScoringAndRankingTestForLowPoints extends LeaderboardSco final BoatClass boatClass = DomainFactory.INSTANCE.getOrCreateBoatClass("470", /* typicallyStartsUpwind */ true); Regatta regatta = new RegattaImpl(RegattaImpl.getDefaultName("Test Regatta", boatClass.getName()), boatClass, - /* canBoatsOfCompetitorsChangePerRace */ true, /* startDate */ null, /* endDate */ null, series, + false, /* startDate */ null, /* endDate */ null, series, /* persistent */false, DomainFactory.INSTANCE .createScoringScheme(useFirstTwoWins ? ScoringSchemeType.LOW_POINT_FIRST_TO_WIN_TWO_RACES @@ -80,6 +80,7 @@ public class LeaderboardScoringAndRankingTestForLowPoints extends LeaderboardSco Series medalSeries = new SeriesImpl("Medal", /* isMedal */true, /* isFleetsCanRunInParallel */ true, medalFleets, medalRaceColumnNames, /* trackedRegattaRegistry */ null); medalSeries.setFirstColumnIsNonDiscardableCarryForward(true); + medalSeries.setStartsWithZeroScore(true); series.add(medalSeries); } @@ -93,10 +94,25 @@ public class LeaderboardScoringAndRankingTestForLowPoints extends LeaderboardSco Series qualificationSeries = new SeriesImpl("Qualification", /* isMedal */false, /* isFleetsCanRunInParallel */ true, qualificationFleets, qualificationRaceColumnNames, /* trackedRegattaRegistry */ null); - // discard the one and only qualification race; it doesn't score - qualificationSeries.setResultDiscardingRule(new ThresholdBasedResultDiscardingRuleImpl(new int[] { 1 })); series.add(qualificationSeries); } + + + private List> createCompetitorResultForTimestamp(TimePoint time, Leaderboard leaderboard) { + List> list = new ArrayList<>(); + for (Competitor competitor : leaderboard.getCompetitorsFromBestToWorst(time)) { + list.add(new Pair(competitor, leaderboard.getNetPoints(competitor, time))); + } + return list; + } + + + private void assertNonFinalistsAreBehindFinalistsAndNotChanged( + List> preSeriesScoreRankResult, List> afterFinalResults) { + List> nonFinalistsPreScore = preSeriesScoreRankResult.subList(4, preSeriesScoreRankResult.size()); + List> nonFinalistsAfterScore = afterFinalResults.subList(4, afterFinalResults.size()); + Assert.assertEquals(nonFinalistsPreScore, nonFinalistsAfterScore); + } @Test public void testFirstPreseriesWinsAgain() throws NoWindException { @@ -117,8 +133,10 @@ public class LeaderboardScoringAndRankingTestForLowPoints extends LeaderboardSco TimePoint later = new MillisecondsTimePoint(now.asMillis() + 1000); executeRandomPreSeries(yellow, blue, now); - List bestQualifing = leaderboard.getCompetitorsFromBestToWorst(later); - List medalCompetitors = bestQualifing.subList(0, 4); + List preSeriesRankResult = leaderboard.getCompetitorsFromBestToWorst(later); + List medalCompetitorsBestToWorst = preSeriesRankResult.subList(0, 4); + List> preSeriesScoreRankResult = createCompetitorResultForTimestamp(later, leaderboard); + List medalCompetitors = preSeriesRankResult.subList(0, 4); manuallyTransferCarry(leaderboard, medalCompetitors); @@ -142,6 +160,9 @@ public class LeaderboardScoringAndRankingTestForLowPoints extends LeaderboardSco Assert.assertEquals(2.0001, leaderboard.getNetPoints(medalCompetitors.get(1), later), EPSILON); Assert.assertEquals(3.0002, leaderboard.getNetPoints(medalCompetitors.get(2), later), EPSILON); Assert.assertEquals(4.0003, leaderboard.getNetPoints(medalCompetitors.get(3), later), EPSILON); + + List> afterFinalResults = createCompetitorResultForTimestamp(later, leaderboard); + assertNonFinalistsAreBehindFinalistsAndNotChanged(preSeriesScoreRankResult, afterFinalResults); } @Test @@ -163,7 +184,9 @@ public class LeaderboardScoringAndRankingTestForLowPoints extends LeaderboardSco TimePoint later = new MillisecondsTimePoint(now.asMillis() + 1000); executeRandomPreSeries(yellow, blue, now); - List medalCompetitorsBestToWorst = leaderboard.getCompetitorsFromBestToWorst(later).subList(0, 4); + List preSeriesRankResult = leaderboard.getCompetitorsFromBestToWorst(later); + List medalCompetitorsBestToWorst = preSeriesRankResult.subList(0, 4); + List> preSeriesScoreRankResult = createCompetitorResultForTimestamp(later, leaderboard); manuallyTransferCarry(leaderboard, medalCompetitorsBestToWorst); Competitor preFirst = medalCompetitorsBestToWorst.get(0); @@ -207,6 +230,9 @@ public class LeaderboardScoringAndRankingTestForLowPoints extends LeaderboardSco Assert.assertEquals(4.0, leaderboard.getNetPoints(preFirst, m2later), EPSILON); Assert.assertEquals(6.0002, leaderboard.getNetPoints(preThird, m2later), EPSILON); Assert.assertEquals(8.0003, leaderboard.getNetPoints(preFourth, m2later), EPSILON); + + List> afterFinalResults = createCompetitorResultForTimestamp(m2later, leaderboard); + assertNonFinalistsAreBehindFinalistsAndNotChanged(preSeriesScoreRankResult, afterFinalResults); } @Test @@ -228,7 +254,9 @@ public class LeaderboardScoringAndRankingTestForLowPoints extends LeaderboardSco TimePoint later = new MillisecondsTimePoint(now.asMillis() + 1000); executeRandomPreSeries(yellow, blue, now); - List medalCompetitorsBestToWorst = leaderboard.getCompetitorsFromBestToWorst(later).subList(0, 4); + List preSeriesRankResult = leaderboard.getCompetitorsFromBestToWorst(later); + List medalCompetitorsBestToWorst = preSeriesRankResult.subList(0, 4); + List> preSeriesScoreRankResult = createCompetitorResultForTimestamp(later, leaderboard); manuallyTransferCarry(leaderboard, medalCompetitorsBestToWorst); Competitor preFirst = medalCompetitorsBestToWorst.get(0); @@ -272,6 +300,9 @@ public class LeaderboardScoringAndRankingTestForLowPoints extends LeaderboardSco Assert.assertEquals(3.0001, leaderboard.getNetPoints(preSecond, m2later), EPSILON); Assert.assertEquals(6.0002, leaderboard.getNetPoints(preThird, m2later), EPSILON); Assert.assertEquals(8.0003, leaderboard.getNetPoints(preFourth, m2later), EPSILON); + + List> afterFinalResults = createCompetitorResultForTimestamp(m2later, leaderboard); + assertNonFinalistsAreBehindFinalistsAndNotChanged(preSeriesScoreRankResult, afterFinalResults); } @Test @@ -293,7 +324,9 @@ public class LeaderboardScoringAndRankingTestForLowPoints extends LeaderboardSco TimePoint later = new MillisecondsTimePoint(now.asMillis() + 1000); executeRandomPreSeries(yellow, blue, now); - List medalCompetitorsBestToWorst = leaderboard.getCompetitorsFromBestToWorst(later).subList(0, 4); + List preSeriesRankResult = leaderboard.getCompetitorsFromBestToWorst(later); + List medalCompetitorsBestToWorst = preSeriesRankResult.subList(0, 4); + List> preSeriesScoreRankResult = createCompetitorResultForTimestamp(later, leaderboard); manuallyTransferCarry(leaderboard, medalCompetitorsBestToWorst); Competitor preFirst = medalCompetitorsBestToWorst.get(0); @@ -337,6 +370,9 @@ public class LeaderboardScoringAndRankingTestForLowPoints extends LeaderboardSco Assert.assertEquals(4.0, leaderboard.getNetPoints(preFirst, m2later), EPSILON); Assert.assertEquals(6.0001, leaderboard.getNetPoints(preSecond, m2later), EPSILON); Assert.assertEquals(8.0002, leaderboard.getNetPoints(preThird, m2later), EPSILON); + + List> afterFinalResults = createCompetitorResultForTimestamp(m2later, leaderboard); + assertNonFinalistsAreBehindFinalistsAndNotChanged(preSeriesScoreRankResult, afterFinalResults); } @Test @@ -358,7 +394,9 @@ public class LeaderboardScoringAndRankingTestForLowPoints extends LeaderboardSco TimePoint later = new MillisecondsTimePoint(now.asMillis() + 1000); executeRandomPreSeries(yellow, blue, now); - List medalCompetitorsBestToWorst = leaderboard.getCompetitorsFromBestToWorst(later).subList(0, 4); + List preSeriesRankResult = leaderboard.getCompetitorsFromBestToWorst(later); + List medalCompetitorsBestToWorst = preSeriesRankResult.subList(0, 4); + List> preSeriesScoreRankResult = createCompetitorResultForTimestamp(later, leaderboard); manuallyTransferCarry(leaderboard, medalCompetitorsBestToWorst); Competitor preFirst = medalCompetitorsBestToWorst.get(0); @@ -402,6 +440,9 @@ public class LeaderboardScoringAndRankingTestForLowPoints extends LeaderboardSco Assert.assertEquals(4.0, leaderboard.getNetPoints(preFirst, m2later), EPSILON); Assert.assertEquals(6.0001, leaderboard.getNetPoints(preSecond, m2later), EPSILON); Assert.assertEquals(5.0002, leaderboard.getNetPoints(preThird, m2later), EPSILON); + + List> afterFinalResults = createCompetitorResultForTimestamp(m2later, leaderboard); + assertNonFinalistsAreBehindFinalistsAndNotChanged(preSeriesScoreRankResult, afterFinalResults); } @@ -424,8 +465,10 @@ public class LeaderboardScoringAndRankingTestForLowPoints extends LeaderboardSco TimePoint later = new MillisecondsTimePoint(now.asMillis() + 1000); executeRandomPreSeries(yellow, blue, now); - List bestQualifing = leaderboard.getCompetitorsFromBestToWorst(later); - List medalCompetitors = bestQualifing.subList(0, 4); + List preSeriesRankResult = leaderboard.getCompetitorsFromBestToWorst(later); + List medalCompetitorsBestToWorst = preSeriesRankResult.subList(0, 4); + List> preSeriesScoreRankResult = createCompetitorResultForTimestamp(later, leaderboard); + List medalCompetitors = preSeriesRankResult.subList(0, 4); manuallyTransferCarry(leaderboard, medalCompetitors); @@ -449,6 +492,9 @@ public class LeaderboardScoringAndRankingTestForLowPoints extends LeaderboardSco Assert.assertEquals(4.0002, leaderboard.getNetPoints(medalCompetitors.get(1), later), EPSILON); Assert.assertEquals(6.0004, leaderboard.getNetPoints(medalCompetitors.get(2), later), EPSILON); Assert.assertEquals(8.0006, leaderboard.getNetPoints(medalCompetitors.get(3), later), EPSILON); + + List> afterFinalResults = createCompetitorResultForTimestamp(later, leaderboard); + assertNonFinalistsAreBehindFinalistsAndNotChanged(preSeriesScoreRankResult, afterFinalResults); } @Test @@ -470,7 +516,9 @@ public class LeaderboardScoringAndRankingTestForLowPoints extends LeaderboardSco TimePoint later = new MillisecondsTimePoint(now.asMillis() + 1000); executeRandomPreSeries(yellow, blue, now); - List medalCompetitorsBestToWorst = leaderboard.getCompetitorsFromBestToWorst(later).subList(0, 4); + List preSeriesRankResult = leaderboard.getCompetitorsFromBestToWorst(later); + List medalCompetitorsBestToWorst = preSeriesRankResult.subList(0, 4); + List> preSeriesScoreRankResult = createCompetitorResultForTimestamp(later, leaderboard); manuallyTransferCarry(leaderboard, medalCompetitorsBestToWorst); Competitor preFirst = medalCompetitorsBestToWorst.get(0); @@ -514,6 +562,9 @@ public class LeaderboardScoringAndRankingTestForLowPoints extends LeaderboardSco Assert.assertEquals(8.0, leaderboard.getNetPoints(preFirst, m2later), EPSILON); Assert.assertEquals(12.0004, leaderboard.getNetPoints(preThird, m2later), EPSILON); Assert.assertEquals(16.0006, leaderboard.getNetPoints(preFourth, m2later), EPSILON); + + List> afterFinalResults = createCompetitorResultForTimestamp(m2later, leaderboard); + assertNonFinalistsAreBehindFinalistsAndNotChanged(preSeriesScoreRankResult, afterFinalResults); } @Test @@ -535,7 +586,9 @@ public class LeaderboardScoringAndRankingTestForLowPoints extends LeaderboardSco TimePoint later = new MillisecondsTimePoint(now.asMillis() + 1000); executeRandomPreSeries(yellow, blue, now); - List medalCompetitorsBestToWorst = leaderboard.getCompetitorsFromBestToWorst(later).subList(0, 4); + List preSeriesRankResult = leaderboard.getCompetitorsFromBestToWorst(later); + List medalCompetitorsBestToWorst = preSeriesRankResult.subList(0, 4); + List> preSeriesScoreRankResult = createCompetitorResultForTimestamp(later, leaderboard); manuallyTransferCarry(leaderboard, medalCompetitorsBestToWorst); Competitor preFirst = medalCompetitorsBestToWorst.get(0); @@ -579,6 +632,9 @@ public class LeaderboardScoringAndRankingTestForLowPoints extends LeaderboardSco Assert.assertEquals(6.0002, leaderboard.getNetPoints(preSecond, m2later), EPSILON); Assert.assertEquals(12.0004, leaderboard.getNetPoints(preThird, m2later), EPSILON); Assert.assertEquals(16.0006, leaderboard.getNetPoints(preFourth, m2later), EPSILON); + + List> afterFinalResults = createCompetitorResultForTimestamp(m2later, leaderboard); + assertNonFinalistsAreBehindFinalistsAndNotChanged(preSeriesScoreRankResult, afterFinalResults); } @Test @@ -600,7 +656,10 @@ public class LeaderboardScoringAndRankingTestForLowPoints extends LeaderboardSco TimePoint later = new MillisecondsTimePoint(now.asMillis() + 1000); executeRandomPreSeries(yellow, blue, now); - List medalCompetitorsBestToWorst = leaderboard.getCompetitorsFromBestToWorst(later).subList(0, 4); + List preSeriesRankResult = leaderboard.getCompetitorsFromBestToWorst(later); + List medalCompetitorsBestToWorst = preSeriesRankResult.subList(0, 4); + List> preSeriesScoreRankResult = createCompetitorResultForTimestamp(later, leaderboard); + manuallyTransferCarry(leaderboard, medalCompetitorsBestToWorst); Competitor preFirst = medalCompetitorsBestToWorst.get(0); @@ -644,6 +703,9 @@ public class LeaderboardScoringAndRankingTestForLowPoints extends LeaderboardSco Assert.assertEquals(8.0, leaderboard.getNetPoints(preFirst, m2later), EPSILON); Assert.assertEquals(12.0002, leaderboard.getNetPoints(preSecond, m2later), EPSILON); Assert.assertEquals(16.0004, leaderboard.getNetPoints(preThird, m2later), EPSILON); + + List> afterFinalResults = createCompetitorResultForTimestamp(m2later, leaderboard); + assertNonFinalistsAreBehindFinalistsAndNotChanged(preSeriesScoreRankResult, afterFinalResults); } @Test @@ -665,7 +727,9 @@ public class LeaderboardScoringAndRankingTestForLowPoints extends LeaderboardSco TimePoint later = new MillisecondsTimePoint(now.asMillis() + 1000); executeRandomPreSeries(yellow, blue, now); - List medalCompetitorsBestToWorst = leaderboard.getCompetitorsFromBestToWorst(later).subList(0, 4); + List preSeriesRankResult = leaderboard.getCompetitorsFromBestToWorst(later); + List medalCompetitorsBestToWorst = preSeriesRankResult.subList(0, 4); + List> preSeriesScoreRankResult = createCompetitorResultForTimestamp(later, leaderboard); manuallyTransferCarry(leaderboard, medalCompetitorsBestToWorst); Competitor preFirst = medalCompetitorsBestToWorst.get(0); @@ -709,6 +773,9 @@ public class LeaderboardScoringAndRankingTestForLowPoints extends LeaderboardSco Assert.assertEquals(8.0, leaderboard.getNetPoints(preFirst, m2later), EPSILON); Assert.assertEquals(12.0002, leaderboard.getNetPoints(preSecond, m2later), EPSILON); Assert.assertEquals(10.0004, leaderboard.getNetPoints(preThird, m2later), EPSILON); + + List> afterFinalResults = createCompetitorResultForTimestamp(m2later, leaderboard); + assertNonFinalistsAreBehindFinalistsAndNotChanged(preSeriesScoreRankResult, afterFinalResults); } } From 30c789820d04602ea26823b954f27efb0893f559 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kai=20B=C3=B6rnert?= Date: Tue, 17 Jul 2018 08:43:11 +0200 Subject: [PATCH 10/43] bug4661 testing of non finalist scores added --- ...oardScoringAndRankingTestForLowPoints.java | 20 +++++++++---------- 1 file changed, 9 insertions(+), 11 deletions(-) diff --git a/java/com.sap.sailing.domain.test/src/com/sap/sailing/domain/test/LeaderboardScoringAndRankingTestForLowPoints.java b/java/com.sap.sailing.domain.test/src/com/sap/sailing/domain/test/LeaderboardScoringAndRankingTestForLowPoints.java index 27fb37b0c8e..dfdfbdc613c 100644 --- a/java/com.sap.sailing.domain.test/src/com/sap/sailing/domain/test/LeaderboardScoringAndRankingTestForLowPoints.java +++ b/java/com.sap.sailing.domain.test/src/com/sap/sailing/domain/test/LeaderboardScoringAndRankingTestForLowPoints.java @@ -136,14 +136,13 @@ public class LeaderboardScoringAndRankingTestForLowPoints extends LeaderboardSco List preSeriesRankResult = leaderboard.getCompetitorsFromBestToWorst(later); List medalCompetitorsBestToWorst = preSeriesRankResult.subList(0, 4); List> preSeriesScoreRankResult = createCompetitorResultForTimestamp(later, leaderboard); - List medalCompetitors = preSeriesRankResult.subList(0, 4); - manuallyTransferCarry(leaderboard, medalCompetitors); + manuallyTransferCarry(leaderboard, medalCompetitorsBestToWorst); - Competitor preFirst = medalCompetitors.get(0); - Competitor preSecond = medalCompetitors.get(1); - Competitor preThird = medalCompetitors.get(2); - Competitor preFourth = medalCompetitors.get(3); + Competitor preFirst = medalCompetitorsBestToWorst.get(0); + Competitor preSecond = medalCompetitorsBestToWorst.get(1); + Competitor preThird = medalCompetitorsBestToWorst.get(2); + Competitor preFourth = medalCompetitorsBestToWorst.get(3); RaceColumn m1 = leaderboard.getRaceColumnByName("M1"); @@ -156,10 +155,10 @@ public class LeaderboardScoringAndRankingTestForLowPoints extends LeaderboardSco TrackedRace mDefault = new MockedTrackedRaceWithStartTimeAndRanks(now, m1Results); m1.setTrackedRace(m1.getFleetByName("Default"), mDefault); - Assert.assertEquals(2.0, leaderboard.getNetPoints(medalCompetitors.get(0), later), EPSILON); - Assert.assertEquals(2.0001, leaderboard.getNetPoints(medalCompetitors.get(1), later), EPSILON); - Assert.assertEquals(3.0002, leaderboard.getNetPoints(medalCompetitors.get(2), later), EPSILON); - Assert.assertEquals(4.0003, leaderboard.getNetPoints(medalCompetitors.get(3), later), EPSILON); + Assert.assertEquals(2.0, leaderboard.getNetPoints(medalCompetitorsBestToWorst.get(0), later), EPSILON); + Assert.assertEquals(2.0001, leaderboard.getNetPoints(medalCompetitorsBestToWorst.get(1), later), EPSILON); + Assert.assertEquals(3.0002, leaderboard.getNetPoints(medalCompetitorsBestToWorst.get(2), later), EPSILON); + Assert.assertEquals(4.0003, leaderboard.getNetPoints(medalCompetitorsBestToWorst.get(3), later), EPSILON); List> afterFinalResults = createCompetitorResultForTimestamp(later, leaderboard); assertNonFinalistsAreBehindFinalistsAndNotChanged(preSeriesScoreRankResult, afterFinalResults); @@ -466,7 +465,6 @@ public class LeaderboardScoringAndRankingTestForLowPoints extends LeaderboardSco executeRandomPreSeries(yellow, blue, now); List preSeriesRankResult = leaderboard.getCompetitorsFromBestToWorst(later); - List medalCompetitorsBestToWorst = preSeriesRankResult.subList(0, 4); List> preSeriesScoreRankResult = createCompetitorResultForTimestamp(later, leaderboard); List medalCompetitors = preSeriesRankResult.subList(0, 4); From 95d71cdb9fb9d300257928fe5bb5e6dd496b7a52 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kai=20B=C3=B6rnert?= Date: Tue, 17 Jul 2018 09:16:03 +0200 Subject: [PATCH 11/43] bug4661 formating/code style only change --- ...oardScoringAndRankingTestForLowPoints.java | 65 ++++++++++--------- .../domain/leaderboard/ScoringScheme.java | 12 ++-- .../impl/AbstractScoringSchemeImpl.java | 4 +- .../impl/LeaderboardTotalRankComparator.java | 23 ++++--- .../gwt/ui/server/SailingServiceImpl.java | 3 +- .../gateway/impl/rc/RaceGroupFactory.java | 16 +++-- .../server/test/MasterDataImportTest.java | 12 ++-- 7 files changed, 73 insertions(+), 62 deletions(-) diff --git a/java/com.sap.sailing.domain.test/src/com/sap/sailing/domain/test/LeaderboardScoringAndRankingTestForLowPoints.java b/java/com.sap.sailing.domain.test/src/com/sap/sailing/domain/test/LeaderboardScoringAndRankingTestForLowPoints.java index dfdfbdc613c..7f79f909480 100644 --- a/java/com.sap.sailing.domain.test/src/com/sap/sailing/domain/test/LeaderboardScoringAndRankingTestForLowPoints.java +++ b/java/com.sap.sailing.domain.test/src/com/sap/sailing/domain/test/LeaderboardScoringAndRankingTestForLowPoints.java @@ -60,8 +60,7 @@ public class LeaderboardScoringAndRankingTestForLowPoints extends LeaderboardSco final BoatClass boatClass = DomainFactory.INSTANCE.getOrCreateBoatClass("470", /* typicallyStartsUpwind */ true); Regatta regatta = new RegattaImpl(RegattaImpl.getDefaultName("Test Regatta", boatClass.getName()), boatClass, - false, /* startDate */ null, /* endDate */ null, series, - /* persistent */false, + false, /* startDate */ null, /* endDate */ null, series, /* persistent */false, DomainFactory.INSTANCE .createScoringScheme(useFirstTwoWins ? ScoringSchemeType.LOW_POINT_FIRST_TO_WIN_TWO_RACES : ScoringSchemeType.LOW_POINT), @@ -96,7 +95,6 @@ public class LeaderboardScoringAndRankingTestForLowPoints extends LeaderboardSco /* trackedRegattaRegistry */ null); series.add(qualificationSeries); } - private List> createCompetitorResultForTimestamp(TimePoint time, Leaderboard leaderboard) { List> list = new ArrayList<>(); @@ -105,11 +103,11 @@ public class LeaderboardScoringAndRankingTestForLowPoints extends LeaderboardSco } return list; } - private void assertNonFinalistsAreBehindFinalistsAndNotChanged( List> preSeriesScoreRankResult, List> afterFinalResults) { - List> nonFinalistsPreScore = preSeriesScoreRankResult.subList(4, preSeriesScoreRankResult.size()); + List> nonFinalistsPreScore = preSeriesScoreRankResult.subList(4, + preSeriesScoreRankResult.size()); List> nonFinalistsAfterScore = afterFinalResults.subList(4, afterFinalResults.size()); Assert.assertEquals(nonFinalistsPreScore, nonFinalistsAfterScore); } @@ -135,7 +133,8 @@ public class LeaderboardScoringAndRankingTestForLowPoints extends LeaderboardSco List preSeriesRankResult = leaderboard.getCompetitorsFromBestToWorst(later); List medalCompetitorsBestToWorst = preSeriesRankResult.subList(0, 4); - List> preSeriesScoreRankResult = createCompetitorResultForTimestamp(later, leaderboard); + List> preSeriesScoreRankResult = createCompetitorResultForTimestamp(later, + leaderboard); manuallyTransferCarry(leaderboard, medalCompetitorsBestToWorst); @@ -159,7 +158,7 @@ public class LeaderboardScoringAndRankingTestForLowPoints extends LeaderboardSco Assert.assertEquals(2.0001, leaderboard.getNetPoints(medalCompetitorsBestToWorst.get(1), later), EPSILON); Assert.assertEquals(3.0002, leaderboard.getNetPoints(medalCompetitorsBestToWorst.get(2), later), EPSILON); Assert.assertEquals(4.0003, leaderboard.getNetPoints(medalCompetitorsBestToWorst.get(3), later), EPSILON); - + List> afterFinalResults = createCompetitorResultForTimestamp(later, leaderboard); assertNonFinalistsAreBehindFinalistsAndNotChanged(preSeriesScoreRankResult, afterFinalResults); } @@ -185,7 +184,8 @@ public class LeaderboardScoringAndRankingTestForLowPoints extends LeaderboardSco List preSeriesRankResult = leaderboard.getCompetitorsFromBestToWorst(later); List medalCompetitorsBestToWorst = preSeriesRankResult.subList(0, 4); - List> preSeriesScoreRankResult = createCompetitorResultForTimestamp(later, leaderboard); + List> preSeriesScoreRankResult = createCompetitorResultForTimestamp(later, + leaderboard); manuallyTransferCarry(leaderboard, medalCompetitorsBestToWorst); Competitor preFirst = medalCompetitorsBestToWorst.get(0); @@ -229,7 +229,7 @@ public class LeaderboardScoringAndRankingTestForLowPoints extends LeaderboardSco Assert.assertEquals(4.0, leaderboard.getNetPoints(preFirst, m2later), EPSILON); Assert.assertEquals(6.0002, leaderboard.getNetPoints(preThird, m2later), EPSILON); Assert.assertEquals(8.0003, leaderboard.getNetPoints(preFourth, m2later), EPSILON); - + List> afterFinalResults = createCompetitorResultForTimestamp(m2later, leaderboard); assertNonFinalistsAreBehindFinalistsAndNotChanged(preSeriesScoreRankResult, afterFinalResults); } @@ -255,7 +255,8 @@ public class LeaderboardScoringAndRankingTestForLowPoints extends LeaderboardSco List preSeriesRankResult = leaderboard.getCompetitorsFromBestToWorst(later); List medalCompetitorsBestToWorst = preSeriesRankResult.subList(0, 4); - List> preSeriesScoreRankResult = createCompetitorResultForTimestamp(later, leaderboard); + List> preSeriesScoreRankResult = createCompetitorResultForTimestamp(later, + leaderboard); manuallyTransferCarry(leaderboard, medalCompetitorsBestToWorst); Competitor preFirst = medalCompetitorsBestToWorst.get(0); @@ -299,7 +300,7 @@ public class LeaderboardScoringAndRankingTestForLowPoints extends LeaderboardSco Assert.assertEquals(3.0001, leaderboard.getNetPoints(preSecond, m2later), EPSILON); Assert.assertEquals(6.0002, leaderboard.getNetPoints(preThird, m2later), EPSILON); Assert.assertEquals(8.0003, leaderboard.getNetPoints(preFourth, m2later), EPSILON); - + List> afterFinalResults = createCompetitorResultForTimestamp(m2later, leaderboard); assertNonFinalistsAreBehindFinalistsAndNotChanged(preSeriesScoreRankResult, afterFinalResults); } @@ -325,7 +326,8 @@ public class LeaderboardScoringAndRankingTestForLowPoints extends LeaderboardSco List preSeriesRankResult = leaderboard.getCompetitorsFromBestToWorst(later); List medalCompetitorsBestToWorst = preSeriesRankResult.subList(0, 4); - List> preSeriesScoreRankResult = createCompetitorResultForTimestamp(later, leaderboard); + List> preSeriesScoreRankResult = createCompetitorResultForTimestamp(later, + leaderboard); manuallyTransferCarry(leaderboard, medalCompetitorsBestToWorst); Competitor preFirst = medalCompetitorsBestToWorst.get(0); @@ -369,7 +371,7 @@ public class LeaderboardScoringAndRankingTestForLowPoints extends LeaderboardSco Assert.assertEquals(4.0, leaderboard.getNetPoints(preFirst, m2later), EPSILON); Assert.assertEquals(6.0001, leaderboard.getNetPoints(preSecond, m2later), EPSILON); Assert.assertEquals(8.0002, leaderboard.getNetPoints(preThird, m2later), EPSILON); - + List> afterFinalResults = createCompetitorResultForTimestamp(m2later, leaderboard); assertNonFinalistsAreBehindFinalistsAndNotChanged(preSeriesScoreRankResult, afterFinalResults); } @@ -395,7 +397,8 @@ public class LeaderboardScoringAndRankingTestForLowPoints extends LeaderboardSco List preSeriesRankResult = leaderboard.getCompetitorsFromBestToWorst(later); List medalCompetitorsBestToWorst = preSeriesRankResult.subList(0, 4); - List> preSeriesScoreRankResult = createCompetitorResultForTimestamp(later, leaderboard); + List> preSeriesScoreRankResult = createCompetitorResultForTimestamp(later, + leaderboard); manuallyTransferCarry(leaderboard, medalCompetitorsBestToWorst); Competitor preFirst = medalCompetitorsBestToWorst.get(0); @@ -439,12 +442,11 @@ public class LeaderboardScoringAndRankingTestForLowPoints extends LeaderboardSco Assert.assertEquals(4.0, leaderboard.getNetPoints(preFirst, m2later), EPSILON); Assert.assertEquals(6.0001, leaderboard.getNetPoints(preSecond, m2later), EPSILON); Assert.assertEquals(5.0002, leaderboard.getNetPoints(preThird, m2later), EPSILON); - + List> afterFinalResults = createCompetitorResultForTimestamp(m2later, leaderboard); assertNonFinalistsAreBehindFinalistsAndNotChanged(preSeriesScoreRankResult, afterFinalResults); } - - + @Test public void negativeTestFirstPreseriesWinsAgain() throws NoWindException { series = new ArrayList(); @@ -465,7 +467,8 @@ public class LeaderboardScoringAndRankingTestForLowPoints extends LeaderboardSco executeRandomPreSeries(yellow, blue, now); List preSeriesRankResult = leaderboard.getCompetitorsFromBestToWorst(later); - List> preSeriesScoreRankResult = createCompetitorResultForTimestamp(later, leaderboard); + List> preSeriesScoreRankResult = createCompetitorResultForTimestamp(later, + leaderboard); List medalCompetitors = preSeriesRankResult.subList(0, 4); manuallyTransferCarry(leaderboard, medalCompetitors); @@ -490,7 +493,7 @@ public class LeaderboardScoringAndRankingTestForLowPoints extends LeaderboardSco Assert.assertEquals(4.0002, leaderboard.getNetPoints(medalCompetitors.get(1), later), EPSILON); Assert.assertEquals(6.0004, leaderboard.getNetPoints(medalCompetitors.get(2), later), EPSILON); Assert.assertEquals(8.0006, leaderboard.getNetPoints(medalCompetitors.get(3), later), EPSILON); - + List> afterFinalResults = createCompetitorResultForTimestamp(later, leaderboard); assertNonFinalistsAreBehindFinalistsAndNotChanged(preSeriesScoreRankResult, afterFinalResults); } @@ -516,7 +519,8 @@ public class LeaderboardScoringAndRankingTestForLowPoints extends LeaderboardSco List preSeriesRankResult = leaderboard.getCompetitorsFromBestToWorst(later); List medalCompetitorsBestToWorst = preSeriesRankResult.subList(0, 4); - List> preSeriesScoreRankResult = createCompetitorResultForTimestamp(later, leaderboard); + List> preSeriesScoreRankResult = createCompetitorResultForTimestamp(later, + leaderboard); manuallyTransferCarry(leaderboard, medalCompetitorsBestToWorst); Competitor preFirst = medalCompetitorsBestToWorst.get(0); @@ -560,7 +564,7 @@ public class LeaderboardScoringAndRankingTestForLowPoints extends LeaderboardSco Assert.assertEquals(8.0, leaderboard.getNetPoints(preFirst, m2later), EPSILON); Assert.assertEquals(12.0004, leaderboard.getNetPoints(preThird, m2later), EPSILON); Assert.assertEquals(16.0006, leaderboard.getNetPoints(preFourth, m2later), EPSILON); - + List> afterFinalResults = createCompetitorResultForTimestamp(m2later, leaderboard); assertNonFinalistsAreBehindFinalistsAndNotChanged(preSeriesScoreRankResult, afterFinalResults); } @@ -586,7 +590,8 @@ public class LeaderboardScoringAndRankingTestForLowPoints extends LeaderboardSco List preSeriesRankResult = leaderboard.getCompetitorsFromBestToWorst(later); List medalCompetitorsBestToWorst = preSeriesRankResult.subList(0, 4); - List> preSeriesScoreRankResult = createCompetitorResultForTimestamp(later, leaderboard); + List> preSeriesScoreRankResult = createCompetitorResultForTimestamp(later, + leaderboard); manuallyTransferCarry(leaderboard, medalCompetitorsBestToWorst); Competitor preFirst = medalCompetitorsBestToWorst.get(0); @@ -630,7 +635,7 @@ public class LeaderboardScoringAndRankingTestForLowPoints extends LeaderboardSco Assert.assertEquals(6.0002, leaderboard.getNetPoints(preSecond, m2later), EPSILON); Assert.assertEquals(12.0004, leaderboard.getNetPoints(preThird, m2later), EPSILON); Assert.assertEquals(16.0006, leaderboard.getNetPoints(preFourth, m2later), EPSILON); - + List> afterFinalResults = createCompetitorResultForTimestamp(m2later, leaderboard); assertNonFinalistsAreBehindFinalistsAndNotChanged(preSeriesScoreRankResult, afterFinalResults); } @@ -656,8 +661,9 @@ public class LeaderboardScoringAndRankingTestForLowPoints extends LeaderboardSco List preSeriesRankResult = leaderboard.getCompetitorsFromBestToWorst(later); List medalCompetitorsBestToWorst = preSeriesRankResult.subList(0, 4); - List> preSeriesScoreRankResult = createCompetitorResultForTimestamp(later, leaderboard); - + List> preSeriesScoreRankResult = createCompetitorResultForTimestamp(later, + leaderboard); + manuallyTransferCarry(leaderboard, medalCompetitorsBestToWorst); Competitor preFirst = medalCompetitorsBestToWorst.get(0); @@ -701,7 +707,7 @@ public class LeaderboardScoringAndRankingTestForLowPoints extends LeaderboardSco Assert.assertEquals(8.0, leaderboard.getNetPoints(preFirst, m2later), EPSILON); Assert.assertEquals(12.0002, leaderboard.getNetPoints(preSecond, m2later), EPSILON); Assert.assertEquals(16.0004, leaderboard.getNetPoints(preThird, m2later), EPSILON); - + List> afterFinalResults = createCompetitorResultForTimestamp(m2later, leaderboard); assertNonFinalistsAreBehindFinalistsAndNotChanged(preSeriesScoreRankResult, afterFinalResults); } @@ -727,7 +733,8 @@ public class LeaderboardScoringAndRankingTestForLowPoints extends LeaderboardSco List preSeriesRankResult = leaderboard.getCompetitorsFromBestToWorst(later); List medalCompetitorsBestToWorst = preSeriesRankResult.subList(0, 4); - List> preSeriesScoreRankResult = createCompetitorResultForTimestamp(later, leaderboard); + List> preSeriesScoreRankResult = createCompetitorResultForTimestamp(later, + leaderboard); manuallyTransferCarry(leaderboard, medalCompetitorsBestToWorst); Competitor preFirst = medalCompetitorsBestToWorst.get(0); @@ -771,9 +778,9 @@ public class LeaderboardScoringAndRankingTestForLowPoints extends LeaderboardSco Assert.assertEquals(8.0, leaderboard.getNetPoints(preFirst, m2later), EPSILON); Assert.assertEquals(12.0002, leaderboard.getNetPoints(preSecond, m2later), EPSILON); Assert.assertEquals(10.0004, leaderboard.getNetPoints(preThird, m2later), EPSILON); - + List> afterFinalResults = createCompetitorResultForTimestamp(m2later, leaderboard); assertNonFinalistsAreBehindFinalistsAndNotChanged(preSeriesScoreRankResult, afterFinalResults); } - + } diff --git a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/ScoringScheme.java b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/ScoringScheme.java index 0c9a4a468ce..b3d4e4545f3 100755 --- a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/ScoringScheme.java +++ b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/ScoringScheme.java @@ -138,16 +138,16 @@ public interface ScoringScheme extends Serializable { default boolean doesCountAsWinInMedalRace(Double o1Score, RaceColumn raceColumn) { 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 different - * from 1 or 2. For example, we've seen cases in the Extreme Sailing Series where the race committee defined that in the - * overall series leaderboard the last two columns each count 1.5 times their scores. + * 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 + * different from 1 or 2. For example, we've seen cases in the Extreme Sailing Series where the race committee + * defined that in the overall series leaderboard the last two columns each count 1.5 times their scores. */ default double getScoreFactor(RaceColumn a) { Double factor = a.getExplicitFactor(); - if(factor == null) { + if (factor == null) { factor = a.isMedalRace() ? DEFAULT_MEDAL_RACE_FACTOR : 1.0; } return factor; diff --git a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/impl/AbstractScoringSchemeImpl.java b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/impl/AbstractScoringSchemeImpl.java index 718fa625fa8..cf443cfb28c 100755 --- a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/impl/AbstractScoringSchemeImpl.java +++ b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/impl/AbstractScoringSchemeImpl.java @@ -129,11 +129,11 @@ public abstract class AbstractScoringSchemeImpl implements ScoringScheme { // needs to compare net points; therefore, divide the total points by the column factor for comparison: List o1NetScores = new ArrayList<>(); for (com.sap.sse.common.Util.Pair o1ColumnAndScore : o1Scores) { - o1NetScores.add(o1ColumnAndScore.getB()/getScoreFactor(o1ColumnAndScore.getA())); + o1NetScores.add(o1ColumnAndScore.getB() / getScoreFactor(o1ColumnAndScore.getA())); } List o2NetScores = new ArrayList<>(); for (com.sap.sse.common.Util.Pair o2ColumnAndScore : o2Scores) { - o2NetScores.add(o2ColumnAndScore.getB()/getScoreFactor(o2ColumnAndScore.getA())); + o2NetScores.add(o2ColumnAndScore.getB() / getScoreFactor(o2ColumnAndScore.getA())); } Collections.sort(o1NetScores, pureScoreComparator); Collections.sort(o2NetScores, pureScoreComparator); diff --git a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/impl/LeaderboardTotalRankComparator.java b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/impl/LeaderboardTotalRankComparator.java index 76b116bc44e..c39b1d123c2 100755 --- a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/impl/LeaderboardTotalRankComparator.java +++ b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/impl/LeaderboardTotalRankComparator.java @@ -211,8 +211,7 @@ public class LeaderboardTotalRankComparator implements Comparator { // break tie by sorting scores and looking for the first score difference. int result = compareByNumberOfRacesScored(o1Scores.size(), o2Scores.size()); if (result == 0) { - if(scoringScheme.isMedalWinAmountCriteria()) { - //FIXME somehere carry values must be obtained and added here, if compeitor was in carry + if (scoringScheme.isMedalWinAmountCriteria()) { result = compareByMedalRacesWon(numberOfMedalRacesWonO1, numberOfMedalRacesWonO2); } if (result == 0) { @@ -220,12 +219,15 @@ public class LeaderboardTotalRankComparator implements Comparator { if (result == 0) { result = compareByMedalRaceScore(o1MedalRaceScore, o2MedalRaceScore); if (result == 0) { - result = compareByBetterScore(o1, Collections.unmodifiableList(o1Scores), o2, Collections.unmodifiableList(o2Scores), timePoint); + result = compareByBetterScore(o1, Collections.unmodifiableList(o1Scores), o2, + Collections.unmodifiableList(o2Scores), timePoint); if (result == 0) { // compare by last race: - result = scoringScheme.compareByLastRace(o1TotalPoints, o2TotalPoints, nullScoresAreBetter, o1, o2); + result = scoringScheme.compareByLastRace(o1TotalPoints, o2TotalPoints, nullScoresAreBetter, + o1, o2); if (result == 0) { - result = scoringScheme.compareByLatestRegattaInMetaLeaderboard(getLeaderboard(), o1, o2, timePoint); + result = scoringScheme.compareByLatestRegattaInMetaLeaderboard(getLeaderboard(), o1, o2, + timePoint); if (result == 0) { result = compareByArbitraryButStableCriteria(o1, o2); } @@ -233,21 +235,22 @@ public class LeaderboardTotalRankComparator implements Comparator { } } } - }else { + } else { System.out.println("chjeck me"); } - + } return result; } private int compareByMedalRacesWon(int numberOfMedalRacesWonO1, int numberOfMedalRacesWonO2) { int targetAmount = scoringScheme.getTargetAmountOfMedalRaceWins(); - //if one reaches the targetamount, this has precendece, else proceed with normal low points scoring (eg not enough races yet) - if(numberOfMedalRacesWonO1 == targetAmount) { + // if one reaches the targetamount, this has priority, else proceed with normal low points scoring (eg. not + // enough races yet) + if (numberOfMedalRacesWonO1 == targetAmount) { return -1; } - if(numberOfMedalRacesWonO2 == targetAmount) { + if (numberOfMedalRacesWonO2 == targetAmount) { return 1; } return 0; diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/server/SailingServiceImpl.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/server/SailingServiceImpl.java index 0d0d0842737..432dd9d5058 100755 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/server/SailingServiceImpl.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/server/SailingServiceImpl.java @@ -2602,7 +2602,8 @@ public class SailingServiceImpl extends ProxiedRemoteServiceServlet implements S } } final FleetDTO fleetDTO = baseDomainFactory.convertToFleetDTO(fleet); - RaceColumnDTO raceColumnDTO = leaderboardDTO.addRace(raceColumn.getName(), raceColumn.getExplicitFactor(), leaderboard.getScoringScheme().getScoreFactor(raceColumn), + RaceColumnDTO raceColumnDTO = leaderboardDTO.addRace(raceColumn.getName(), + raceColumn.getExplicitFactor(), leaderboard.getScoringScheme().getScoreFactor(raceColumn), raceColumn instanceof RaceColumnInSeries ? ((RaceColumnInSeries) raceColumn).getRegatta().getName() : null, raceColumn instanceof RaceColumnInSeries ? ((RaceColumnInSeries) raceColumn).getSeries().getName() : null, fleetDTO, raceColumn.isMedalRace(), raceIdentifier, raceDTO, raceColumn instanceof MetaLeaderboardColumn); diff --git a/java/com.sap.sailing.server.gateway/src/com/sap/sailing/server/gateway/impl/rc/RaceGroupFactory.java b/java/com.sap.sailing.server.gateway/src/com/sap/sailing/server/gateway/impl/rc/RaceGroupFactory.java index e020041083e..fb6a755ff0d 100644 --- a/java/com.sap.sailing.server.gateway/src/com/sap/sailing/server/gateway/impl/rc/RaceGroupFactory.java +++ b/java/com.sap.sailing.server.gateway/src/com/sap/sailing/server/gateway/impl/rc/RaceGroupFactory.java @@ -75,8 +75,9 @@ public class RaceGroupFactory { Map> seriesToRaceColumns = getSeriesToRaceColumns(leaderboard); Collection seriesWithRows = new ArrayList<>(); for (Series series : getSeriesIterable(leaderboard, seriesToRaceColumns)) { - seriesWithRows.add(new SeriesWithRowsImpl(series.getName(), series.isMedal(), series.isFleetsCanRunInParallel(), getRows(series, - seriesToRaceColumns.get(series), leaderboard.getScoringScheme()))); + seriesWithRows + .add(new SeriesWithRowsImpl(series.getName(), series.isMedal(), series.isFleetsCanRunInParallel(), + getRows(series, seriesToRaceColumns.get(series), leaderboard.getScoringScheme()))); } return seriesWithRows; } @@ -90,15 +91,17 @@ public class RaceGroupFactory { } /** - * @param raceColumns must be provided in the same order in which they appear in the series / leaderboard - * @param scoringScheme + * @param raceColumns + * must be provided in the same order in which they appear in the series / leaderboard + * @param scoringScheme */ private Collection getRows(Series series, List raceColumns, ScoringScheme scoringScheme) { Collection rows = new ArrayList<>(); for (Fleet fleet : series.getFleets()) { // We are taking the fleet name because there might be several "default fleet" // objects when TrackedRaces are linked onto this Leaderboard - rows.add(new RaceRowImpl(fleet, getCells(fleet.getName(), raceColumns, isFirstRaceColumnVirtual(series), scoringScheme))); + rows.add(new RaceRowImpl(fleet, + getCells(fleet.getName(), raceColumns, isFirstRaceColumnVirtual(series), scoringScheme))); } return rows; } @@ -133,7 +136,8 @@ public class RaceGroupFactory { targetTime = null; } cells.add(new RaceCellImpl(raceColumn.getName(), raceColumn.getRaceLog(fleet), - scoringScheme.getScoreFactor(raceColumn), raceColumn.getExplicitFactor(), zeroBasedIndexOfRaceInFleet++, targetTime)); + scoringScheme.getScoreFactor(raceColumn), raceColumn.getExplicitFactor(), + zeroBasedIndexOfRaceInFleet++, targetTime)); } } } diff --git a/java/com.sap.sailing.server.test/src/com/sap/sailing/server/test/MasterDataImportTest.java b/java/com.sap.sailing.server.test/src/com/sap/sailing/server/test/MasterDataImportTest.java index ca21256b360..1c79016d831 100644 --- a/java/com.sap.sailing.server.test/src/com/sap/sailing/server/test/MasterDataImportTest.java +++ b/java/com.sap.sailing.server.test/src/com/sap/sailing/server/test/MasterDataImportTest.java @@ -423,10 +423,8 @@ public class MasterDataImportTest { scoreCorrection, leaderboardOnTarget.getScoreCorrection().getExplicitScoreCorrection(competitorOnTarget, raceColumnOnTarget)); - Assert.assertEquals( - maxPointsReason, - leaderboardOnTarget.getScoreCorrection().getMaxPointsReason(competitorOnTarget, raceColumnOnTarget, - MillisecondsTimePoint.now())); + Assert.assertEquals(maxPointsReason, leaderboardOnTarget.getScoreCorrection() + .getMaxPointsReason(competitorOnTarget, raceColumnOnTarget, MillisecondsTimePoint.now())); // Check for carried points Assert.assertEquals(carriedPoints, leaderboardOnTarget.getCarriedPoints(competitorOnTarget)); @@ -2296,10 +2294,8 @@ public class MasterDataImportTest { scoreCorrection, leaderboardOnTarget.getScoreCorrection().getExplicitScoreCorrection(competitorOnTarget, raceColumnOnTarget)); - Assert.assertEquals( - maxPointsReason, - leaderboardOnTarget.getScoreCorrection().getMaxPointsReason(competitorOnTarget, raceColumnOnTarget, - MillisecondsTimePoint.now())); + Assert.assertEquals(maxPointsReason, leaderboardOnTarget.getScoreCorrection() + .getMaxPointsReason(competitorOnTarget, raceColumnOnTarget, MillisecondsTimePoint.now())); // Check for carried points Assert.assertEquals(carriedPoints, leaderboardOnTarget.getCarriedPoints(competitorOnTarget)); From 9c067f321b19e21d930ff98ae8714170ea55e98b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kai=20B=C3=B6rnert?= Date: Tue, 17 Jul 2018 10:34:40 +0200 Subject: [PATCH 12/43] bug4661 added score scheme descriptions --- .../java/com/sap/sailing/gwt/ui/client/StringMessages.java | 1 + .../com/sap/sailing/gwt/ui/client/StringMessages.properties | 3 ++- .../com/sap/sailing/gwt/ui/client/StringMessages_de.properties | 2 ++ .../sailing/gwt/ui/leaderboard/ScoringSchemeTypeFormatter.java | 2 ++ 4 files changed, 7 insertions(+), 1 deletion(-) diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/StringMessages.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/StringMessages.java index 6e86ff570e1..74a2e96a87c 100755 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/StringMessages.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/StringMessages.java @@ -435,6 +435,7 @@ public interface StringMessages extends com.sap.sse.gwt.client.StringMessages, String addGate(); String scoringSchemeLowPointSystem(); String scoringSchemeLowPointSystemFirstTwoWins(); + String scoringSchemeLowPointSystemFirstTwoWinsDescription(); String scoringSchemeHighPointSystem(); String scoringSchemeLowPointWinnerGetsZero(); String scoringSchemeWinnerGetsFive(); diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/StringMessages.properties b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/StringMessages.properties index de4510c4480..811466f1f48 100755 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/StringMessages.properties +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/StringMessages.properties @@ -484,7 +484,8 @@ scoringSchemeHighPointFirstGetsTwelveOrEight=High Point, winner gets 12 points ( scoringSchemeHighPointFirstGetsTwelveOrEightDescription=Score in points. Winner scores 12 points, 2nd - 11 points, .... A tie is broken in favour of the competitor with the highest score, if tie remains then tie is broken by the rank in the last race scored. scoringSchemeHighPointFirstGetsTwelveOrEight2017=High Point ESS 2017, winner gets 12 points (or 8) scoringSchemeHighPointFirstGetsTwelveOrEight2017Description=Score in points. Winner scores 12 points, 2nd - 11 points, .... A tie is broken in favour of the competitor with the highest score, if tie remains then tie is broken by the rank in the last race scored. -scoringSchemeLowPointSystemFirstTwoWins=Low Point System, First two wins +scoringSchemeLowPointSystemFirstTwoWins=Low Point System, First two wins is winner +scoringSchemeLowPointSystemFirstTwoWinsDescription=Low Point System. The first in the medal series to win two races wins the medal series. Being the best in the pre medal series counts as one win for this. scoringSystem=Scoring system createFlexibleLeaderboard=Create flexible leaderboard createRegattaLeaderboard=Create regatta leaderboard diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/StringMessages_de.properties b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/StringMessages_de.properties index e3b9c942808..8922d4a86dd 100755 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/StringMessages_de.properties +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/StringMessages_de.properties @@ -474,6 +474,8 @@ scoringSchemeLowPointForLeagueOverallLeaderboardDescription=Bei Punktegleichstan scoringSchemeLowPointTieBreakBasedOnLastSeriesOnly=Low Point System, bei Punktegleichstand zählt letzten Serie scoringSchemeLowPointTieBreakBasedOnLastSeriesOnlyDescription=Bei Punktegleichstand entscheidet die Punktesumme aller (auch der gestrichenen) Wettfahrten der letzten Serie scoringSchemeLowPointWithAutomaticRdg=Low Point System, RDG erhält Durchschnitt aller nicht-RDG-Wertungen als Vorschlag +scoringSchemeLowPointSystemFirstTwoWins=Low Point System, Erster mit zwei Siegen +scoringSchemeLowPointSystemFirstTwoWinsDescription=Low Point System. Der Erste der zwei Rennen in der Medal-Serie gewinnt, zählt als Sieger der Medal-Serie. Der Beste der Vorserien bekommt hierfür einen Sieg angerechnet. scoringSystem=Bepunktungssystem createFlexibleLeaderboard=Flexible Rangliste anlegen createRegattaLeaderboard=Rangliste für Regatta anlegen diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/leaderboard/ScoringSchemeTypeFormatter.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/leaderboard/ScoringSchemeTypeFormatter.java index 57bb7c5b241..b5ad2383a81 100644 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/leaderboard/ScoringSchemeTypeFormatter.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/leaderboard/ScoringSchemeTypeFormatter.java @@ -74,6 +74,8 @@ public class ScoringSchemeTypeFormatter { return stringMessages.scoringSchemeHighPointMatchRacingDescription(); case LOW_POINT_TIE_BREAK_BASED_ON_LAST_SERIES_ONLY: return stringMessages.scoringSchemeLowPointTieBreakBasedOnLastSeriesOnlyDescription(); + case LOW_POINT_FIRST_TO_WIN_TWO_RACES: + return stringMessages.scoringSchemeLowPointSystemFirstTwoWinsDescription(); default: return format(scoringSchemeType, stringMessages); } From 84fd1a0a8312218bfb7c645d2985faa90eb5ae03 Mon Sep 17 00:00:00 2001 From: Steffen Schaefer Date: Tue, 17 Jul 2018 14:29:04 +0200 Subject: [PATCH 13/43] Bug 4661: Optimized messages --- .../com/sap/sailing/gwt/ui/client/StringMessages.properties | 2 +- .../sap/sailing/gwt/ui/client/StringMessages_de.properties | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/StringMessages.properties b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/StringMessages.properties index 811466f1f48..f3eeb8da0de 100755 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/StringMessages.properties +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/StringMessages.properties @@ -484,7 +484,7 @@ scoringSchemeHighPointFirstGetsTwelveOrEight=High Point, winner gets 12 points ( scoringSchemeHighPointFirstGetsTwelveOrEightDescription=Score in points. Winner scores 12 points, 2nd - 11 points, .... A tie is broken in favour of the competitor with the highest score, if tie remains then tie is broken by the rank in the last race scored. scoringSchemeHighPointFirstGetsTwelveOrEight2017=High Point ESS 2017, winner gets 12 points (or 8) scoringSchemeHighPointFirstGetsTwelveOrEight2017Description=Score in points. Winner scores 12 points, 2nd - 11 points, .... A tie is broken in favour of the competitor with the highest score, if tie remains then tie is broken by the rank in the last race scored. -scoringSchemeLowPointSystemFirstTwoWins=Low Point System, First two wins is winner +scoringSchemeLowPointSystemFirstTwoWins=Low Point System, First with two wins in medals is winner scoringSchemeLowPointSystemFirstTwoWinsDescription=Low Point System. The first in the medal series to win two races wins the medal series. Being the best in the pre medal series counts as one win for this. scoringSystem=Scoring system createFlexibleLeaderboard=Create flexible leaderboard diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/StringMessages_de.properties b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/StringMessages_de.properties index 8922d4a86dd..796a208cbe3 100755 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/StringMessages_de.properties +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/StringMessages_de.properties @@ -474,8 +474,8 @@ scoringSchemeLowPointForLeagueOverallLeaderboardDescription=Bei Punktegleichstan scoringSchemeLowPointTieBreakBasedOnLastSeriesOnly=Low Point System, bei Punktegleichstand zählt letzten Serie scoringSchemeLowPointTieBreakBasedOnLastSeriesOnlyDescription=Bei Punktegleichstand entscheidet die Punktesumme aller (auch der gestrichenen) Wettfahrten der letzten Serie scoringSchemeLowPointWithAutomaticRdg=Low Point System, RDG erhält Durchschnitt aller nicht-RDG-Wertungen als Vorschlag -scoringSchemeLowPointSystemFirstTwoWins=Low Point System, Erster mit zwei Siegen -scoringSchemeLowPointSystemFirstTwoWinsDescription=Low Point System. Der Erste der zwei Rennen in der Medal-Serie gewinnt, zählt als Sieger der Medal-Serie. Der Beste der Vorserien bekommt hierfür einen Sieg angerechnet. +scoringSchemeLowPointSystemFirstTwoWins=Low Point System, Erster mit zwei Siegen in Medals gewinnt +scoringSchemeLowPointSystemFirstTwoWinsDescription=Low Point System. Der Erste, der zwei Rennen in der Medal-Serie gewinnt, zählt als Sieger der Medal-Serie. Der Beste der Vorserien bekommt einen zusätzlichen Sieg angerechnet. scoringSystem=Bepunktungssystem createFlexibleLeaderboard=Flexible Rangliste anlegen createRegattaLeaderboard=Rangliste für Regatta anlegen From 3211caf970939f69ef2f4dcc020943b5d483fc7d Mon Sep 17 00:00:00 2001 From: Steffen Schaefer Date: Tue, 17 Jul 2018 14:39:46 +0200 Subject: [PATCH 14/43] Bug 4661: Code formatting --- .../leaderboard/impl/LeaderboardTotalRankComparator.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/impl/LeaderboardTotalRankComparator.java b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/impl/LeaderboardTotalRankComparator.java index c39b1d123c2..95d693c8c90 100755 --- a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/impl/LeaderboardTotalRankComparator.java +++ b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/impl/LeaderboardTotalRankComparator.java @@ -184,9 +184,9 @@ public class LeaderboardTotalRankComparator implements Comparator { // similar to compareByFleet, however, tracking is not required; having medal race column points // (tracked or manual) is sufficient preemptiveColumnResult = compareByMedalRaceParticipation(o1Score, o2Score); - if(scoringScheme.isMedalWinAmountCriteria()) { - numberOfMedalRacesWonO1+= scoringScheme.doesCountAsWinInMedalRace(o1Score, raceColumn) ? 1:0; - numberOfMedalRacesWonO2+= scoringScheme.doesCountAsWinInMedalRace(o2Score, raceColumn) ? 1:0; + if (scoringScheme.isMedalWinAmountCriteria()) { + numberOfMedalRacesWonO1 += scoringScheme.doesCountAsWinInMedalRace(o1Score, raceColumn) ? 1 : 0; + numberOfMedalRacesWonO2 += scoringScheme.doesCountAsWinInMedalRace(o2Score, raceColumn) ? 1 : 0; } } if (preemptiveColumnResult == 0 && raceColumn.isTotalOrderDefinedByFleet()) { From da0ad9d1c861b4d3b6b3c270188629e0cec0df97 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kai=20B=C3=B6rnert?= Date: Tue, 17 Jul 2018 15:29:54 +0200 Subject: [PATCH 15/43] bug4661 added javadoc to tests --- ...oardScoringAndRankingTestForLowPoints.java | 46 +++++++++++++++++++ 1 file changed, 46 insertions(+) diff --git a/java/com.sap.sailing.domain.test/src/com/sap/sailing/domain/test/LeaderboardScoringAndRankingTestForLowPoints.java b/java/com.sap.sailing.domain.test/src/com/sap/sailing/domain/test/LeaderboardScoringAndRankingTestForLowPoints.java index 7f79f909480..d801a072844 100644 --- a/java/com.sap.sailing.domain.test/src/com/sap/sailing/domain/test/LeaderboardScoringAndRankingTestForLowPoints.java +++ b/java/com.sap.sailing.domain.test/src/com/sap/sailing/domain/test/LeaderboardScoringAndRankingTestForLowPoints.java @@ -30,6 +30,12 @@ import com.sap.sse.common.impl.MillisecondsTimePoint; import junit.framework.Assert; +/** + * This class contains several Tests for the first two victories in medal series rule in the LOW_POINT_FIRST_TO_WIN_TWO_RACES scheme. + * It tests that the carry is correctly applied and that the ordering is as expected. + * Furthermore it contains seeral negative tests, that validate, that the normal low point behaviour is not changed and still works for those same cases in case the LOW_POINT scoringscheme is used. + * + */ public class LeaderboardScoringAndRankingTestForLowPoints extends LeaderboardScoringAndRankingTestBase { private static final double EPSILON = 0.000001; @@ -113,6 +119,11 @@ public class LeaderboardScoringAndRankingTestForLowPoints extends LeaderboardSco } @Test + /** + * In this test the preseries 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 + */ public void testFirstPreseriesWinsAgain() throws NoWindException { series = new ArrayList(); setupQualificationSeriesWithOneRaceColumn(); @@ -164,6 +175,11 @@ public class LeaderboardScoringAndRankingTestForLowPoints extends LeaderboardSco } @Test + /** + * In this test the second best in the preseries wins the first two medal races, 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 + */ public void testSecondPreSeriesWinsTwice() throws NoWindException { series = new ArrayList(); // -------- qualification series ------------ @@ -235,6 +251,11 @@ public class LeaderboardScoringAndRankingTestForLowPoints extends LeaderboardSco } @Test + /** + * In this test the best in the preseries wins the first second medal races, 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 + */ public void testFirstWinsSecondRace() throws NoWindException { series = new ArrayList(); // -------- qualification series ------------ @@ -306,6 +327,11 @@ public class LeaderboardScoringAndRankingTestForLowPoints extends LeaderboardSco } @Test + /** + * In this test the worst finalist the first and second medal races, 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 + */ public void testLastWinsTwoRaces() throws NoWindException { series = new ArrayList(); // -------- qualification series ------------ @@ -377,6 +403,11 @@ public class LeaderboardScoringAndRankingTestForLowPoints extends LeaderboardSco } @Test + /** + * In this test the no finalist reaches two wins before terminating (eg. due to bad weather) all finalists + * should be scored with Low_Points restarting at 0 for the medal series The non finalists score should not change + * during the medalseries. + */ public void noTwoWinsAbortAfterTwoRacesAndTieBraker() throws NoWindException { series = new ArrayList(); // -------- qualification series ------------ @@ -448,6 +479,9 @@ public class LeaderboardScoringAndRankingTestForLowPoints extends LeaderboardSco } @Test + /** + * Using normal lowpoints, having two wins should not matter, also the racecolum factor is expected to be 2 instead of 1 + */ public void negativeTestFirstPreseriesWinsAgain() throws NoWindException { series = new ArrayList(); setupQualificationSeriesWithOneRaceColumn(); @@ -499,6 +533,9 @@ public class LeaderboardScoringAndRankingTestForLowPoints extends LeaderboardSco } @Test + /** + * Using normal lowpoints, having two wins should not matter, also the racecolum factor is expected to be 2 instead of 1 + */ public void negativeTestSecondPreSeriesWinsTwice() throws NoWindException { series = new ArrayList(); // -------- qualification series ------------ @@ -570,6 +607,9 @@ public class LeaderboardScoringAndRankingTestForLowPoints extends LeaderboardSco } @Test + /** + * Using normal lowpoints, having two wins should not matter, also the racecolum factor is expected to be 2 instead of 1 + */ public void negativeTestFirstWinsSecondRace() throws NoWindException { series = new ArrayList(); // -------- qualification series ------------ @@ -641,6 +681,9 @@ public class LeaderboardScoringAndRankingTestForLowPoints extends LeaderboardSco } @Test + /** + * Using normal lowpoints, the racecolum factor is expected to be 2 instead of 1 + */ public void negativeTestLastWinsTwoRaces() throws NoWindException { series = new ArrayList(); // -------- qualification series ------------ @@ -713,6 +756,9 @@ public class LeaderboardScoringAndRankingTestForLowPoints extends LeaderboardSco } @Test + /** + * Using normal lowpoints, tie braking is done with manual carry decimals + */ public void negativeNoTwoWinsAbortAfterTwoRacesAndTieBraker() throws NoWindException { series = new ArrayList(); // -------- qualification series ------------ From a0f6b24191c2c61d29860477a7312260b70888b2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kai=20B=C3=B6rnert?= Date: Tue, 17 Jul 2018 16:02:35 +0200 Subject: [PATCH 16/43] bug4661 moved amount of races won score to scoring scheme --- .../com/sap/sailing/domain/leaderboard/ScoringScheme.java | 4 ++++ .../leaderboard/impl/AbstractSimpleLeaderboardImpl.java | 2 +- .../domain/leaderboard/impl/LowPointFirstToWinTwoRaces.java | 5 +++++ 3 files changed, 10 insertions(+), 1 deletion(-) diff --git a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/ScoringScheme.java b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/ScoringScheme.java index b3d4e4545f3..11643668747 100755 --- a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/ScoringScheme.java +++ b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/ScoringScheme.java @@ -152,4 +152,8 @@ public interface ScoringScheme extends Serializable { } return factor; } + + default double getTargetAmountOfMedalRaceWinsScore() { + throw new IllegalStateException("This call is not valid for this scoringSheme"); + }; } diff --git a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/impl/AbstractSimpleLeaderboardImpl.java b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/impl/AbstractSimpleLeaderboardImpl.java index 9fa4963779f..3aa7688a5b6 100644 --- a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/impl/AbstractSimpleLeaderboardImpl.java +++ b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/impl/AbstractSimpleLeaderboardImpl.java @@ -517,7 +517,7 @@ public abstract class AbstractSimpleLeaderboardImpl extends AbstractLeaderboardW } if (getScoringScheme().isMedalWinAmountCriteria()) { if (wonRaces == getScoringScheme().getTargetAmountOfMedalRaceWins()) { - return 2.0; + return getScoringScheme().getTargetAmountOfMedalRaceWinsScore(); } } return result; diff --git a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/impl/LowPointFirstToWinTwoRaces.java b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/impl/LowPointFirstToWinTwoRaces.java index 56138b13d0f..b89622666c1 100644 --- a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/impl/LowPointFirstToWinTwoRaces.java +++ b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/impl/LowPointFirstToWinTwoRaces.java @@ -40,4 +40,9 @@ public class LowPointFirstToWinTwoRaces extends LowPoint { return factor; } + @Override + public double getTargetAmountOfMedalRaceWinsScore() { + return 2.0; + } + } From 6d5cd22980aca8fe710cf7e947b87983fc1511be Mon Sep 17 00:00:00 2001 From: Steffen Schaefer Date: Tue, 17 Jul 2018 16:33:37 +0200 Subject: [PATCH 17/43] Bug 4661: JavaDoc improvements --- ...oardScoringAndRankingTestForLowPoints.java | 71 ++++++++++--------- 1 file changed, 38 insertions(+), 33 deletions(-) diff --git a/java/com.sap.sailing.domain.test/src/com/sap/sailing/domain/test/LeaderboardScoringAndRankingTestForLowPoints.java b/java/com.sap.sailing.domain.test/src/com/sap/sailing/domain/test/LeaderboardScoringAndRankingTestForLowPoints.java index d801a072844..0c953070991 100644 --- a/java/com.sap.sailing.domain.test/src/com/sap/sailing/domain/test/LeaderboardScoringAndRankingTestForLowPoints.java +++ b/java/com.sap.sailing.domain.test/src/com/sap/sailing/domain/test/LeaderboardScoringAndRankingTestForLowPoints.java @@ -21,6 +21,7 @@ import com.sap.sailing.domain.common.NoWindException; import com.sap.sailing.domain.common.ScoringSchemeType; import com.sap.sailing.domain.leaderboard.Leaderboard; import com.sap.sailing.domain.leaderboard.impl.DelegatingRegattaLeaderboardWithCompetitorElimination; +import com.sap.sailing.domain.leaderboard.impl.LowPointFirstToWinTwoRaces; import com.sap.sailing.domain.ranking.OneDesignRankingMetric; import com.sap.sailing.domain.test.mock.MockedTrackedRaceWithStartTimeAndRanks; import com.sap.sailing.domain.tracking.TrackedRace; @@ -31,10 +32,11 @@ import com.sap.sse.common.impl.MillisecondsTimePoint; import junit.framework.Assert; /** - * This class contains several Tests for the first two victories in medal series rule in the LOW_POINT_FIRST_TO_WIN_TWO_RACES scheme. - * It tests that the carry is correctly applied and that the ordering is as expected. - * Furthermore it contains seeral negative tests, that validate, that the normal low point behaviour is not changed and still works for those same cases in case the LOW_POINT scoringscheme is used. - * + * This class contains several tests for the {@link LowPointFirstToWinTwoRaces} scoring rule defined by + * {@link ScoringSchemeType#LOW_POINT_FIRST_TO_WIN_TWO_RACES}. It tests that the carry is correctly applied and that the + * ordering is as expected. Furthermore it contains several negative tests, that validate, that the normal low point + * behavior is not changed and still works for those same cases in case the {@link ScoringSchemeType#LOW_POINT} scoring + * scheme is used. */ public class LeaderboardScoringAndRankingTestForLowPoints extends LeaderboardScoringAndRankingTestBase { private static final double EPSILON = 0.000001; @@ -118,12 +120,12 @@ public class LeaderboardScoringAndRankingTestForLowPoints extends LeaderboardSco Assert.assertEquals(nonFinalistsPreScore, nonFinalistsAfterScore); } - @Test /** * In this test the preseries 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 + * 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 testFirstPreseriesWinsAgain() throws NoWindException { series = new ArrayList(); setupQualificationSeriesWithOneRaceColumn(); @@ -174,12 +176,12 @@ public class LeaderboardScoringAndRankingTestForLowPoints extends LeaderboardSco assertNonFinalistsAreBehindFinalistsAndNotChanged(preSeriesScoreRankResult, afterFinalResults); } - @Test /** - * In this test the second best in the preseries wins the first two medal races, 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 + * In this test the second best in the preseries wins the first two medal races, 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 testSecondPreSeriesWinsTwice() throws NoWindException { series = new ArrayList(); // -------- qualification series ------------ @@ -250,12 +252,12 @@ public class LeaderboardScoringAndRankingTestForLowPoints extends LeaderboardSco assertNonFinalistsAreBehindFinalistsAndNotChanged(preSeriesScoreRankResult, afterFinalResults); } - @Test /** - * In this test the best in the preseries wins the first second medal races, 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 + * In this test the best in the preseries wins the second medal 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 testFirstWinsSecondRace() throws NoWindException { series = new ArrayList(); // -------- qualification series ------------ @@ -326,12 +328,12 @@ public class LeaderboardScoringAndRankingTestForLowPoints extends LeaderboardSco assertNonFinalistsAreBehindFinalistsAndNotChanged(preSeriesScoreRankResult, afterFinalResults); } - @Test /** - * In this test the worst finalist the first and second medal races, 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 + * In this test the worst finalist of the qualification wins the first and second medal races, 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 testLastWinsTwoRaces() throws NoWindException { series = new ArrayList(); // -------- qualification series ------------ @@ -402,12 +404,12 @@ public class LeaderboardScoringAndRankingTestForLowPoints extends LeaderboardSco assertNonFinalistsAreBehindFinalistsAndNotChanged(preSeriesScoreRankResult, afterFinalResults); } - @Test /** - * In this test the no finalist reaches two wins before terminating (eg. due to bad weather) all finalists - * should be scored with Low_Points restarting at 0 for the medal series The non finalists score should not change - * during the medalseries. + * In this test the no finalist reaches two wins before terminating (eg. due to bad weather) all 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 noTwoWinsAbortAfterTwoRacesAndTieBraker() throws NoWindException { series = new ArrayList(); // -------- qualification series ------------ @@ -478,10 +480,11 @@ public class LeaderboardScoringAndRankingTestForLowPoints extends LeaderboardSco assertNonFinalistsAreBehindFinalistsAndNotChanged(preSeriesScoreRankResult, afterFinalResults); } - @Test /** - * Using normal lowpoints, having two wins should not matter, also the racecolum factor is expected to be 2 instead of 1 + * Using normal lowpoints, having two wins should not matter, also the racecolum factor is expected to be 2 instead + * of 1. */ + @Test public void negativeTestFirstPreseriesWinsAgain() throws NoWindException { series = new ArrayList(); setupQualificationSeriesWithOneRaceColumn(); @@ -532,10 +535,11 @@ public class LeaderboardScoringAndRankingTestForLowPoints extends LeaderboardSco assertNonFinalistsAreBehindFinalistsAndNotChanged(preSeriesScoreRankResult, afterFinalResults); } - @Test /** - * Using normal lowpoints, having two wins should not matter, also the racecolum factor is expected to be 2 instead of 1 + * Using normal lowpoints, having two wins should not matter, also the racecolum factor is expected to be 2 instead + * of 1. */ + @Test public void negativeTestSecondPreSeriesWinsTwice() throws NoWindException { series = new ArrayList(); // -------- qualification series ------------ @@ -606,10 +610,11 @@ public class LeaderboardScoringAndRankingTestForLowPoints extends LeaderboardSco assertNonFinalistsAreBehindFinalistsAndNotChanged(preSeriesScoreRankResult, afterFinalResults); } - @Test /** - * Using normal lowpoints, having two wins should not matter, also the racecolum factor is expected to be 2 instead of 1 + * Using normal lowpoints, having two wins should not matter, also the racecolum factor is expected to be 2 instead + * of 1. */ + @Test public void negativeTestFirstWinsSecondRace() throws NoWindException { series = new ArrayList(); // -------- qualification series ------------ @@ -680,10 +685,10 @@ public class LeaderboardScoringAndRankingTestForLowPoints extends LeaderboardSco assertNonFinalistsAreBehindFinalistsAndNotChanged(preSeriesScoreRankResult, afterFinalResults); } - @Test /** - * Using normal lowpoints, the racecolum factor is expected to be 2 instead of 1 + * Using normal lowpoints, the racecolum factor is expected to be 2 instead of 1. */ + @Test public void negativeTestLastWinsTwoRaces() throws NoWindException { series = new ArrayList(); // -------- qualification series ------------ @@ -755,10 +760,10 @@ public class LeaderboardScoringAndRankingTestForLowPoints extends LeaderboardSco assertNonFinalistsAreBehindFinalistsAndNotChanged(preSeriesScoreRankResult, afterFinalResults); } - @Test /** - * Using normal lowpoints, tie braking is done with manual carry decimals + * Using normal lowpoints, tie braking is done with manual carry decimals. */ + @Test public void negativeNoTwoWinsAbortAfterTwoRacesAndTieBraker() throws NoWindException { series = new ArrayList(); // -------- qualification series ------------ From 33617799a1fad30eb4238bd7d19d4abb41f46e7f Mon Sep 17 00:00:00 2001 From: Steffen Schaefer Date: Wed, 18 Jul 2018 09:15:05 +0200 Subject: [PATCH 18/43] Bug 4652: Implemented the possibility to rank competitors by carry forward and the last race in medal series --- .../domain/leaderboard/ScoringScheme.java | 8 +++ .../impl/LeaderboardTotalRankComparator.java | 52 +++++++++++++++---- .../impl/LowPointFirstToWinTwoRaces.java | 10 ++++ 3 files changed, 61 insertions(+), 9 deletions(-) diff --git a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/ScoringScheme.java b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/ScoringScheme.java index 11643668747..d0ebf66b631 100755 --- a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/ScoringScheme.java +++ b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/ScoringScheme.java @@ -130,6 +130,14 @@ public interface ScoringScheme extends Serializable { default boolean isMedalWinAmountCriteria() { return false; } + + default boolean isCarryForwardInMedalsCriteria() { + return false; + } + + default boolean isLastMedalRaceCriteria() { + return false; + } default int getTargetAmountOfMedalRaceWins() { throw new IllegalStateException("This call is not valid for this scoringSheme"); diff --git a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/impl/LeaderboardTotalRankComparator.java b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/impl/LeaderboardTotalRankComparator.java index 95d693c8c90..8db952ab923 100755 --- a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/impl/LeaderboardTotalRankComparator.java +++ b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/impl/LeaderboardTotalRankComparator.java @@ -111,6 +111,10 @@ public class LeaderboardTotalRankComparator implements Comparator { double o2ScoreSum = getLeaderboard().getCarriedPoints(o2); Double o1MedalRaceScore = 0.0; Double o2MedalRaceScore = 0.0; + Double o1CarryForwardScoreInMedals = null; + Double o2CarryForwardScoreInMedals = null; + Double o1LastMedalScore = null; + Double o2LastMedalScore = null; // When a column has isStartsWithZeroScore, the competitor's score only need to be reset to zero if from there on // the competitor scored in this or any subsequent columns boolean needToResetO1ScoreUponNextValidResult = false; @@ -180,6 +184,13 @@ public class LeaderboardTotalRankComparator implements Comparator { if (o2Score != null) { o2MedalRaceScore += o2Score; } + if (o1Score != null || o2Score != null) { + o1LastMedalScore = o1Score; + o2LastMedalScore = o2Score; + } + } else { + o1CarryForwardScoreInMedals = o1Score; + o2CarryForwardScoreInMedals = o2Score; } // similar to compareByFleet, however, tracking is not required; having medal race column points // (tracked or manual) is sufficient @@ -217,19 +228,29 @@ public class LeaderboardTotalRankComparator implements Comparator { if (result == 0) { result = compareByScoreSum(o1ScoreSum, o2ScoreSum); if (result == 0) { - result = compareByMedalRaceScore(o1MedalRaceScore, o2MedalRaceScore); + if (scoringScheme.isCarryForwardInMedalsCriteria()) { + result = compareBySingleRaceColumnScore(o1CarryForwardScoreInMedals, o2CarryForwardScoreInMedals); + } if (result == 0) { - result = compareByBetterScore(o1, Collections.unmodifiableList(o1Scores), o2, - Collections.unmodifiableList(o2Scores), timePoint); + if (scoringScheme.isLastMedalRaceCriteria()) { + result = compareBySingleRaceColumnScore(o1LastMedalScore, o2LastMedalScore); + } if (result == 0) { - // compare by last race: - result = scoringScheme.compareByLastRace(o1TotalPoints, o2TotalPoints, nullScoresAreBetter, - o1, o2); + result = compareByMedalRaceScore(o1MedalRaceScore, o2MedalRaceScore); if (result == 0) { - result = scoringScheme.compareByLatestRegattaInMetaLeaderboard(getLeaderboard(), o1, o2, - timePoint); + result = compareByBetterScore(o1, Collections.unmodifiableList(o1Scores), o2, + Collections.unmodifiableList(o2Scores), timePoint); if (result == 0) { - result = compareByArbitraryButStableCriteria(o1, o2); + // compare by last race: + result = scoringScheme.compareByLastRace(o1TotalPoints, o2TotalPoints, nullScoresAreBetter, + o1, o2); + if (result == 0) { + result = scoringScheme.compareByLatestRegattaInMetaLeaderboard(getLeaderboard(), o1, o2, + timePoint); + if (result == 0) { + result = compareByArbitraryButStableCriteria(o1, o2); + } + } } } } @@ -255,6 +276,19 @@ public class LeaderboardTotalRankComparator implements Comparator { } return 0; } + + private int compareBySingleRaceColumnScore(Double o1CarryForwardInMedals, Double o2CarryForwardInMedals) { + if (o1CarryForwardInMedals == null && o2CarryForwardInMedals == null) { + return 0; + } + if (o1CarryForwardInMedals == null) { + return 1; + } + if (o2CarryForwardInMedals == null) { + return -1; + } + return getScoreComparator().compare(o1CarryForwardInMedals, o2CarryForwardInMedals); + } private int compareByArbitraryButStableCriteria(Competitor o1, Competitor o2) { return o1.getName().compareTo(o2.getName()); diff --git a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/impl/LowPointFirstToWinTwoRaces.java b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/impl/LowPointFirstToWinTwoRaces.java index b89622666c1..e553fe4aece 100644 --- a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/impl/LowPointFirstToWinTwoRaces.java +++ b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/impl/LowPointFirstToWinTwoRaces.java @@ -16,6 +16,16 @@ public class LowPointFirstToWinTwoRaces extends LowPoint { return true; } + @Override + public boolean isCarryForwardInMedalsCriteria() { + return true; + } + + @Override + public boolean isLastMedalRaceCriteria() { + return true; + } + @Override public int getTargetAmountOfMedalRaceWins() { return 2; From 7c94812594b94a359b37cf55ee782ea87a7e9302 Mon Sep 17 00:00:00 2001 From: Steffen Schaefer Date: Wed, 18 Jul 2018 09:15:26 +0200 Subject: [PATCH 19/43] Bug 4652: Removed temporary debug logging --- .../leaderboard/impl/LeaderboardTotalRankComparator.java | 3 --- 1 file changed, 3 deletions(-) diff --git a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/impl/LeaderboardTotalRankComparator.java b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/impl/LeaderboardTotalRankComparator.java index 8db952ab923..bb3f59f37ed 100755 --- a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/impl/LeaderboardTotalRankComparator.java +++ b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/impl/LeaderboardTotalRankComparator.java @@ -256,10 +256,7 @@ public class LeaderboardTotalRankComparator implements Comparator { } } } - } else { - System.out.println("chjeck me"); } - } return result; } From 2c5a5f0c7b70a3c4fd827a10ef63a1b5e89e4e05 Mon Sep 17 00:00:00 2001 From: Steffen Schaefer Date: Wed, 18 Jul 2018 10:18:04 +0200 Subject: [PATCH 20/43] Bug 4661: Added JavaDocs --- .../sailing/domain/leaderboard/ScoringScheme.java | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/ScoringScheme.java b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/ScoringScheme.java index d0ebf66b631..815014eaeac 100755 --- a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/ScoringScheme.java +++ b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/ScoringScheme.java @@ -127,14 +127,26 @@ public interface ScoringScheme extends Serializable { */ int compareByLatestRegattaInMetaLeaderboard(Leaderboard leaderboard, Competitor o1, Competitor o2, TimePoint timePoint); + /** + * Returning {@code true} makes the number of wins in a medal series the primary ranking criteria. + * The number of wins that makes a competitor the overall winner must be returned by {@link #getTargetAmountOfMedalRaceWins()}. + */ default boolean isMedalWinAmountCriteria() { return false; } + /** + * Returning {@code true} makes the carry forward score a secondary ranking criteria for competitors that have an + * equal overall score. + */ default boolean isCarryForwardInMedalsCriteria() { return false; } + /** + * Returning {@code true} makes the last medal race (having valid scores) a secondary ranking criteria for + * competitors that have an equal overall score. + */ default boolean isLastMedalRaceCriteria() { return false; } From 4fb7b460a046f9437ae0c932e392bd60e226107e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kai=20B=C3=B6rnert?= Date: Wed, 18 Jul 2018 10:56:34 +0200 Subject: [PATCH 21/43] bug4661 test simplification due to removed decimals/ manual tie braking. Added tests that check that automatic tie braking is not changed for lowpoint and changed for new scheme --- ...oardScoringAndRankingTestForLowPoints.java | 184 +++++++++++------- .../impl/LowPointFirstToWinTwoRaces.java | 2 +- 2 files changed, 112 insertions(+), 74 deletions(-) diff --git a/java/com.sap.sailing.domain.test/src/com/sap/sailing/domain/test/LeaderboardScoringAndRankingTestForLowPoints.java b/java/com.sap.sailing.domain.test/src/com/sap/sailing/domain/test/LeaderboardScoringAndRankingTestForLowPoints.java index 0c953070991..8e999e9b93c 100644 --- a/java/com.sap.sailing.domain.test/src/com/sap/sailing/domain/test/LeaderboardScoringAndRankingTestForLowPoints.java +++ b/java/com.sap.sailing.domain.test/src/com/sap/sailing/domain/test/LeaderboardScoringAndRankingTestForLowPoints.java @@ -56,11 +56,10 @@ public class LeaderboardScoringAndRankingTestForLowPoints extends LeaderboardSco } private void manuallyTransferCarry(Leaderboard leaderboard, List medalCompetitors) { - double carryScore = 0; + int carryScore = 1; for (Competitor medalCompetitor : medalCompetitors) { leaderboard.getScoreCorrection().correctScore(medalCompetitor, leaderboard.getRaceColumnByName("Carry"), - carryScore); - carryScore += 0.0001; + carryScore++); } } @@ -167,10 +166,10 @@ public class LeaderboardScoringAndRankingTestForLowPoints extends LeaderboardSco TrackedRace mDefault = new MockedTrackedRaceWithStartTimeAndRanks(now, m1Results); m1.setTrackedRace(m1.getFleetByName("Default"), mDefault); - Assert.assertEquals(2.0, leaderboard.getNetPoints(medalCompetitorsBestToWorst.get(0), later), EPSILON); - Assert.assertEquals(2.0001, leaderboard.getNetPoints(medalCompetitorsBestToWorst.get(1), later), EPSILON); - Assert.assertEquals(3.0002, leaderboard.getNetPoints(medalCompetitorsBestToWorst.get(2), later), EPSILON); - Assert.assertEquals(4.0003, leaderboard.getNetPoints(medalCompetitorsBestToWorst.get(3), later), EPSILON); + Assert.assertEquals(2.0, leaderboard.getNetPoints(preFirst, later), EPSILON); + Assert.assertEquals(4, leaderboard.getNetPoints(preSecond, later), EPSILON); + Assert.assertEquals(6, leaderboard.getNetPoints(preThird, later), EPSILON); + Assert.assertEquals(8, leaderboard.getNetPoints(preFourth, later), EPSILON); List> afterFinalResults = createCompetitorResultForTimestamp(later, leaderboard); assertNonFinalistsAreBehindFinalistsAndNotChanged(preSeriesScoreRankResult, afterFinalResults); @@ -225,11 +224,15 @@ public class LeaderboardScoringAndRankingTestForLowPoints extends LeaderboardSco TrackedRace m1Default = new MockedTrackedRaceWithStartTimeAndRanks(now, m1Results); m1.setTrackedRace(m1.getFleetByName("Default"), m1Default); - Assert.assertEquals(1.0001, leaderboard.getNetPoints(preSecond, later), EPSILON); - Assert.assertEquals(2.0, leaderboard.getNetPoints(preFirst, later), EPSILON); - Assert.assertEquals(3.0002, leaderboard.getNetPoints(preThird, later), EPSILON); - Assert.assertEquals(4.0003, leaderboard.getNetPoints(preFourth, later), EPSILON); - + Assert.assertEquals(3, leaderboard.getNetPoints(preSecond, later), EPSILON); + Assert.assertEquals(3, leaderboard.getNetPoints(preFirst, later), EPSILON); + Assert.assertEquals(6, leaderboard.getNetPoints(preThird, later), EPSILON); + Assert.assertEquals(8, leaderboard.getNetPoints(preFourth, later), EPSILON); + + List res = leaderboard.getCompetitorsFromBestToWorst(later); + Assert.assertEquals(res.get(0), preFirst); + Assert.assertEquals(res.get(1), preSecond); + RaceColumn m2 = leaderboard.getRaceColumnByName("M2"); ArrayList m2Results = new ArrayList<>(); @@ -244,9 +247,9 @@ public class LeaderboardScoringAndRankingTestForLowPoints extends LeaderboardSco m2.setTrackedRace(m1.getFleetByName("Default"), m2Default); Assert.assertEquals(2.0, leaderboard.getNetPoints(preSecond, m2later), EPSILON); - Assert.assertEquals(4.0, leaderboard.getNetPoints(preFirst, m2later), EPSILON); - Assert.assertEquals(6.0002, leaderboard.getNetPoints(preThird, m2later), EPSILON); - Assert.assertEquals(8.0003, leaderboard.getNetPoints(preFourth, m2later), EPSILON); + Assert.assertEquals(5.0, leaderboard.getNetPoints(preFirst, m2later), EPSILON); + Assert.assertEquals(9, leaderboard.getNetPoints(preThird, m2later), EPSILON); + Assert.assertEquals(12, leaderboard.getNetPoints(preFourth, m2later), EPSILON); List> afterFinalResults = createCompetitorResultForTimestamp(m2later, leaderboard); assertNonFinalistsAreBehindFinalistsAndNotChanged(preSeriesScoreRankResult, afterFinalResults); @@ -301,10 +304,14 @@ public class LeaderboardScoringAndRankingTestForLowPoints extends LeaderboardSco TrackedRace m1Default = new MockedTrackedRaceWithStartTimeAndRanks(now, m1Results); m1.setTrackedRace(m1.getFleetByName("Default"), m1Default); - Assert.assertEquals(1.0001, leaderboard.getNetPoints(preSecond, later), EPSILON); - Assert.assertEquals(2.0, leaderboard.getNetPoints(preFirst, later), EPSILON); - Assert.assertEquals(3.0002, leaderboard.getNetPoints(preThird, later), EPSILON); - Assert.assertEquals(4.0003, leaderboard.getNetPoints(preFourth, later), EPSILON); + Assert.assertEquals(3, leaderboard.getNetPoints(preSecond, later), EPSILON); + Assert.assertEquals(3.0, leaderboard.getNetPoints(preFirst, later), EPSILON); + Assert.assertEquals(6, leaderboard.getNetPoints(preThird, later), EPSILON); + Assert.assertEquals(8, leaderboard.getNetPoints(preFourth, later), EPSILON); + + List res = leaderboard.getCompetitorsFromBestToWorst(later); + Assert.assertEquals(res.get(0), preFirst); + Assert.assertEquals(res.get(1), preSecond); RaceColumn m2 = leaderboard.getRaceColumnByName("M2"); @@ -320,9 +327,9 @@ public class LeaderboardScoringAndRankingTestForLowPoints extends LeaderboardSco m2.setTrackedRace(m1.getFleetByName("Default"), m2Default); Assert.assertEquals(2.0, leaderboard.getNetPoints(preFirst, m2later), EPSILON); - Assert.assertEquals(3.0001, leaderboard.getNetPoints(preSecond, m2later), EPSILON); - Assert.assertEquals(6.0002, leaderboard.getNetPoints(preThird, m2later), EPSILON); - Assert.assertEquals(8.0003, leaderboard.getNetPoints(preFourth, m2later), EPSILON); + Assert.assertEquals(5, leaderboard.getNetPoints(preSecond, m2later), EPSILON); + Assert.assertEquals(9, leaderboard.getNetPoints(preThird, m2later), EPSILON); + Assert.assertEquals(12, leaderboard.getNetPoints(preFourth, m2later), EPSILON); List> afterFinalResults = createCompetitorResultForTimestamp(m2later, leaderboard); assertNonFinalistsAreBehindFinalistsAndNotChanged(preSeriesScoreRankResult, afterFinalResults); @@ -377,10 +384,15 @@ public class LeaderboardScoringAndRankingTestForLowPoints extends LeaderboardSco TrackedRace m1Default = new MockedTrackedRaceWithStartTimeAndRanks(now, m1Results); m1.setTrackedRace(m1.getFleetByName("Default"), m1Default); - Assert.assertEquals(1.0003, leaderboard.getNetPoints(preFourth, later), EPSILON); - Assert.assertEquals(2.0, leaderboard.getNetPoints(preFirst, later), EPSILON); - Assert.assertEquals(3.0001, leaderboard.getNetPoints(preSecond, later), EPSILON); - Assert.assertEquals(4.0002, leaderboard.getNetPoints(preThird, later), EPSILON); + Assert.assertEquals(5, leaderboard.getNetPoints(preFourth, later), EPSILON); + Assert.assertEquals(3.0, leaderboard.getNetPoints(preFirst, later), EPSILON); + Assert.assertEquals(5, leaderboard.getNetPoints(preSecond, later), EPSILON); + Assert.assertEquals(7, leaderboard.getNetPoints(preThird, later), EPSILON); + + List res = leaderboard.getCompetitorsFromBestToWorst(later); + Assert.assertEquals(res.get(0), preFirst); + Assert.assertEquals(res.get(1), preSecond); + Assert.assertEquals(res.get(2), preFourth); RaceColumn m2 = leaderboard.getRaceColumnByName("M2"); @@ -396,9 +408,9 @@ public class LeaderboardScoringAndRankingTestForLowPoints extends LeaderboardSco m2.setTrackedRace(m1.getFleetByName("Default"), m2Default); Assert.assertEquals(2.0, leaderboard.getNetPoints(preFourth, m2later), EPSILON); - Assert.assertEquals(4.0, leaderboard.getNetPoints(preFirst, m2later), EPSILON); - Assert.assertEquals(6.0001, leaderboard.getNetPoints(preSecond, m2later), EPSILON); - Assert.assertEquals(8.0002, leaderboard.getNetPoints(preThird, m2later), EPSILON); + Assert.assertEquals(5.0, leaderboard.getNetPoints(preFirst, m2later), EPSILON); + Assert.assertEquals(8, leaderboard.getNetPoints(preSecond, m2later), EPSILON); + Assert.assertEquals(11, leaderboard.getNetPoints(preThird, m2later), EPSILON); List> afterFinalResults = createCompetitorResultForTimestamp(m2later, leaderboard); assertNonFinalistsAreBehindFinalistsAndNotChanged(preSeriesScoreRankResult, afterFinalResults); @@ -453,10 +465,16 @@ public class LeaderboardScoringAndRankingTestForLowPoints extends LeaderboardSco TrackedRace m1Default = new MockedTrackedRaceWithStartTimeAndRanks(now, m1Results); m1.setTrackedRace(m1.getFleetByName("Default"), m1Default); - Assert.assertEquals(1.0003, leaderboard.getNetPoints(preFourth, later), EPSILON); - Assert.assertEquals(2.0, leaderboard.getNetPoints(preFirst, later), EPSILON); - Assert.assertEquals(3.0001, leaderboard.getNetPoints(preSecond, later), EPSILON); - Assert.assertEquals(4.0002, leaderboard.getNetPoints(preThird, later), EPSILON); + Assert.assertEquals(5, leaderboard.getNetPoints(preFourth, later), EPSILON); + Assert.assertEquals(3.0, leaderboard.getNetPoints(preFirst, later), EPSILON); + Assert.assertEquals(5, leaderboard.getNetPoints(preSecond, later), EPSILON); + Assert.assertEquals(7, leaderboard.getNetPoints(preThird, later), EPSILON); + + + List res = leaderboard.getCompetitorsFromBestToWorst(later); + Assert.assertEquals(res.get(0), preFirst); + Assert.assertEquals(res.get(1), preSecond); + Assert.assertEquals(res.get(2), preFourth); RaceColumn m2 = leaderboard.getRaceColumnByName("M2"); @@ -471,10 +489,10 @@ public class LeaderboardScoringAndRankingTestForLowPoints extends LeaderboardSco TrackedRace m2Default = new MockedTrackedRaceWithStartTimeAndRanks(m2now, m2Results); m2.setTrackedRace(m1.getFleetByName("Default"), m2Default); - Assert.assertEquals(5.0003, leaderboard.getNetPoints(preFourth, m2later), EPSILON); - Assert.assertEquals(4.0, leaderboard.getNetPoints(preFirst, m2later), EPSILON); - Assert.assertEquals(6.0001, leaderboard.getNetPoints(preSecond, m2later), EPSILON); - Assert.assertEquals(5.0002, leaderboard.getNetPoints(preThird, m2later), EPSILON); + Assert.assertEquals(9, leaderboard.getNetPoints(preFourth, m2later), EPSILON); + Assert.assertEquals(5.0, leaderboard.getNetPoints(preFirst, m2later), EPSILON); + Assert.assertEquals(8, leaderboard.getNetPoints(preSecond, m2later), EPSILON); + Assert.assertEquals(8, leaderboard.getNetPoints(preThird, m2later), EPSILON); List> afterFinalResults = createCompetitorResultForTimestamp(m2later, leaderboard); assertNonFinalistsAreBehindFinalistsAndNotChanged(preSeriesScoreRankResult, afterFinalResults); @@ -526,10 +544,10 @@ public class LeaderboardScoringAndRankingTestForLowPoints extends LeaderboardSco TrackedRace mDefault = new MockedTrackedRaceWithStartTimeAndRanks(now, m1Results); m1.setTrackedRace(m1.getFleetByName("Default"), mDefault); - Assert.assertEquals(2.0, leaderboard.getNetPoints(medalCompetitors.get(0), later), EPSILON); - Assert.assertEquals(4.0002, leaderboard.getNetPoints(medalCompetitors.get(1), later), EPSILON); - Assert.assertEquals(6.0004, leaderboard.getNetPoints(medalCompetitors.get(2), later), EPSILON); - Assert.assertEquals(8.0006, leaderboard.getNetPoints(medalCompetitors.get(3), later), EPSILON); + Assert.assertEquals(4, leaderboard.getNetPoints(preFirst, later), EPSILON); + Assert.assertEquals(8, leaderboard.getNetPoints(preSecond, later), EPSILON); + Assert.assertEquals(12, leaderboard.getNetPoints(preThird, later), EPSILON); + Assert.assertEquals(16, leaderboard.getNetPoints(preFourth, later), EPSILON); List> afterFinalResults = createCompetitorResultForTimestamp(later, leaderboard); assertNonFinalistsAreBehindFinalistsAndNotChanged(preSeriesScoreRankResult, afterFinalResults); @@ -583,10 +601,10 @@ public class LeaderboardScoringAndRankingTestForLowPoints extends LeaderboardSco TrackedRace m1Default = new MockedTrackedRaceWithStartTimeAndRanks(now, m1Results); m1.setTrackedRace(m1.getFleetByName("Default"), m1Default); - Assert.assertEquals(2.0002, leaderboard.getNetPoints(preSecond, later), EPSILON); - Assert.assertEquals(4.0, leaderboard.getNetPoints(preFirst, later), EPSILON); - Assert.assertEquals(6.0004, leaderboard.getNetPoints(preThird, later), EPSILON); - Assert.assertEquals(8.0006, leaderboard.getNetPoints(preFourth, later), EPSILON); + Assert.assertEquals(6, leaderboard.getNetPoints(preSecond, later), EPSILON); + Assert.assertEquals(6.0, leaderboard.getNetPoints(preFirst, later), EPSILON); + Assert.assertEquals(12, leaderboard.getNetPoints(preThird, later), EPSILON); + Assert.assertEquals(16, leaderboard.getNetPoints(preFourth, later), EPSILON); RaceColumn m2 = leaderboard.getRaceColumnByName("M2"); @@ -601,10 +619,10 @@ public class LeaderboardScoringAndRankingTestForLowPoints extends LeaderboardSco TrackedRace m2Default = new MockedTrackedRaceWithStartTimeAndRanks(m2now, m2Results); m2.setTrackedRace(m1.getFleetByName("Default"), m2Default); - Assert.assertEquals(4.0002, leaderboard.getNetPoints(preSecond, m2later), EPSILON); - Assert.assertEquals(8.0, leaderboard.getNetPoints(preFirst, m2later), EPSILON); - Assert.assertEquals(12.0004, leaderboard.getNetPoints(preThird, m2later), EPSILON); - Assert.assertEquals(16.0006, leaderboard.getNetPoints(preFourth, m2later), EPSILON); + Assert.assertEquals(8, leaderboard.getNetPoints(preSecond, m2later), EPSILON); + Assert.assertEquals(10.0, leaderboard.getNetPoints(preFirst, m2later), EPSILON); + Assert.assertEquals(18, leaderboard.getNetPoints(preThird, m2later), EPSILON); + Assert.assertEquals(24, leaderboard.getNetPoints(preFourth, m2later), EPSILON); List> afterFinalResults = createCompetitorResultForTimestamp(m2later, leaderboard); assertNonFinalistsAreBehindFinalistsAndNotChanged(preSeriesScoreRankResult, afterFinalResults); @@ -658,10 +676,15 @@ public class LeaderboardScoringAndRankingTestForLowPoints extends LeaderboardSco TrackedRace m1Default = new MockedTrackedRaceWithStartTimeAndRanks(now, m1Results); m1.setTrackedRace(m1.getFleetByName("Default"), m1Default); - Assert.assertEquals(2.0002, leaderboard.getNetPoints(preSecond, later), EPSILON); - Assert.assertEquals(4.0, leaderboard.getNetPoints(preFirst, later), EPSILON); - Assert.assertEquals(6.0004, leaderboard.getNetPoints(preThird, later), EPSILON); - Assert.assertEquals(8.0006, leaderboard.getNetPoints(preFourth, later), EPSILON); + Assert.assertEquals(6, leaderboard.getNetPoints(preSecond, later), EPSILON); + Assert.assertEquals(6, leaderboard.getNetPoints(preFirst, later), EPSILON); + Assert.assertEquals(12, leaderboard.getNetPoints(preThird, later), EPSILON); + Assert.assertEquals(16, leaderboard.getNetPoints(preFourth, later), EPSILON); + + + List res = leaderboard.getCompetitorsFromBestToWorst(later); + Assert.assertEquals(res.get(0), preSecond); + Assert.assertEquals(res.get(1), preFirst); RaceColumn m2 = leaderboard.getRaceColumnByName("M2"); @@ -676,10 +699,10 @@ public class LeaderboardScoringAndRankingTestForLowPoints extends LeaderboardSco TrackedRace m2Default = new MockedTrackedRaceWithStartTimeAndRanks(m2now, m2Results); m2.setTrackedRace(m1.getFleetByName("Default"), m2Default); - Assert.assertEquals(6.0, leaderboard.getNetPoints(preFirst, m2later), EPSILON); - Assert.assertEquals(6.0002, leaderboard.getNetPoints(preSecond, m2later), EPSILON); - Assert.assertEquals(12.0004, leaderboard.getNetPoints(preThird, m2later), EPSILON); - Assert.assertEquals(16.0006, leaderboard.getNetPoints(preFourth, m2later), EPSILON); + Assert.assertEquals(8, leaderboard.getNetPoints(preFirst, m2later), EPSILON); + Assert.assertEquals(10, leaderboard.getNetPoints(preSecond, m2later), EPSILON); + Assert.assertEquals(18, leaderboard.getNetPoints(preThird, m2later), EPSILON); + Assert.assertEquals(24, leaderboard.getNetPoints(preFourth, m2later), EPSILON); List> afterFinalResults = createCompetitorResultForTimestamp(m2later, leaderboard); assertNonFinalistsAreBehindFinalistsAndNotChanged(preSeriesScoreRankResult, afterFinalResults); @@ -733,10 +756,15 @@ public class LeaderboardScoringAndRankingTestForLowPoints extends LeaderboardSco TrackedRace m1Default = new MockedTrackedRaceWithStartTimeAndRanks(now, m1Results); m1.setTrackedRace(m1.getFleetByName("Default"), m1Default); - Assert.assertEquals(2.0006, leaderboard.getNetPoints(preFourth, later), EPSILON); - Assert.assertEquals(4.0, leaderboard.getNetPoints(preFirst, later), EPSILON); - Assert.assertEquals(6.0002, leaderboard.getNetPoints(preSecond, later), EPSILON); - Assert.assertEquals(8.0004, leaderboard.getNetPoints(preThird, later), EPSILON); + Assert.assertEquals(10, leaderboard.getNetPoints(preFourth, later), EPSILON); + Assert.assertEquals(6.0, leaderboard.getNetPoints(preFirst, later), EPSILON); + Assert.assertEquals(10, leaderboard.getNetPoints(preSecond, later), EPSILON); + Assert.assertEquals(14, leaderboard.getNetPoints(preThird, later), EPSILON); + + List res = leaderboard.getCompetitorsFromBestToWorst(later); + Assert.assertEquals(res.get(0), preFirst); + Assert.assertEquals(res.get(1), preFourth); + Assert.assertEquals(res.get(2), preSecond); RaceColumn m2 = leaderboard.getRaceColumnByName("M2"); @@ -751,10 +779,10 @@ public class LeaderboardScoringAndRankingTestForLowPoints extends LeaderboardSco TrackedRace m2Default = new MockedTrackedRaceWithStartTimeAndRanks(m2now, m2Results); m2.setTrackedRace(m1.getFleetByName("Default"), m2Default); - Assert.assertEquals(4.0006, leaderboard.getNetPoints(preFourth, m2later), EPSILON); - Assert.assertEquals(8.0, leaderboard.getNetPoints(preFirst, m2later), EPSILON); - Assert.assertEquals(12.0002, leaderboard.getNetPoints(preSecond, m2later), EPSILON); - Assert.assertEquals(16.0004, leaderboard.getNetPoints(preThird, m2later), EPSILON); + Assert.assertEquals(12, leaderboard.getNetPoints(preFourth, m2later), EPSILON); + Assert.assertEquals(10, leaderboard.getNetPoints(preFirst, m2later), EPSILON); + Assert.assertEquals(16, leaderboard.getNetPoints(preSecond, m2later), EPSILON); + Assert.assertEquals(22, leaderboard.getNetPoints(preThird, m2later), EPSILON); List> afterFinalResults = createCompetitorResultForTimestamp(m2later, leaderboard); assertNonFinalistsAreBehindFinalistsAndNotChanged(preSeriesScoreRankResult, afterFinalResults); @@ -807,10 +835,15 @@ public class LeaderboardScoringAndRankingTestForLowPoints extends LeaderboardSco TrackedRace m1Default = new MockedTrackedRaceWithStartTimeAndRanks(now, m1Results); m1.setTrackedRace(m1.getFleetByName("Default"), m1Default); - Assert.assertEquals(2.0006, leaderboard.getNetPoints(preFourth, later), EPSILON); - Assert.assertEquals(4.0, leaderboard.getNetPoints(preFirst, later), EPSILON); - Assert.assertEquals(6.0002, leaderboard.getNetPoints(preSecond, later), EPSILON); - Assert.assertEquals(8.0004, leaderboard.getNetPoints(preThird, later), EPSILON); + Assert.assertEquals(10, leaderboard.getNetPoints(preFourth, later), EPSILON); + Assert.assertEquals(6.0, leaderboard.getNetPoints(preFirst, later), EPSILON); + Assert.assertEquals(10, leaderboard.getNetPoints(preSecond, later), EPSILON); + Assert.assertEquals(14, leaderboard.getNetPoints(preThird, later), EPSILON); + + List res = leaderboard.getCompetitorsFromBestToWorst(later); + Assert.assertEquals(res.get(0), preFirst); + Assert.assertEquals(res.get(1), preFourth); + Assert.assertEquals(res.get(2), preSecond); RaceColumn m2 = leaderboard.getRaceColumnByName("M2"); @@ -825,10 +858,15 @@ public class LeaderboardScoringAndRankingTestForLowPoints extends LeaderboardSco TrackedRace m2Default = new MockedTrackedRaceWithStartTimeAndRanks(m2now, m2Results); m2.setTrackedRace(m1.getFleetByName("Default"), m2Default); - Assert.assertEquals(10.0006, leaderboard.getNetPoints(preFourth, m2later), EPSILON); - Assert.assertEquals(8.0, leaderboard.getNetPoints(preFirst, m2later), EPSILON); - Assert.assertEquals(12.0002, leaderboard.getNetPoints(preSecond, m2later), EPSILON); - Assert.assertEquals(10.0004, leaderboard.getNetPoints(preThird, m2later), EPSILON); + Assert.assertEquals(18, leaderboard.getNetPoints(preFourth, m2later), EPSILON); + Assert.assertEquals(10, leaderboard.getNetPoints(preFirst, m2later), EPSILON); + Assert.assertEquals(16, leaderboard.getNetPoints(preSecond, m2later), EPSILON); + Assert.assertEquals(16, leaderboard.getNetPoints(preThird, m2later), EPSILON); + + List res2 = leaderboard.getCompetitorsFromBestToWorst(later); + Assert.assertEquals(res2.get(0), preFirst); + Assert.assertEquals(res2.get(1), preFourth); + Assert.assertEquals(res2.get(2), preSecond); List> afterFinalResults = createCompetitorResultForTimestamp(m2later, leaderboard); assertNonFinalistsAreBehindFinalistsAndNotChanged(preSeriesScoreRankResult, afterFinalResults); diff --git a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/impl/LowPointFirstToWinTwoRaces.java b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/impl/LowPointFirstToWinTwoRaces.java index e553fe4aece..d1236863fb6 100644 --- a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/impl/LowPointFirstToWinTwoRaces.java +++ b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/impl/LowPointFirstToWinTwoRaces.java @@ -35,7 +35,7 @@ public class LowPointFirstToWinTwoRaces extends LowPoint { public boolean doesCountAsWinInMedalRace(Double score, RaceColumn raceColumn) { if(score != null) { double minScore = 1 * getScoreFactor(raceColumn); - return score == minScore || score == 0.0; + return score == minScore; } else { return false; } From b9512328897eec57d3df19add9ef3a9ff7f292f1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kai=20B=C3=B6rnert?= Date: Wed, 18 Jul 2018 11:23:21 +0200 Subject: [PATCH 22/43] bug4661 removed discarding rule, adjusted tests, removed now dead code in score calculation --- ...oardScoringAndRankingTestForLowPoints.java | 31 ++++++++++++++++--- .../domain/leaderboard/ScoringScheme.java | 4 --- .../impl/AbstractSimpleLeaderboardImpl.java | 10 ------ .../impl/LowPointFirstToWinTwoRaces.java | 6 ---- 4 files changed, 26 insertions(+), 25 deletions(-) diff --git a/java/com.sap.sailing.domain.test/src/com/sap/sailing/domain/test/LeaderboardScoringAndRankingTestForLowPoints.java b/java/com.sap.sailing.domain.test/src/com/sap/sailing/domain/test/LeaderboardScoringAndRankingTestForLowPoints.java index 8e999e9b93c..7c30a687003 100644 --- a/java/com.sap.sailing.domain.test/src/com/sap/sailing/domain/test/LeaderboardScoringAndRankingTestForLowPoints.java +++ b/java/com.sap.sailing.domain.test/src/com/sap/sailing/domain/test/LeaderboardScoringAndRankingTestForLowPoints.java @@ -246,10 +246,16 @@ public class LeaderboardScoringAndRankingTestForLowPoints extends LeaderboardSco TrackedRace m2Default = new MockedTrackedRaceWithStartTimeAndRanks(m2now, m2Results); m2.setTrackedRace(m1.getFleetByName("Default"), m2Default); - Assert.assertEquals(2.0, leaderboard.getNetPoints(preSecond, m2later), EPSILON); + Assert.assertEquals(4.0, leaderboard.getNetPoints(preSecond, m2later), EPSILON); Assert.assertEquals(5.0, leaderboard.getNetPoints(preFirst, m2later), EPSILON); Assert.assertEquals(9, leaderboard.getNetPoints(preThird, m2later), EPSILON); Assert.assertEquals(12, leaderboard.getNetPoints(preFourth, m2later), EPSILON); + + List res2 = leaderboard.getCompetitorsFromBestToWorst(m2later); + Assert.assertEquals(res2.get(0), preSecond); + Assert.assertEquals(res2.get(1), preFirst); + Assert.assertEquals(res2.get(2), preThird); + Assert.assertEquals(res2.get(3), preFourth); List> afterFinalResults = createCompetitorResultForTimestamp(m2later, leaderboard); assertNonFinalistsAreBehindFinalistsAndNotChanged(preSeriesScoreRankResult, afterFinalResults); @@ -326,10 +332,16 @@ public class LeaderboardScoringAndRankingTestForLowPoints extends LeaderboardSco TrackedRace m2Default = new MockedTrackedRaceWithStartTimeAndRanks(m2now, m2Results); m2.setTrackedRace(m1.getFleetByName("Default"), m2Default); - Assert.assertEquals(2.0, leaderboard.getNetPoints(preFirst, m2later), EPSILON); + Assert.assertEquals(4, leaderboard.getNetPoints(preFirst, m2later), EPSILON); Assert.assertEquals(5, leaderboard.getNetPoints(preSecond, m2later), EPSILON); Assert.assertEquals(9, leaderboard.getNetPoints(preThird, m2later), EPSILON); Assert.assertEquals(12, leaderboard.getNetPoints(preFourth, m2later), EPSILON); + + List res2 = leaderboard.getCompetitorsFromBestToWorst(m2later); + Assert.assertEquals(res2.get(0), preFirst); + Assert.assertEquals(res2.get(1), preSecond); + Assert.assertEquals(res2.get(2), preThird); + Assert.assertEquals(res2.get(3), preFourth); List> afterFinalResults = createCompetitorResultForTimestamp(m2later, leaderboard); assertNonFinalistsAreBehindFinalistsAndNotChanged(preSeriesScoreRankResult, afterFinalResults); @@ -407,10 +419,18 @@ public class LeaderboardScoringAndRankingTestForLowPoints extends LeaderboardSco TrackedRace m2Default = new MockedTrackedRaceWithStartTimeAndRanks(m2now, m2Results); m2.setTrackedRace(m1.getFleetByName("Default"), m2Default); - Assert.assertEquals(2.0, leaderboard.getNetPoints(preFourth, m2later), EPSILON); + Assert.assertEquals(6.0, leaderboard.getNetPoints(preFourth, m2later), EPSILON); Assert.assertEquals(5.0, leaderboard.getNetPoints(preFirst, m2later), EPSILON); Assert.assertEquals(8, leaderboard.getNetPoints(preSecond, m2later), EPSILON); Assert.assertEquals(11, leaderboard.getNetPoints(preThird, m2later), EPSILON); + + List res2 = leaderboard.getCompetitorsFromBestToWorst(m2later); + Assert.assertEquals(res2.get(0), preFourth); + Assert.assertEquals(res2.get(1), preFirst); + Assert.assertEquals(res2.get(2), preSecond); + Assert.assertEquals(res2.get(3), preThird); + + List> afterFinalResults = createCompetitorResultForTimestamp(m2later, leaderboard); assertNonFinalistsAreBehindFinalistsAndNotChanged(preSeriesScoreRankResult, afterFinalResults); @@ -863,10 +883,11 @@ public class LeaderboardScoringAndRankingTestForLowPoints extends LeaderboardSco Assert.assertEquals(16, leaderboard.getNetPoints(preSecond, m2later), EPSILON); Assert.assertEquals(16, leaderboard.getNetPoints(preThird, m2later), EPSILON); - List res2 = leaderboard.getCompetitorsFromBestToWorst(later); + List res2 = leaderboard.getCompetitorsFromBestToWorst(m2later); Assert.assertEquals(res2.get(0), preFirst); - Assert.assertEquals(res2.get(1), preFourth); + Assert.assertEquals(res2.get(1), preThird); Assert.assertEquals(res2.get(2), preSecond); + Assert.assertEquals(res2.get(3), preFourth); List> afterFinalResults = createCompetitorResultForTimestamp(m2later, leaderboard); assertNonFinalistsAreBehindFinalistsAndNotChanged(preSeriesScoreRankResult, afterFinalResults); diff --git a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/ScoringScheme.java b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/ScoringScheme.java index 815014eaeac..7781bc88e1c 100755 --- a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/ScoringScheme.java +++ b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/ScoringScheme.java @@ -172,8 +172,4 @@ public interface ScoringScheme extends Serializable { } return factor; } - - default double getTargetAmountOfMedalRaceWinsScore() { - throw new IllegalStateException("This call is not valid for this scoringSheme"); - }; } diff --git a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/impl/AbstractSimpleLeaderboardImpl.java b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/impl/AbstractSimpleLeaderboardImpl.java index 3aa7688a5b6..572042110c2 100644 --- a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/impl/AbstractSimpleLeaderboardImpl.java +++ b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/impl/AbstractSimpleLeaderboardImpl.java @@ -493,7 +493,6 @@ public abstract class AbstractSimpleLeaderboardImpl extends AbstractLeaderboardW // from there on boolean needToResetScoreUponNextNonEmptyEntry = false; double result = getCarriedPoints(competitor); - int wonRaces = 0; final Set discardedRaceColumns = getResultDiscardingRule().getDiscardedRaceColumns(competitor, this, raceColumnsToConsider, timePoint); for (RaceColumn raceColumn : raceColumnsToConsider) { @@ -505,21 +504,12 @@ public abstract class AbstractSimpleLeaderboardImpl extends AbstractLeaderboardW if (netPoints != null) { if (needToResetScoreUponNextNonEmptyEntry) { result = 0; - wonRaces = 0; needToResetScoreUponNextNonEmptyEntry = false; } result += netPoints; - if (getScoringScheme().isMedalWinAmountCriteria() && raceColumn.isMedalRace()) { - wonRaces += getScoringScheme().doesCountAsWinInMedalRace(netPoints, raceColumn) ? 1 : 0; - } } } } - if (getScoringScheme().isMedalWinAmountCriteria()) { - if (wonRaces == getScoringScheme().getTargetAmountOfMedalRaceWins()) { - return getScoringScheme().getTargetAmountOfMedalRaceWinsScore(); - } - } return result; } diff --git a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/impl/LowPointFirstToWinTwoRaces.java b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/impl/LowPointFirstToWinTwoRaces.java index d1236863fb6..ea527082bf4 100644 --- a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/impl/LowPointFirstToWinTwoRaces.java +++ b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/impl/LowPointFirstToWinTwoRaces.java @@ -49,10 +49,4 @@ public class LowPointFirstToWinTwoRaces extends LowPoint { } return factor; } - - @Override - public double getTargetAmountOfMedalRaceWinsScore() { - return 2.0; - } - } From 9a3eb7def0cbbc6d3291f251eea0e2258709f120 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kai=20B=C3=B6rnert?= Date: Wed, 18 Jul 2018 12:37:12 +0200 Subject: [PATCH 23/43] bug4661 use central point of code to determine if a race counts as won --- .../data/RaceResultOfCompetitorWithContext.java | 9 +-------- .../sailing/domain/leaderboard/Leaderboard.java | 15 ++++++++++++++- .../sailing/domain/leaderboard/ScoringScheme.java | 4 ---- .../leaderboard/impl/AbstractLeaderboardImpl.java | 2 +- .../impl/AbstractSimpleLeaderboardImpl.java | 2 ++ .../impl/LeaderboardTotalRankComparator.java | 4 ++-- .../impl/LowPointFirstToWinTwoRaces.java | 10 ---------- 7 files changed, 20 insertions(+), 26 deletions(-) mode change 100755 => 100644 java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/impl/AbstractLeaderboardImpl.java diff --git a/java/com.sap.sailing.datamining/src/com/sap/sailing/datamining/impl/data/RaceResultOfCompetitorWithContext.java b/java/com.sap.sailing.datamining/src/com/sap/sailing/datamining/impl/data/RaceResultOfCompetitorWithContext.java index f0e7b4a0831..3648c6802b7 100644 --- a/java/com.sap.sailing.datamining/src/com/sap/sailing/datamining/impl/data/RaceResultOfCompetitorWithContext.java +++ b/java/com.sap.sailing.datamining/src/com/sap/sailing/datamining/impl/data/RaceResultOfCompetitorWithContext.java @@ -209,15 +209,8 @@ public class RaceResultOfCompetitorWithContext implements HasRaceResultOfCompeti @Override public Boolean isWin() { - Leaderboard leaderboard = getLeaderboard(); final TimePoint now = MillisecondsTimePoint.now(); - double points = leaderboard.getTotalPoints(competitor, raceColumn, now); - if (leaderboard.getScoringScheme().isHigherBetter()) { - double competitorCount = Util.size(leaderboard.getCompetitors()); - return points >= (competitorCount - 0.05); - } else { - return points <= 1.05; - } + return getLeaderboard().isWin(competitor, raceColumn, now); } } diff --git a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/Leaderboard.java b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/Leaderboard.java index 098bdb90cf9..a59850784c3 100644 --- a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/Leaderboard.java +++ b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/Leaderboard.java @@ -604,4 +604,17 @@ public interface Leaderboard extends LeaderboardBase, HasRaceColumns { * leaderboard. */ boolean hasScores(Competitor competitor, TimePoint timePoint); -} + + default boolean isWin(Competitor competitor, RaceColumn raceColumn, TimePoint timePoint) { + Double points = getTotalPoints(competitor, raceColumn, timePoint); + if(points == null) { + return false; + } + if (getScoringScheme().isHigherBetter()) { + double competitorCount = Util.size(getCompetitors()); + return points >= (competitorCount - 0.05); + } else { + return points <= 1.05; + } + } +} \ No newline at end of file diff --git a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/ScoringScheme.java b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/ScoringScheme.java index 7781bc88e1c..6ae47a1cd3c 100755 --- a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/ScoringScheme.java +++ b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/ScoringScheme.java @@ -155,10 +155,6 @@ public interface ScoringScheme extends Serializable { throw new IllegalStateException("This call is not valid for this scoringSheme"); } - default boolean doesCountAsWinInMedalRace(Double o1Score, RaceColumn raceColumn) { - 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 diff --git a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/impl/AbstractLeaderboardImpl.java b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/impl/AbstractLeaderboardImpl.java old mode 100755 new mode 100644 index a49dc0d95bd..c2d8203bbb5 --- a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/impl/AbstractLeaderboardImpl.java +++ b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/impl/AbstractLeaderboardImpl.java @@ -281,5 +281,5 @@ public abstract class AbstractLeaderboardImpl extends AbstractSimpleLeaderboardI RegattaLogBoatDeregistrator deregisterer = new RegattaLogBoatDeregistrator<>(regattaLog, boats, regattaLogEventAuthorForAbstractLeaderboard); deregisterer.deregister(deregisterer.analyze()); } - + } diff --git a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/impl/AbstractSimpleLeaderboardImpl.java b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/impl/AbstractSimpleLeaderboardImpl.java index 572042110c2..992edf20d05 100644 --- a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/impl/AbstractSimpleLeaderboardImpl.java +++ b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/impl/AbstractSimpleLeaderboardImpl.java @@ -959,5 +959,7 @@ public abstract class AbstractSimpleLeaderboardImpl extends AbstractLeaderboardW return Util.getDominantObject(StreamSupport.stream(allBoats.spliterator(), /* parallel */ false) .map(b -> b.getBoatClass()).collect(Collectors.toList())); } + + } diff --git a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/impl/LeaderboardTotalRankComparator.java b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/impl/LeaderboardTotalRankComparator.java index bb3f59f37ed..abc78af606e 100755 --- a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/impl/LeaderboardTotalRankComparator.java +++ b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/impl/LeaderboardTotalRankComparator.java @@ -196,8 +196,8 @@ public class LeaderboardTotalRankComparator implements Comparator { // (tracked or manual) is sufficient preemptiveColumnResult = compareByMedalRaceParticipation(o1Score, o2Score); if (scoringScheme.isMedalWinAmountCriteria()) { - numberOfMedalRacesWonO1 += scoringScheme.doesCountAsWinInMedalRace(o1Score, raceColumn) ? 1 : 0; - numberOfMedalRacesWonO2 += scoringScheme.doesCountAsWinInMedalRace(o2Score, raceColumn) ? 1 : 0; + numberOfMedalRacesWonO1 += leaderboard.isWin(o1, raceColumn, timePoint) ? 1 : 0; + numberOfMedalRacesWonO2 += leaderboard.isWin(o2, raceColumn, timePoint) ? 1 : 0; } } if (preemptiveColumnResult == 0 && raceColumn.isTotalOrderDefinedByFleet()) { diff --git a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/impl/LowPointFirstToWinTwoRaces.java b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/impl/LowPointFirstToWinTwoRaces.java index ea527082bf4..055b9e5c2e3 100644 --- a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/impl/LowPointFirstToWinTwoRaces.java +++ b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/impl/LowPointFirstToWinTwoRaces.java @@ -31,16 +31,6 @@ public class LowPointFirstToWinTwoRaces extends LowPoint { return 2; } - @Override - public boolean doesCountAsWinInMedalRace(Double score, RaceColumn raceColumn) { - if(score != null) { - double minScore = 1 * getScoreFactor(raceColumn); - return score == minScore; - } else { - return false; - } - } - @Override public double getScoreFactor(RaceColumn a) { Double factor = a.getExplicitFactor(); From 0b61a4c5dd590d8fb766589cec784a9f2cafe30f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kai=20B=C3=B6rnert?= Date: Wed, 18 Jul 2018 12:49:54 +0200 Subject: [PATCH 24/43] bug4661 added javadocs --- .../src/com/sap/sailing/domain/leaderboard/Leaderboard.java | 4 ++++ .../com/sap/sailing/domain/leaderboard/ScoringScheme.java | 4 ++++ .../domain/leaderboard/impl/LowPointFirstToWinTwoRaces.java | 5 +++++ 3 files changed, 13 insertions(+) diff --git a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/Leaderboard.java b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/Leaderboard.java index a59850784c3..19779becfd5 100644 --- a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/Leaderboard.java +++ b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/Leaderboard.java @@ -605,6 +605,10 @@ public interface Leaderboard extends LeaderboardBase, HasRaceColumns { */ boolean hasScores(Competitor competitor, TimePoint timePoint); + /** + * Returns true if a racecolumn evaluates to be a win for the given competitor at the given timepoint. + * If the competitor is not scored for this race, false is returned + */ default boolean isWin(Competitor competitor, RaceColumn raceColumn, TimePoint timePoint) { Double points = getTotalPoints(competitor, raceColumn, timePoint); if(points == null) { diff --git a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/ScoringScheme.java b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/ScoringScheme.java index 6ae47a1cd3c..e7b5aafa825 100755 --- a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/ScoringScheme.java +++ b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/ScoringScheme.java @@ -151,6 +151,10 @@ public interface ScoringScheme extends Serializable { return false; } + /** + * If isMedalWinAmountCriteria returns 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"); } diff --git a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/impl/LowPointFirstToWinTwoRaces.java b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/impl/LowPointFirstToWinTwoRaces.java index 055b9e5c2e3..c567761f5ab 100644 --- a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/impl/LowPointFirstToWinTwoRaces.java +++ b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/impl/LowPointFirstToWinTwoRaces.java @@ -3,6 +3,11 @@ package com.sap.sailing.domain.leaderboard.impl; import com.sap.sailing.domain.base.RaceColumn; import com.sap.sailing.domain.common.ScoringSchemeType; +/** + * This class is a derivation of the LowPointScoring scheme. The first participant in the medal series, that wins two + * races is ranked as the first. The participant that has the score 1 in the preSeries carry column only must reach one + * additional victory. This Scheme will change the default scoring factor for medal races to 1, usually 2 is used + */ public class LowPointFirstToWinTwoRaces extends LowPoint { private static final long serialVersionUID = 7072175334160798617L; From 5efe0ee7d7c59d21cfc8a9d0707a95630d950625 Mon Sep 17 00:00:00 2001 From: Steffen Schaefer Date: Wed, 18 Jul 2018 12:52:29 +0200 Subject: [PATCH 25/43] Bug 4661: Added JavaDocs --- .../leaderboard/impl/LeaderboardTotalRankComparator.java | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/impl/LeaderboardTotalRankComparator.java b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/impl/LeaderboardTotalRankComparator.java index abc78af606e..046a45db260 100755 --- a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/impl/LeaderboardTotalRankComparator.java +++ b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/impl/LeaderboardTotalRankComparator.java @@ -261,6 +261,11 @@ public class LeaderboardTotalRankComparator implements Comparator { return result; } + /** + * Compares by the number of races won in the medal series. If one of the competitors reached the target of won + * races (defined by {@link ScoringScheme#getTargetAmountOfMedalRaceWins()} he is ranked better than the other. If + * none of the competitors reached the target, they are ranked equally even if one has more wins. + */ private int compareByMedalRacesWon(int numberOfMedalRacesWonO1, int numberOfMedalRacesWonO2) { int targetAmount = scoringScheme.getTargetAmountOfMedalRaceWins(); // if one reaches the targetamount, this has priority, else proceed with normal low points scoring (eg. not @@ -274,6 +279,10 @@ public class LeaderboardTotalRankComparator implements Comparator { return 0; } + /** + * Compares by the scores of a single race column. If only one of the competitors has a result this competitor is + * ranked better than the other one. + */ private int compareBySingleRaceColumnScore(Double o1CarryForwardInMedals, Double o2CarryForwardInMedals) { if (o1CarryForwardInMedals == null && o2CarryForwardInMedals == null) { return 0; From a644b5c4cd869f3f5610fb432e1f226004175fbc Mon Sep 17 00:00:00 2001 From: Axel Uhl Date: Wed, 18 Jul 2018 20:42:28 +0200 Subject: [PATCH 26/43] coding and formatting conventions Change-Id: Ic0115215d4d235eab4bc2023186395d7434b128f --- .../sailing/domain/leaderboard/Leaderboard.java | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/Leaderboard.java b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/Leaderboard.java index 19779becfd5..1149ec9004c 100644 --- a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/Leaderboard.java +++ b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/Leaderboard.java @@ -610,15 +610,16 @@ public interface Leaderboard extends LeaderboardBase, HasRaceColumns { * If the competitor is not scored for this race, false is returned */ default boolean isWin(Competitor competitor, RaceColumn raceColumn, TimePoint timePoint) { - Double points = getTotalPoints(competitor, raceColumn, timePoint); - if(points == null) { - return false; - } - if (getScoringScheme().isHigherBetter()) { + final Double points = getTotalPoints(competitor, raceColumn, timePoint); + final boolean result; + if (points == null) { + result = false; + } else if (getScoringScheme().isHigherBetter()) { double competitorCount = Util.size(getCompetitors()); - return points >= (competitorCount - 0.05); + result = points >= (competitorCount - 0.05); } else { - return points <= 1.05; + result = points <= 1.05; } + return result; } } \ No newline at end of file From 8673bd82f5ace004a2213c2624a21aaf4de534d3 Mon Sep 17 00:00:00 2001 From: Axel Uhl Date: Wed, 18 Jul 2018 21:16:37 +0200 Subject: [PATCH 27/43] improved Javadoc; code formatting Change-Id: I88502e8e808776f46743e653b248a8808d6524fa --- .../src/com/sap/sailing/domain/leaderboard/ScoringScheme.java | 4 ++-- .../domain/leaderboard/impl/LowPointFirstToWinTwoRaces.java | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/ScoringScheme.java b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/ScoringScheme.java index e7b5aafa825..c0eecf6663a 100755 --- a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/ScoringScheme.java +++ b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/ScoringScheme.java @@ -152,8 +152,8 @@ public interface ScoringScheme extends Serializable { } /** - * If isMedalWinAmountCriteria returns true, this will be the amount of races that must be won, in order to win the - * medal series instantly + * 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"); diff --git a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/impl/LowPointFirstToWinTwoRaces.java b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/impl/LowPointFirstToWinTwoRaces.java index c567761f5ab..bcb7da5898a 100644 --- a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/impl/LowPointFirstToWinTwoRaces.java +++ b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/impl/LowPointFirstToWinTwoRaces.java @@ -39,7 +39,7 @@ public class LowPointFirstToWinTwoRaces extends LowPoint { @Override public double getScoreFactor(RaceColumn a) { Double factor = a.getExplicitFactor(); - if(factor == null) { + if (factor == null) { factor = 1.0; } return factor; From be06df2557bb4ea1d8b8ab121720d17d22b7d1fd Mon Sep 17 00:00:00 2001 From: Axel Uhl Date: Wed, 18 Jul 2018 21:26:29 +0200 Subject: [PATCH 28/43] updated Javadoc in ScoringScheme to better reflect the details Change-Id: I369a99e9d2b07843930fa4fa745af58e2bae20ff --- .../sailing/domain/leaderboard/ScoringScheme.java | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/ScoringScheme.java b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/ScoringScheme.java index c0eecf6663a..8964a073e76 100755 --- a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/ScoringScheme.java +++ b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/ScoringScheme.java @@ -8,6 +8,7 @@ import java.util.concurrent.Callable; import com.sap.sailing.domain.base.Competitor; import com.sap.sailing.domain.base.RaceColumn; import com.sap.sailing.domain.base.Regatta; +import com.sap.sailing.domain.base.Series; import com.sap.sailing.domain.common.MaxPointsReason; import com.sap.sailing.domain.common.NoWindException; import com.sap.sailing.domain.common.ScoringSchemeType; @@ -136,8 +137,9 @@ public interface ScoringScheme extends Serializable { } /** - * Returning {@code true} makes the carry forward score a secondary ranking criteria for competitors that have an - * equal overall score. + * Returning {@code true} makes the {@link RaceColumn#isCarryForward() carry forward score} in a + * {@link Series#isMedal() medal series} a secondary ranking criteria for competitors that have an equal overall + * score. */ default boolean isCarryForwardInMedalsCriteria() { return false; @@ -165,10 +167,10 @@ public interface ScoringScheme extends Serializable { * different from 1 or 2. For example, we've seen cases in the Extreme Sailing Series where the race committee * defined that in the overall series leaderboard the last two columns each count 1.5 times their scores. */ - default double getScoreFactor(RaceColumn a) { - Double factor = a.getExplicitFactor(); + default double getScoreFactor(RaceColumn raceColumn) { + Double factor = raceColumn.getExplicitFactor(); if (factor == null) { - factor = a.isMedalRace() ? DEFAULT_MEDAL_RACE_FACTOR : 1.0; + factor = raceColumn.isMedalRace() ? DEFAULT_MEDAL_RACE_FACTOR : 1.0; } return factor; } From 21a0adc91d485e49dcfb6e1cbba58d091ae4591b Mon Sep 17 00:00:00 2001 From: Axel Uhl Date: Wed, 18 Jul 2018 21:35:09 +0200 Subject: [PATCH 29/43] added TODO for compareByMedalRacesWon; coding conventions Change-Id: I0325d3f671c6218edb5017122351665457b56124 --- .../impl/LeaderboardTotalRankComparator.java | 23 +++++++++++-------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/impl/LeaderboardTotalRankComparator.java b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/impl/LeaderboardTotalRankComparator.java index 046a45db260..429b7199288 100755 --- a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/impl/LeaderboardTotalRankComparator.java +++ b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/impl/LeaderboardTotalRankComparator.java @@ -223,6 +223,8 @@ public class LeaderboardTotalRankComparator implements Comparator { int result = compareByNumberOfRacesScored(o1Scores.size(), o2Scores.size()); if (result == 0) { if (scoringScheme.isMedalWinAmountCriteria()) { + // if one reaches the target amount of races won then this has priority, else proceed with normal low + // points scoring (e.g., not enough races yet) result = compareByMedalRacesWon(numberOfMedalRacesWonO1, numberOfMedalRacesWonO2); } if (result == 0) { @@ -262,21 +264,22 @@ public class LeaderboardTotalRankComparator implements Comparator { } /** - * Compares by the number of races won in the medal series. If one of the competitors reached the target of won - * races (defined by {@link ScoringScheme#getTargetAmountOfMedalRaceWins()} he is ranked better than the other. If + * Compares by the number of races won in the medal series. If one of the competitors reached the target of races won + * (defined by {@link ScoringScheme#getTargetAmountOfMedalRaceWins()} it is ranked better than the other. If * none of the competitors reached the target, they are ranked equally even if one has more wins. */ private int compareByMedalRacesWon(int numberOfMedalRacesWonO1, int numberOfMedalRacesWonO2) { - int targetAmount = scoringScheme.getTargetAmountOfMedalRaceWins(); - // if one reaches the targetamount, this has priority, else proceed with normal low points scoring (eg. not - // enough races yet) + // TODO bug4661 clarify what the desired outcome is if (e.g., temporarily due to manual score corrections) both reached or surpassed the number of wins required + final int targetAmount = scoringScheme.getTargetAmountOfMedalRaceWins(); + final int result; if (numberOfMedalRacesWonO1 == targetAmount) { - return -1; + result = -1; + } else if (numberOfMedalRacesWonO2 == targetAmount) { + result = 1; + } else { + result = 0; } - if (numberOfMedalRacesWonO2 == targetAmount) { - return 1; - } - return 0; + return result; } /** From b55acabff081e496180461497f6da2b70b43dbf1 Mon Sep 17 00:00:00 2001 From: Axel Uhl Date: Wed, 18 Jul 2018 21:38:49 +0200 Subject: [PATCH 30/43] reverted unnecessary formatting changes, also to ease review Change-Id: Id769da07307a081194cb52096673085db6ff5062 --- .../leaderboard/impl/LeaderboardTotalRankComparator.java | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/impl/LeaderboardTotalRankComparator.java b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/impl/LeaderboardTotalRankComparator.java index 429b7199288..84f32bee426 100755 --- a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/impl/LeaderboardTotalRankComparator.java +++ b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/impl/LeaderboardTotalRankComparator.java @@ -240,15 +240,12 @@ public class LeaderboardTotalRankComparator implements Comparator { if (result == 0) { result = compareByMedalRaceScore(o1MedalRaceScore, o2MedalRaceScore); if (result == 0) { - result = compareByBetterScore(o1, Collections.unmodifiableList(o1Scores), o2, - Collections.unmodifiableList(o2Scores), timePoint); + result = compareByBetterScore(o1, Collections.unmodifiableList(o1Scores), o2, Collections.unmodifiableList(o2Scores), timePoint); if (result == 0) { // compare by last race: - result = scoringScheme.compareByLastRace(o1TotalPoints, o2TotalPoints, nullScoresAreBetter, - o1, o2); + result = scoringScheme.compareByLastRace(o1TotalPoints, o2TotalPoints, nullScoresAreBetter, o1, o2); if (result == 0) { - result = scoringScheme.compareByLatestRegattaInMetaLeaderboard(getLeaderboard(), o1, o2, - timePoint); + result = scoringScheme.compareByLatestRegattaInMetaLeaderboard(getLeaderboard(), o1, o2, timePoint); if (result == 0) { result = compareByArbitraryButStableCriteria(o1, o2); } From df234945f22c438ae5045c735254d97916b05b28 Mon Sep 17 00:00:00 2001 From: Axel Uhl Date: Wed, 18 Jul 2018 21:41:36 +0200 Subject: [PATCH 31/43] improved scoring scheme i18n text messages Change-Id: I011c918be0e854023bd5572b0f283b2b69ad91f8 --- .../sap/sailing/gwt/ui/client/StringMessages_de.properties | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/StringMessages_de.properties b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/StringMessages_de.properties index c0a03e691b6..be22b9f7076 100755 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/StringMessages_de.properties +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/StringMessages_de.properties @@ -474,8 +474,8 @@ scoringSchemeLowPointForLeagueOverallLeaderboardDescription=Bei Punktegleichstan scoringSchemeLowPointTieBreakBasedOnLastSeriesOnly=Low Point System, bei Punktegleichstand zählt letzten Serie scoringSchemeLowPointTieBreakBasedOnLastSeriesOnlyDescription=Bei Punktegleichstand entscheidet die Punktesumme aller (auch der gestrichenen) Wettfahrten der letzten Serie scoringSchemeLowPointWithAutomaticRdg=Low Point System, RDG erhält Durchschnitt aller nicht-RDG-Wertungen als Vorschlag -scoringSchemeLowPointSystemFirstTwoWins=Low Point System, Erster mit zwei Siegen in Medals gewinnt -scoringSchemeLowPointSystemFirstTwoWinsDescription=Low Point System. Der Erste, der zwei Rennen in der Medal-Serie gewinnt, zählt als Sieger der Medal-Serie. Der Beste der Vorserien bekommt einen zusätzlichen Sieg angerechnet. +scoringSchemeLowPointSystemFirstTwoWins=Low Point System, Erster mit zwei Siegen in Medaillen-Rennen gewinnt +scoringSchemeLowPointSystemFirstTwoWinsDescription=Low Point System. Der Erste, der zwei Rennen in den Medaillen-Rennen gewinnt, zählt als Sieger der Medaillen-Serie. Der Beste der Vorserien bekommt einen zusätzlichen Sieg angerechnet. scoringSystem=Bepunktungssystem createFlexibleLeaderboard=Flexible Rangliste anlegen createRegattaLeaderboard=Rangliste für Regatta anlegen From 9d990e470d68a9870e2fdc84b0e4c548db43e3e4 Mon Sep 17 00:00:00 2001 From: Axel Uhl Date: Wed, 18 Jul 2018 21:43:37 +0200 Subject: [PATCH 32/43] coding conventions Change-Id: I674fb13c731b3f07b09e06eb93a781a4ea7ce252 --- .../impl/LeaderboardTotalRankComparator.java | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/impl/LeaderboardTotalRankComparator.java b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/impl/LeaderboardTotalRankComparator.java index 84f32bee426..477d374f6d1 100755 --- a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/impl/LeaderboardTotalRankComparator.java +++ b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/impl/LeaderboardTotalRankComparator.java @@ -284,16 +284,17 @@ public class LeaderboardTotalRankComparator implements Comparator { * ranked better than the other one. */ private int compareBySingleRaceColumnScore(Double o1CarryForwardInMedals, Double o2CarryForwardInMedals) { + final int result; if (o1CarryForwardInMedals == null && o2CarryForwardInMedals == null) { - return 0; + result = 0; + } else if (o1CarryForwardInMedals == null) { + result = 1; + } else if (o2CarryForwardInMedals == null) { + result = -1; + } else { + result = getScoreComparator().compare(o1CarryForwardInMedals, o2CarryForwardInMedals); } - if (o1CarryForwardInMedals == null) { - return 1; - } - if (o2CarryForwardInMedals == null) { - return -1; - } - return getScoreComparator().compare(o1CarryForwardInMedals, o2CarryForwardInMedals); + return result; } private int compareByArbitraryButStableCriteria(Competitor o1, Competitor o2) { From 03d93bca0ce3a26256f3cbb4f46c863156601e6b Mon Sep 17 00:00:00 2001 From: Axel Uhl Date: Wed, 18 Jul 2018 21:44:14 +0200 Subject: [PATCH 33/43] improved parameter naming Change-Id: I0d6aa8f22952c19c907aaba0f90c425396abffcb --- .../impl/LeaderboardTotalRankComparator.java | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/impl/LeaderboardTotalRankComparator.java b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/impl/LeaderboardTotalRankComparator.java index 477d374f6d1..38be04b22ae 100755 --- a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/impl/LeaderboardTotalRankComparator.java +++ b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/impl/LeaderboardTotalRankComparator.java @@ -283,16 +283,16 @@ public class LeaderboardTotalRankComparator implements Comparator { * Compares by the scores of a single race column. If only one of the competitors has a result this competitor is * ranked better than the other one. */ - private int compareBySingleRaceColumnScore(Double o1CarryForwardInMedals, Double o2CarryForwardInMedals) { + private int compareBySingleRaceColumnScore(Double o1Score, Double o2Score) { final int result; - if (o1CarryForwardInMedals == null && o2CarryForwardInMedals == null) { + if (o1Score == null && o2Score == null) { result = 0; - } else if (o1CarryForwardInMedals == null) { + } else if (o1Score == null) { result = 1; - } else if (o2CarryForwardInMedals == null) { + } else if (o2Score == null) { result = -1; } else { - result = getScoreComparator().compare(o1CarryForwardInMedals, o2CarryForwardInMedals); + result = getScoreComparator().compare(o1Score, o2Score); } return result; } From 206fee1214c46e9fb0eb718a53d21bd9e0a01945 Mon Sep 17 00:00:00 2001 From: Axel Uhl Date: Wed, 18 Jul 2018 21:46:30 +0200 Subject: [PATCH 34/43] cleaned up and simplified code Change-Id: I1c159d3a2daa1e96c12ca48599cfadbae6983307 --- .../impl/LeaderboardTotalRankComparator.java | 18 +++++------------- 1 file changed, 5 insertions(+), 13 deletions(-) diff --git a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/impl/LeaderboardTotalRankComparator.java b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/impl/LeaderboardTotalRankComparator.java index 38be04b22ae..f4d4a00762c 100755 --- a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/impl/LeaderboardTotalRankComparator.java +++ b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/impl/LeaderboardTotalRankComparator.java @@ -284,17 +284,7 @@ public class LeaderboardTotalRankComparator implements Comparator { * ranked better than the other one. */ private int compareBySingleRaceColumnScore(Double o1Score, Double o2Score) { - final int result; - if (o1Score == null && o2Score == null) { - result = 0; - } else if (o1Score == null) { - result = 1; - } else if (o2Score == null) { - result = -1; - } else { - result = getScoreComparator().compare(o1Score, o2Score); - } - return result; + return Comparator.nullsLast((Double o1s, Double o2s)->getScoreComparator().compare(o1s, o2s)).compare(o1Score, o2Score); } private int compareByArbitraryButStableCriteria(Competitor o1, Competitor o2) { @@ -307,11 +297,13 @@ public class LeaderboardTotalRankComparator implements Comparator { */ private int compareByMedalRaceScore(Double o1MedalRaceScore, Double o2MedalRaceScore) { assert o1MedalRaceScore != null || o2MedalRaceScore == null; + final int result; if (o1MedalRaceScore != null) { - return getScoreComparator().compare(o1MedalRaceScore, o2MedalRaceScore); + result = getScoreComparator().compare(o1MedalRaceScore, o2MedalRaceScore); } else { - return 0; + result = 0; } + return result; } private static class FleetComparisonResult { From 3a9262718fa4c081b04100b0b43f93d97dd99c95 Mon Sep 17 00:00:00 2001 From: Axel Uhl Date: Wed, 18 Jul 2018 21:50:13 +0200 Subject: [PATCH 35/43] improved parameter name Change-Id: Id193f1dddadb17f4512baec41f4a81f8945e5e53 --- .../domain/leaderboard/impl/LowPointFirstToWinTwoRaces.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/impl/LowPointFirstToWinTwoRaces.java b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/impl/LowPointFirstToWinTwoRaces.java index bcb7da5898a..e0a376a5bb4 100644 --- a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/impl/LowPointFirstToWinTwoRaces.java +++ b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/impl/LowPointFirstToWinTwoRaces.java @@ -37,8 +37,8 @@ public class LowPointFirstToWinTwoRaces extends LowPoint { } @Override - public double getScoreFactor(RaceColumn a) { - Double factor = a.getExplicitFactor(); + public double getScoreFactor(RaceColumn raceColumn) { + Double factor = raceColumn.getExplicitFactor(); if (factor == null) { factor = 1.0; } From d182929c106712cd5546229095802c7617feb700 Mon Sep 17 00:00:00 2001 From: Axel Uhl Date: Wed, 18 Jul 2018 22:00:28 +0200 Subject: [PATCH 36/43] removed unused @param tag in Javadoc Change-Id: I77d03456d58cf46332e2afdb0e9fbe802d049edb --- .../com/sap/sailing/server/gateway/impl/rc/RaceGroupFactory.java | 1 - 1 file changed, 1 deletion(-) diff --git a/java/com.sap.sailing.server.gateway/src/com/sap/sailing/server/gateway/impl/rc/RaceGroupFactory.java b/java/com.sap.sailing.server.gateway/src/com/sap/sailing/server/gateway/impl/rc/RaceGroupFactory.java index fb6a755ff0d..3d719143ebe 100644 --- a/java/com.sap.sailing.server.gateway/src/com/sap/sailing/server/gateway/impl/rc/RaceGroupFactory.java +++ b/java/com.sap.sailing.server.gateway/src/com/sap/sailing/server/gateway/impl/rc/RaceGroupFactory.java @@ -93,7 +93,6 @@ public class RaceGroupFactory { /** * @param raceColumns * must be provided in the same order in which they appear in the series / leaderboard - * @param scoringScheme */ private Collection getRows(Series series, List raceColumns, ScoringScheme scoringScheme) { Collection rows = new ArrayList<>(); From 6d9ec55b35bb89ad70370c198a0246e1c7c9836b Mon Sep 17 00:00:00 2001 From: Axel Uhl Date: Wed, 18 Jul 2018 22:06:36 +0200 Subject: [PATCH 37/43] fixed method name typos Change-Id: Ia30f33192dd896b4c143dddef7f57ff583bf9f82 --- .../LeaderboardScoringAndRankingTestForLowPoints.java | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/java/com.sap.sailing.domain.test/src/com/sap/sailing/domain/test/LeaderboardScoringAndRankingTestForLowPoints.java b/java/com.sap.sailing.domain.test/src/com/sap/sailing/domain/test/LeaderboardScoringAndRankingTestForLowPoints.java index 7c30a687003..56da5855540 100644 --- a/java/com.sap.sailing.domain.test/src/com/sap/sailing/domain/test/LeaderboardScoringAndRankingTestForLowPoints.java +++ b/java/com.sap.sailing.domain.test/src/com/sap/sailing/domain/test/LeaderboardScoringAndRankingTestForLowPoints.java @@ -58,14 +58,12 @@ public class LeaderboardScoringAndRankingTestForLowPoints extends LeaderboardSco private void manuallyTransferCarry(Leaderboard leaderboard, List medalCompetitors) { int carryScore = 1; for (Competitor medalCompetitor : medalCompetitors) { - leaderboard.getScoreCorrection().correctScore(medalCompetitor, leaderboard.getRaceColumnByName("Carry"), - carryScore++); + leaderboard.getScoreCorrection().correctScore(medalCompetitor, leaderboard.getRaceColumnByName("Carry"), carryScore++); } } private Regatta setupRegatta(boolean useFirstTwoWins) { - final BoatClass boatClass = DomainFactory.INSTANCE.getOrCreateBoatClass("470", - /* typicallyStartsUpwind */ true); + final BoatClass boatClass = DomainFactory.INSTANCE.getOrCreateBoatClass("470", /* typicallyStartsUpwind */ true); Regatta regatta = new RegattaImpl(RegattaImpl.getDefaultName("Test Regatta", boatClass.getName()), boatClass, false, /* startDate */ null, /* endDate */ null, series, /* persistent */false, DomainFactory.INSTANCE @@ -442,7 +440,7 @@ public class LeaderboardScoringAndRankingTestForLowPoints extends LeaderboardSco * medalseries. */ @Test - public void noTwoWinsAbortAfterTwoRacesAndTieBraker() throws NoWindException { + public void noTwoWinsAbortAfterTwoRacesAndTieBreaker() throws NoWindException { series = new ArrayList(); // -------- qualification series ------------ setupQualificationSeriesWithOneRaceColumn(); @@ -812,7 +810,7 @@ public class LeaderboardScoringAndRankingTestForLowPoints extends LeaderboardSco * Using normal lowpoints, tie braking is done with manual carry decimals. */ @Test - public void negativeNoTwoWinsAbortAfterTwoRacesAndTieBraker() throws NoWindException { + public void negativeNoTwoWinsAbortAfterTwoRacesAndTieBreaker() throws NoWindException { series = new ArrayList(); // -------- qualification series ------------ setupQualificationSeriesWithOneRaceColumn(); From c3f57fdc9a9f8d5ce748fabff813fbdd6fdf30cb Mon Sep 17 00:00:00 2001 From: Axel Uhl Date: Wed, 18 Jul 2018 22:19:58 +0200 Subject: [PATCH 38/43] added test verdict that actually uses the total rank comparator Change-Id: I0f3bbe837fdf5d69e2d92817e7dc15818805c233 --- .../test/LeaderboardScoringAndRankingTestForLowPoints.java | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/java/com.sap.sailing.domain.test/src/com/sap/sailing/domain/test/LeaderboardScoringAndRankingTestForLowPoints.java b/java/com.sap.sailing.domain.test/src/com/sap/sailing/domain/test/LeaderboardScoringAndRankingTestForLowPoints.java index 56da5855540..e087f731392 100644 --- a/java/com.sap.sailing.domain.test/src/com/sap/sailing/domain/test/LeaderboardScoringAndRankingTestForLowPoints.java +++ b/java/com.sap.sailing.domain.test/src/com/sap/sailing/domain/test/LeaderboardScoringAndRankingTestForLowPoints.java @@ -435,7 +435,7 @@ public class LeaderboardScoringAndRankingTestForLowPoints extends LeaderboardSco } /** - * In this test the no finalist reaches two wins before terminating (eg. due to bad weather) all finalists should be + * In this test no finalist reaches two wins before terminating (eg. due to bad weather) all finalists should be * scored with Low_Points restarting at 0 for the medal series. The non finalists score should not change during the * medalseries. */ @@ -641,7 +641,10 @@ public class LeaderboardScoringAndRankingTestForLowPoints extends LeaderboardSco Assert.assertEquals(10.0, leaderboard.getNetPoints(preFirst, m2later), EPSILON); Assert.assertEquals(18, leaderboard.getNetPoints(preThird, m2later), EPSILON); Assert.assertEquals(24, leaderboard.getNetPoints(preFourth, m2later), EPSILON); - + Assert.assertEquals(1, leaderboard.getTotalRankOfCompetitor(preSecond, m2later)); + Assert.assertEquals(2, leaderboard.getTotalRankOfCompetitor(preFirst, m2later)); + Assert.assertEquals(3, leaderboard.getTotalRankOfCompetitor(preThird, m2later)); + Assert.assertEquals(4, leaderboard.getTotalRankOfCompetitor(preFourth, m2later)); List> afterFinalResults = createCompetitorResultForTimestamp(m2later, leaderboard); assertNonFinalistsAreBehindFinalistsAndNotChanged(preSeriesScoreRankResult, afterFinalResults); } From b2e2beacf195af4c94dfe9116dd181575b2ef8ba Mon Sep 17 00:00:00 2001 From: Axel Uhl Date: Wed, 18 Jul 2018 22:25:21 +0200 Subject: [PATCH 39/43] added more total rank verdicts, improved comments Change-Id: I4d88400ec07de75e0af53fc904f9806f1fcf9cd4 --- ...eaderboardScoringAndRankingTestForLowPoints.java | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/java/com.sap.sailing.domain.test/src/com/sap/sailing/domain/test/LeaderboardScoringAndRankingTestForLowPoints.java b/java/com.sap.sailing.domain.test/src/com/sap/sailing/domain/test/LeaderboardScoringAndRankingTestForLowPoints.java index e087f731392..a33572307d0 100644 --- a/java/com.sap.sailing.domain.test/src/com/sap/sailing/domain/test/LeaderboardScoringAndRankingTestForLowPoints.java +++ b/java/com.sap.sailing.domain.test/src/com/sap/sailing/domain/test/LeaderboardScoringAndRankingTestForLowPoints.java @@ -262,7 +262,8 @@ public class LeaderboardScoringAndRankingTestForLowPoints extends LeaderboardSco /** * In this test the best in the preseries wins the second medal 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. + * not change during the medalseries. Also asserts that during tie-breaking the pre-series carry score takes + * precedence. */ @Test public void testFirstWinsSecondRace() throws NoWindException { @@ -309,10 +310,10 @@ public class LeaderboardScoringAndRankingTestForLowPoints extends LeaderboardSco m1.setTrackedRace(m1.getFleetByName("Default"), m1Default); Assert.assertEquals(3, leaderboard.getNetPoints(preSecond, later), EPSILON); - Assert.assertEquals(3.0, leaderboard.getNetPoints(preFirst, later), EPSILON); + Assert.assertEquals(3, leaderboard.getNetPoints(preFirst, later), EPSILON); Assert.assertEquals(6, leaderboard.getNetPoints(preThird, later), EPSILON); Assert.assertEquals(8, leaderboard.getNetPoints(preFourth, later), EPSILON); - + // assert that during tie-breaking the pre-series carry score takes precedence List res = leaderboard.getCompetitorsFromBestToWorst(later); Assert.assertEquals(res.get(0), preFirst); Assert.assertEquals(res.get(1), preSecond); @@ -427,8 +428,6 @@ public class LeaderboardScoringAndRankingTestForLowPoints extends LeaderboardSco Assert.assertEquals(res2.get(1), preFirst); Assert.assertEquals(res2.get(2), preSecond); Assert.assertEquals(res2.get(3), preThird); - - List> afterFinalResults = createCompetitorResultForTimestamp(m2later, leaderboard); assertNonFinalistsAreBehindFinalistsAndNotChanged(preSeriesScoreRankResult, afterFinalResults); @@ -566,6 +565,10 @@ public class LeaderboardScoringAndRankingTestForLowPoints extends LeaderboardSco Assert.assertEquals(8, leaderboard.getNetPoints(preSecond, later), EPSILON); Assert.assertEquals(12, leaderboard.getNetPoints(preThird, later), EPSILON); Assert.assertEquals(16, leaderboard.getNetPoints(preFourth, later), EPSILON); + Assert.assertEquals(1, leaderboard.getTotalRankOfCompetitor(preFirst, later)); + Assert.assertEquals(2, leaderboard.getTotalRankOfCompetitor(preSecond, later)); + Assert.assertEquals(3, leaderboard.getTotalRankOfCompetitor(preThird, later)); + Assert.assertEquals(4, leaderboard.getTotalRankOfCompetitor(preFourth, later)); List> afterFinalResults = createCompetitorResultForTimestamp(later, leaderboard); assertNonFinalistsAreBehindFinalistsAndNotChanged(preSeriesScoreRankResult, afterFinalResults); From 0d9775fc5caed1c3cb089dfab70f1aa56fe79af5 Mon Sep 17 00:00:00 2001 From: Steffen Schaefer Date: Thu, 19 Jul 2018 10:05:15 +0200 Subject: [PATCH 40/43] Bug 4661: Handles the special case when two competitors reach the target amount of wins necessary. This could e.g. occur while editing score corrections. --- .../impl/LeaderboardTotalRankComparator.java | 28 ++++++++++++------- 1 file changed, 18 insertions(+), 10 deletions(-) mode change 100755 => 100644 java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/impl/LeaderboardTotalRankComparator.java diff --git a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/impl/LeaderboardTotalRankComparator.java b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/impl/LeaderboardTotalRankComparator.java old mode 100755 new mode 100644 index f4d4a00762c..f24050f4d2f --- a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/impl/LeaderboardTotalRankComparator.java +++ b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/impl/LeaderboardTotalRankComparator.java @@ -261,20 +261,28 @@ public class LeaderboardTotalRankComparator implements Comparator { } /** - * Compares by the number of races won in the medal series. If one of the competitors reached the target of races won - * (defined by {@link ScoringScheme#getTargetAmountOfMedalRaceWins()} it is ranked better than the other. If - * none of the competitors reached the target, they are ranked equally even if one has more wins. + * Compares by the number of races won in the medal series. If one of the competitors reached the target of races + * won (defined by {@link ScoringScheme#getTargetAmountOfMedalRaceWins()} it is ranked better than the other. If + * none of the competitors reached the target, they are ranked equally even if one has more wins. This is because + * only reaching the exact number of wins counts for this criteria but not the general comparison by the number of + * wins. If both competitors exactly reached the target, they are also ranked equally (this can e.g. occur while + * entering score corrections). */ private int compareByMedalRacesWon(int numberOfMedalRacesWonO1, int numberOfMedalRacesWonO2) { - // TODO bug4661 clarify what the desired outcome is if (e.g., temporarily due to manual score corrections) both reached or surpassed the number of wins required - final int targetAmount = scoringScheme.getTargetAmountOfMedalRaceWins(); final int result; - if (numberOfMedalRacesWonO1 == targetAmount) { - result = -1; - } else if (numberOfMedalRacesWonO2 == targetAmount) { - result = 1; - } else { + if (numberOfMedalRacesWonO1 == numberOfMedalRacesWonO2) { + // If both competitors have an equal amount of wins it doesn't matter if they reached the target. + // In this case we just can't say who is better based on the number of wins. result = 0; + } else { + final int targetAmount = scoringScheme.getTargetAmountOfMedalRaceWins(); + if (numberOfMedalRacesWonO1 == targetAmount) { + result = -1; + } else if (numberOfMedalRacesWonO2 == targetAmount) { + result = 1; + } else { + result = 0; + } } return result; } From f9d3d16f4b5a12b3ec2be99178f956bdf882875a Mon Sep 17 00:00:00 2001 From: Steffen Schaefer Date: Thu, 19 Jul 2018 10:13:52 +0200 Subject: [PATCH 41/43] Bug 4661: JavaDoc and method naming improvements --- ...oardScoringAndRankingTestForLowPoints.java | 26 +++++++++---------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/java/com.sap.sailing.domain.test/src/com/sap/sailing/domain/test/LeaderboardScoringAndRankingTestForLowPoints.java b/java/com.sap.sailing.domain.test/src/com/sap/sailing/domain/test/LeaderboardScoringAndRankingTestForLowPoints.java index a33572307d0..8bbc958e8b1 100644 --- a/java/com.sap.sailing.domain.test/src/com/sap/sailing/domain/test/LeaderboardScoringAndRankingTestForLowPoints.java +++ b/java/com.sap.sailing.domain.test/src/com/sap/sailing/domain/test/LeaderboardScoringAndRankingTestForLowPoints.java @@ -47,7 +47,7 @@ public class LeaderboardScoringAndRankingTestForLowPoints extends LeaderboardSco () -> createLeaderboard(regatta, discardingThresholds), leaderboardName); } - private void executeRandomPreSeries(List yellow, List blue, TimePoint now) { + private void executePreSeries(List yellow, List blue, TimePoint now) { RaceColumn qColumn = series.get(0).getRaceColumnByName("Q"); TrackedRace qYellow = new MockedTrackedRaceWithStartTimeAndRanks(now, yellow); qColumn.setTrackedRace(qColumn.getFleetByName("Yellow"), qYellow); @@ -139,7 +139,7 @@ public class LeaderboardScoringAndRankingTestForLowPoints extends LeaderboardSco Leaderboard leaderboard = createLeaderboard(regatta, /* discarding thresholds */ new int[0]); TimePoint now = MillisecondsTimePoint.now(); TimePoint later = new MillisecondsTimePoint(now.asMillis() + 1000); - executeRandomPreSeries(yellow, blue, now); + executePreSeries(yellow, blue, now); List preSeriesRankResult = leaderboard.getCompetitorsFromBestToWorst(later); List medalCompetitorsBestToWorst = preSeriesRankResult.subList(0, 4); @@ -195,7 +195,7 @@ public class LeaderboardScoringAndRankingTestForLowPoints extends LeaderboardSco Leaderboard leaderboard = createLeaderboard(regatta, /* discarding thresholds */ new int[0]); TimePoint now = MillisecondsTimePoint.now(); TimePoint later = new MillisecondsTimePoint(now.asMillis() + 1000); - executeRandomPreSeries(yellow, blue, now); + executePreSeries(yellow, blue, now); List preSeriesRankResult = leaderboard.getCompetitorsFromBestToWorst(later); List medalCompetitorsBestToWorst = preSeriesRankResult.subList(0, 4); @@ -282,7 +282,7 @@ public class LeaderboardScoringAndRankingTestForLowPoints extends LeaderboardSco Leaderboard leaderboard = createLeaderboard(regatta, /* discarding thresholds */ new int[0]); TimePoint now = MillisecondsTimePoint.now(); TimePoint later = new MillisecondsTimePoint(now.asMillis() + 1000); - executeRandomPreSeries(yellow, blue, now); + executePreSeries(yellow, blue, now); List preSeriesRankResult = leaderboard.getCompetitorsFromBestToWorst(later); List medalCompetitorsBestToWorst = preSeriesRankResult.subList(0, 4); @@ -368,7 +368,7 @@ public class LeaderboardScoringAndRankingTestForLowPoints extends LeaderboardSco Leaderboard leaderboard = createLeaderboard(regatta, /* discarding thresholds */ new int[0]); TimePoint now = MillisecondsTimePoint.now(); TimePoint later = new MillisecondsTimePoint(now.asMillis() + 1000); - executeRandomPreSeries(yellow, blue, now); + executePreSeries(yellow, blue, now); List preSeriesRankResult = leaderboard.getCompetitorsFromBestToWorst(later); List medalCompetitorsBestToWorst = preSeriesRankResult.subList(0, 4); @@ -455,7 +455,7 @@ public class LeaderboardScoringAndRankingTestForLowPoints extends LeaderboardSco Leaderboard leaderboard = createLeaderboard(regatta, /* discarding thresholds */ new int[0]); TimePoint now = MillisecondsTimePoint.now(); TimePoint later = new MillisecondsTimePoint(now.asMillis() + 1000); - executeRandomPreSeries(yellow, blue, now); + executePreSeries(yellow, blue, now); List preSeriesRankResult = leaderboard.getCompetitorsFromBestToWorst(later); List medalCompetitorsBestToWorst = preSeriesRankResult.subList(0, 4); @@ -516,8 +516,8 @@ public class LeaderboardScoringAndRankingTestForLowPoints extends LeaderboardSco } /** - * Using normal lowpoints, having two wins should not matter, also the racecolum factor is expected to be 2 instead - * of 1. + * Using normal lowpoints, being the best in the preseries and having an additional win in the medals, should not + * make you the overall winner in case another finalist has a better score. */ @Test public void negativeTestFirstPreseriesWinsAgain() throws NoWindException { @@ -536,7 +536,7 @@ public class LeaderboardScoringAndRankingTestForLowPoints extends LeaderboardSco Leaderboard leaderboard = createLeaderboard(regatta, /* discarding thresholds */ new int[0]); TimePoint now = MillisecondsTimePoint.now(); TimePoint later = new MillisecondsTimePoint(now.asMillis() + 1000); - executeRandomPreSeries(yellow, blue, now); + executePreSeries(yellow, blue, now); List preSeriesRankResult = leaderboard.getCompetitorsFromBestToWorst(later); List> preSeriesScoreRankResult = createCompetitorResultForTimestamp(later, @@ -595,7 +595,7 @@ public class LeaderboardScoringAndRankingTestForLowPoints extends LeaderboardSco Leaderboard leaderboard = createLeaderboard(regatta, /* discarding thresholds */ new int[0]); TimePoint now = MillisecondsTimePoint.now(); TimePoint later = new MillisecondsTimePoint(now.asMillis() + 1000); - executeRandomPreSeries(yellow, blue, now); + executePreSeries(yellow, blue, now); List preSeriesRankResult = leaderboard.getCompetitorsFromBestToWorst(later); List medalCompetitorsBestToWorst = preSeriesRankResult.subList(0, 4); @@ -673,7 +673,7 @@ public class LeaderboardScoringAndRankingTestForLowPoints extends LeaderboardSco Leaderboard leaderboard = createLeaderboard(regatta, /* discarding thresholds */ new int[0]); TimePoint now = MillisecondsTimePoint.now(); TimePoint later = new MillisecondsTimePoint(now.asMillis() + 1000); - executeRandomPreSeries(yellow, blue, now); + executePreSeries(yellow, blue, now); List preSeriesRankResult = leaderboard.getCompetitorsFromBestToWorst(later); List medalCompetitorsBestToWorst = preSeriesRankResult.subList(0, 4); @@ -752,7 +752,7 @@ public class LeaderboardScoringAndRankingTestForLowPoints extends LeaderboardSco Leaderboard leaderboard = createLeaderboard(regatta, /* discarding thresholds */ new int[0]); TimePoint now = MillisecondsTimePoint.now(); TimePoint later = new MillisecondsTimePoint(now.asMillis() + 1000); - executeRandomPreSeries(yellow, blue, now); + executePreSeries(yellow, blue, now); List preSeriesRankResult = leaderboard.getCompetitorsFromBestToWorst(later); List medalCompetitorsBestToWorst = preSeriesRankResult.subList(0, 4); @@ -832,7 +832,7 @@ public class LeaderboardScoringAndRankingTestForLowPoints extends LeaderboardSco Leaderboard leaderboard = createLeaderboard(regatta, /* discarding thresholds */ new int[0]); TimePoint now = MillisecondsTimePoint.now(); TimePoint later = new MillisecondsTimePoint(now.asMillis() + 1000); - executeRandomPreSeries(yellow, blue, now); + executePreSeries(yellow, blue, now); List preSeriesRankResult = leaderboard.getCompetitorsFromBestToWorst(later); List medalCompetitorsBestToWorst = preSeriesRankResult.subList(0, 4); From 2580435a5247a441de95d7e2261d69c9615bc4b9 Mon Sep 17 00:00:00 2001 From: Steffen Schaefer Date: Thu, 19 Jul 2018 10:36:45 +0200 Subject: [PATCH 42/43] Bug 4661: Extended the JavaDocs of LowPointFirstToWinTwoRaces to explain all special rules compared to the default LowPoint rules --- .../impl/LowPointFirstToWinTwoRaces.java | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/impl/LowPointFirstToWinTwoRaces.java b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/impl/LowPointFirstToWinTwoRaces.java index e0a376a5bb4..575e652f03b 100644 --- a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/impl/LowPointFirstToWinTwoRaces.java +++ b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/impl/LowPointFirstToWinTwoRaces.java @@ -4,9 +4,19 @@ import com.sap.sailing.domain.base.RaceColumn; import com.sap.sailing.domain.common.ScoringSchemeType; /** - * This class is a derivation of the LowPointScoring scheme. The first participant in the medal series, that wins two - * races is ranked as the first. The participant that has the score 1 in the preSeries carry column only must reach one - * additional victory. This Scheme will change the default scoring factor for medal races to 1, usually 2 is used + * This class is a derivation of the LowPointScoring scheme. The following additional rules apply: + *
    + *
  1. The first participant in the medal series, that wins two races is ranked as the first.
  2. + *
  3. Having 1 point in the carry forward column of the medal series explicitly counts as an additional win which + * requires the winner of the qualification to only need one additional win in the medals.
  4. + *
  5. If none of the participants in the medal series reached the target amount of 2 wins yet, the ranking is done + * based on the points only.
  6. + *
  7. If there is a carry forward column in the medal series, the carry forward points are used as the primary tie + * breaking criteria in case two participants in the medal series have the same overall score.
  8. + *
  9. If there is no carry forward column in the medal series or the carry forward score is not sufficient, the points + * of the last medal race are used as a secondary tie breaking criteria.
  10. + *
  11. This Scheme will change the default scoring factor for medal races to 1, usually 2 is used
  12. + *
      */ public class LowPointFirstToWinTwoRaces extends LowPoint { private static final long serialVersionUID = 7072175334160798617L; From ea92ee34cbf1c8bda6f13741dad6833c3a98a6a1 Mon Sep 17 00:00:00 2001 From: Steffen Schaefer Date: Thu, 19 Jul 2018 10:44:06 +0200 Subject: [PATCH 43/43] Bug 4661: Ensures that having more wins that required also counts as overall winner. If more than one competitor reached the requires wins, the one with more wins will be ranked better. --- .../impl/LeaderboardTotalRankComparator.java | 16 ++++------------ 1 file changed, 4 insertions(+), 12 deletions(-) diff --git a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/impl/LeaderboardTotalRankComparator.java b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/impl/LeaderboardTotalRankComparator.java index f24050f4d2f..5a94b862a3e 100644 --- a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/impl/LeaderboardTotalRankComparator.java +++ b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/impl/LeaderboardTotalRankComparator.java @@ -270,19 +270,11 @@ public class LeaderboardTotalRankComparator implements Comparator { */ private int compareByMedalRacesWon(int numberOfMedalRacesWonO1, int numberOfMedalRacesWonO2) { final int result; - if (numberOfMedalRacesWonO1 == numberOfMedalRacesWonO2) { - // If both competitors have an equal amount of wins it doesn't matter if they reached the target. - // In this case we just can't say who is better based on the number of wins. - result = 0; + final int targetAmount = scoringScheme.getTargetAmountOfMedalRaceWins(); + if (numberOfMedalRacesWonO1 >= targetAmount || numberOfMedalRacesWonO2 >= targetAmount) { + result = Integer.compare(numberOfMedalRacesWonO2, numberOfMedalRacesWonO1); } else { - final int targetAmount = scoringScheme.getTargetAmountOfMedalRaceWins(); - if (numberOfMedalRacesWonO1 == targetAmount) { - result = -1; - } else if (numberOfMedalRacesWonO2 == targetAmount) { - result = 1; - } else { - result = 0; - } + result = 0; } return result; }