Working on swiss pairing algorithm.

This commit is contained in:
marcins78
2013-01-02 18:25:18 +00:00
parent a1b531d122
commit ab00e0ec0d
3 changed files with 134 additions and 2 deletions

View File

@@ -308,7 +308,10 @@ public class DefaultTournament implements Tournament {
_tournamentService.updateTournamentRound(_tournamentId, _tournamentRound);
Map<String, String> pairingResults = new HashMap<String, String>();
Set<String> byeResults = new HashSet<String>();
boolean finished = _pairingMechanism.pairPlayers(_tournamentRound, _players, _droppedPlayers, _playerByes, getCurrentStandings(), pairingResults, byeResults);
Map<String, Set<String>> previouslyPaired = getPreviouslyPairedPlayersMap();
boolean finished = _pairingMechanism.pairPlayers(_tournamentRound, _players, _droppedPlayers, _playerByes, getCurrentStandings(), previouslyPaired, pairingResults, byeResults);
if (finished) {
finishTournament(tournamentCallback, collectionsManager);
} else {
@@ -328,6 +331,18 @@ public class DefaultTournament implements Tournament {
}
}
private Map<String, Set<String>> getPreviouslyPairedPlayersMap() {
Map<String, Set<String>> previouslyPaired = new HashMap<String, Set<String>>();
for (String player : _players)
previouslyPaired.put(player, new HashSet<String>());
for (TournamentMatch finishedTournamentMatch : _finishedTournamentMatches) {
previouslyPaired.get(finishedTournamentMatch.getWinner()).add(finishedTournamentMatch.getLoser());
previouslyPaired.get(finishedTournamentMatch.getLoser()).add(finishedTournamentMatch.getWinner());
}
return previouslyPaired;
}
private void addPlayerBye(String player) {
Integer byes = _playerByes.get(player);
if (byes == null)

View File

@@ -11,7 +11,8 @@ public interface PairingMechanism {
public boolean isFinished(int round, Set<String> players, Set<String> droppedPlayers);
public boolean pairPlayers(int round, Set<String> players, Set<String> droppedPlayers, Map<String, Integer> playerByes, List<PlayerStanding> currentStandings, Map<String, String> pairingResults, Set<String> byeResults);
public boolean pairPlayers(int round, Set<String> players, Set<String> droppedPlayers, Map<String, Integer> playerByes,
List<PlayerStanding> currentStandings, Map<String, Set<String>> previouslyPaired, Map<String, String> pairingResults, Set<String> byeResults);
public String getPlayOffSystem();
}

View File

@@ -0,0 +1,116 @@
package com.gempukku.lotro.tournament;
import com.gempukku.lotro.competitive.PlayerStanding;
import java.util.*;
public class SwissPairingMechanism implements PairingMechanism {
@Override
public String getPlayOffSystem() {
return "Swiss";
}
@Override
public boolean shouldDropLoser() {
return false;
}
@Override
public boolean isFinished(int round, Set<String> players, Set<String> droppedPlayers) {
return round >= getRoundCountBasedOnNumberOfPlayers(players.size());
}
@Override
public boolean pairPlayers(int round, Set<String> players, Set<String> droppedPlayers, Map<String, Integer> playerByes, List<PlayerStanding> currentStandings,
Map<String, Set<String>> previouslyPaired, Map<String, String> pairingResults, Set<String> byeResults) {
int maxNumberOfPoints = determineMaximumNumberOfPoints(droppedPlayers, currentStandings);
List<List<String>> playersGroupedByBracket = groupPlayersByPointBracket(droppedPlayers, currentStandings, maxNumberOfPoints);
shufflePlayersWithinBrackets(playersGroupedByBracket);
Set<String> playersWithByes = getPlayersWithByes(playerByes);
boolean success = tryPairBracketAndFurther(0, new HashSet<String>(), playersGroupedByBracket, playersWithByes, previouslyPaired, pairingResults, byeResults);
// Managed to pair with this carry over count - proceed with the pairings
if (success)
return false;
// We can't pair, just finish the tournament
return true;
}
private boolean tryPairBracketAndFurther(int bracketIndex, Set<String> carryOverPlayers, List<List<String>> playersGroupedByBracket, Set<String> playersWithByes,
Map<String, Set<String>> previouslyPaired, Map<String, String> pairingsResult, Set<String> byes) {
for (int carryOverMax = 0; carryOverMax < 4; carryOverMax++) {
boolean success = tryPairBracketWithCarryOverMax(bracketIndex, carryOverMax, playersGroupedByBracket, playersWithByes, previouslyPaired, pairingsResult, pairingsResult, byes);
if (success)
return true;
}
return false;
}
private boolean tryPairBracketWithCarryOverMax(int bracketIndex, int carryOverMax, List<List<String>> playersGroupedByPoints, Set<String> playersWithByes,
Map<String, Set<String>> previouslyPaired, Map<String, String> pairingsResult,
Map<String, String> pairingsResult1, Set<String> byes) {
// TODO
return true;
}
private Set<String> getPlayersWithByes(Map<String, Integer> playerByes) {
Set<String> playersWithByes = new HashSet<String>();
for (Map.Entry<String, Integer> playerByeCount : playerByes.entrySet()) {
if (playerByeCount.getValue() != null && playerByeCount.getValue() > 0)
playersWithByes.add(playerByeCount.getKey());
}
return playersWithByes;
}
private void shufflePlayersWithinBrackets(List<List<String>> playersGroupedByPoints) {
for (List<String> playersByPoint : playersGroupedByPoints)
Collections.shuffle(playersByPoint);
}
private List<List<String>> groupPlayersByPointBracket(Set<String> droppedPlayers, List<PlayerStanding> currentStandings, int maxNumberOfPoints) {
List<String>[] playersByPoints = new List[maxNumberOfPoints + 1];
for (PlayerStanding currentStanding : currentStandings) {
String playerName = currentStanding.getPlayerName();
if (!droppedPlayers.contains(playerName)) {
int points = currentStanding.getPoints();
List<String> playersByPoint = playersByPoints[maxNumberOfPoints - points];
if (playersByPoint == null) {
playersByPoint = new ArrayList<String>();
playersByPoints[maxNumberOfPoints - points] = playersByPoint;
}
playersByPoint.add(playerName);
}
}
List<List<String>> result = new ArrayList<List<String>>();
for (List<String> playersByPoint : playersByPoints) {
if (playersByPoint != null)
result.add(playersByPoint);
}
return result;
}
private int determineMaximumNumberOfPoints(Set<String> droppedPlayers, List<PlayerStanding> currentStandings) {
int maxNumberOfPoints = 0;
for (PlayerStanding currentStanding : currentStandings) {
if (!droppedPlayers.contains(currentStanding.getPlayerName()))
maxNumberOfPoints = Math.max(currentStanding.getPoints(), maxNumberOfPoints);
}
return maxNumberOfPoints;
}
private static int getRoundCountBasedOnNumberOfPlayers(int numberOfPlayers) {
return (int) (Math.ceil(Math.log(numberOfPlayers) / Math.log(2))) + 1;
}
public static void main(String[] args) {
for (int i = 1; i <= 128; i++) {
System.out.println("i=" + i + " - " + getRoundCountBasedOnNumberOfPlayers(i));
}
}
}