Fixed head-to-head face-off comparison being sorted backwards. Fixed median calculation dropping the wrong score.

This commit is contained in:
Christian 'ketura' McCarty
2024-08-24 18:29:24 -05:00
parent f84c8eb206
commit 40fdb6271e
2 changed files with 17 additions and 29 deletions

View File

@@ -14,10 +14,10 @@ public class ModifiedMedianStandingsProducer {
private static final Comparator<PlayerStanding> MEDIAN_STANDING_COMPARATOR = private static final Comparator<PlayerStanding> MEDIAN_STANDING_COMPARATOR =
new MultipleComparator<>( new MultipleComparator<>(
new DescComparator<>(Comparator.comparingInt(x -> x.points)), new DescComparator<>(Comparator.comparingInt(x -> x.points)),
FACE_OFF_COMPARATOR, new DescComparator<>(FACE_OFF_COMPARATOR),
new DescComparator<>(Comparator.comparingInt(x -> x.medianScore)), new DescComparator<>(Comparator.comparingInt(x -> x.medianScore)),
new DescComparator<>(Comparator.comparingInt(x -> x.cumulativeScore)), new DescComparator<>(Comparator.comparingInt(x -> x.cumulativeScore)),
new DescComparator<>(new OpponentsWinComparator())); new DescComparator<>(Comparator.comparingDouble(x -> x.opponentWinRate)));
public static List<PlayerStanding> produceStandings(Collection<String> participants, Collection<TournamentMatch> matches, public static List<PlayerStanding> produceStandings(Collection<String> participants, Collection<TournamentMatch> matches,
@@ -108,13 +108,15 @@ public class ModifiedMedianStandingsProducer {
opponentGames += playerWinCounts.get(opponent).intValue() + playerLossCounts.get(opponent).intValue(); opponentGames += playerWinCounts.get(opponent).intValue() + playerLossCounts.get(opponent).intValue();
} }
Collections.sort(oppScores, Collections.reverseOrder()); oppScores.sort(Collections.reverseOrder());
float playerscore = (float) playerWins / gamesPlayed;
float opponentWR = 0f; float opponentWR = 0f;
if (opponentGames != 0) { if (opponentGames != 0) {
opponentWR = opponentWins * 1f / opponentGames; opponentWR = opponentWins * 1f / opponentGames;
} }
//List of opponent scores is now sorted such that the first entry is the highest score, and the last entry
// is the lowest score. We will drop one or more of those positions based on the player's performance:
if(gamesPlayed > 0) { if(gamesPlayed > 0) {
if(playerWins == playerLosses) { // i.e. that player has a 50% win rate; this eliminates floating point comparisons if(playerWins == playerLosses) { // i.e. that player has a 50% win rate; this eliminates floating point comparisons
if(oppScores.size() > 1) { if(oppScores.size() > 1) {
@@ -125,16 +127,16 @@ public class ModifiedMedianStandingsProducer {
oppScores.removeFirst(); oppScores.removeFirst();
} }
} }
else if(playerscore > 0.5f) { else if(playerWins > playerLosses) {
if(oppScores.size() > 1) {
oppScores.removeFirst();
}
}
else { //playerscore < 50% win rate
if(oppScores.size() > 1) { if(oppScores.size() > 1) {
oppScores.removeLast(); oppScores.removeLast();
} }
} }
else { //playerWins < playerLosses
if(oppScores.size() > 1) {
oppScores.removeFirst();
}
}
} }
int median = 0; int median = 0;
@@ -184,20 +186,6 @@ public class ModifiedMedianStandingsProducer {
} }
private static class OpponentsWinComparator implements Comparator<PlayerStanding> {
@Override
public int compare(PlayerStanding o1, PlayerStanding o2) {
final float diff = o1.opponentWinRate - o2.opponentWinRate;
if (diff < 0) {
return -1;
}
if (diff > 0) {
return 1;
}
return 0;
}
}
private static class FaceOffComparator implements Comparator<PlayerStanding> { private static class FaceOffComparator implements Comparator<PlayerStanding> {
public Collection<? extends CompetitiveMatchResult> matches; public Collection<? extends CompetitiveMatchResult> matches;

View File

@@ -22,8 +22,8 @@ import java.util.concurrent.locks.ReentrantReadWriteLock;
public class DefaultTournament implements Tournament { public class DefaultTournament implements Tournament {
// 10 minutes // 10 minutes
private final int _deckBuildTime = 10 * 60 * 1000; public static int DeckBuildTime = 10 * 60 * 1000;
private long _waitForPairingsTime = 1000 * 60 * 1; public static long PairingDelayTime = 1000 * 60 * 1;
private final PairingMechanism _pairingMechanism; private final PairingMechanism _pairingMechanism;
private final TournamentPrizes _tournamentPrizes; private final TournamentPrizes _tournamentPrizes;
@@ -145,7 +145,7 @@ public class DefaultTournament implements Tournament {
} }
public void setWaitForPairingsTime(long waitForPairingsTime) { public void setWaitForPairingsTime(long waitForPairingsTime) {
_waitForPairingsTime = waitForPairingsTime; PairingDelayTime = waitForPairingsTime;
} }
@Override @Override
@@ -303,7 +303,7 @@ public class DefaultTournament implements Tournament {
} }
} }
if (_tournamentStage == Stage.DECK_BUILDING) { if (_tournamentStage == Stage.DECK_BUILDING) {
if (_deckBuildStartTime + _deckBuildTime < System.currentTimeMillis() if (_deckBuildStartTime + DeckBuildTime < System.currentTimeMillis()
|| _playerDecks.size() == _players.size()) { || _playerDecks.size() == _players.size()) {
_tournamentStage = Stage.PLAYING_GAMES; _tournamentStage = Stage.PLAYING_GAMES;
_tournamentService.updateTournamentStage(_tournamentId, _tournamentStage); _tournamentService.updateTournamentStage(_tournamentId, _tournamentStage);
@@ -426,7 +426,7 @@ public class DefaultTournament implements Tournament {
} }
private class PairPlayers implements TournamentTask { private class PairPlayers implements TournamentTask {
private final long _taskStart = System.currentTimeMillis() + _waitForPairingsTime; private final long _taskStart = System.currentTimeMillis() + PairingDelayTime;
@Override @Override
public void executeTask(TournamentCallback tournamentCallback, CollectionsManager collectionsManager) { public void executeTask(TournamentCallback tournamentCallback, CollectionsManager collectionsManager) {