* Fixed that players during elemination tournaments could get multiple byes in a row.

This commit is contained in:
LevelX2 2015-10-11 23:55:45 +02:00
parent 01a14a2665
commit a54843fd26
2 changed files with 48 additions and 14 deletions

View file

@ -32,6 +32,7 @@ import java.util.Collection;
import java.util.Date; import java.util.Date;
import java.util.HashMap; import java.util.HashMap;
import java.util.HashSet; import java.util.HashSet;
import java.util.Iterator;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Random; import java.util.Random;
@ -187,15 +188,16 @@ public abstract class TournamentImpl implements Tournament {
Round round = new Round(rounds.size() + 1, this); Round round = new Round(rounds.size() + 1, this);
rounds.add(round); rounds.add(round);
List<TournamentPlayer> roundPlayers = getActivePlayers(); List<TournamentPlayer> roundPlayers = getActivePlayers();
// search the player with a bye last round
List<TournamentPlayer> playerWithByes = getTournamentPlayersWithBye(roundPlayers);
while (roundPlayers.size() > 1) { while (roundPlayers.size() > 1) {
int i = rnd.nextInt(roundPlayers.size()); TournamentPlayer player1 = getNextAvailablePlayer(roundPlayers, playerWithByes);
TournamentPlayer player1 = roundPlayers.get(i); TournamentPlayer player2 = getNextAvailablePlayer(roundPlayers, playerWithByes);
roundPlayers.remove(i);
i = rnd.nextInt(roundPlayers.size());
TournamentPlayer player2 = roundPlayers.get(i);
roundPlayers.remove(i);
round.addPairing(new TournamentPairing(player1, player2)); round.addPairing(new TournamentPairing(player1, player2));
} }
if (roundPlayers.size() > 0) { if (roundPlayers.size() > 0) {
// player free round - add to bye players of this round // player free round - add to bye players of this round
TournamentPlayer player1 = roundPlayers.get(0); TournamentPlayer player1 = roundPlayers.get(0);
@ -207,6 +209,37 @@ public abstract class TournamentImpl implements Tournament {
return round; return round;
} }
private TournamentPlayer getNextAvailablePlayer(List<TournamentPlayer> roundPlayers, List<TournamentPlayer> playerWithByes) {
TournamentPlayer nextPlayer;
if (playerWithByes.isEmpty()) {
int i = rnd.nextInt(roundPlayers.size());
nextPlayer = roundPlayers.get(i);
roundPlayers.remove(i);
} else { // prefer players with byes to pair
Iterator<TournamentPlayer> iterator = playerWithByes.iterator();
nextPlayer = iterator.next();
iterator.remove();
roundPlayers.remove(nextPlayer);
}
return nextPlayer;
}
private List<TournamentPlayer> getTournamentPlayersWithBye(List<TournamentPlayer> roundPlayers) {
List<TournamentPlayer> playersWithBye = new ArrayList<>();
if (rounds.size() > 1) {
for (int i = rounds.size() - 2; i >= 0; i--) {
Round oldRound = rounds.get(i);
if (oldRound != null && !oldRound.getPlayerByes().isEmpty()) {
TournamentPlayer tournamentPlayerWithBye = oldRound.getPlayerByes().iterator().next();
if (roundPlayers.contains(tournamentPlayerWithBye)) {
playersWithBye.add(tournamentPlayerWithBye);
}
}
}
}
return playersWithBye;
}
protected void playRound(Round round) { protected void playRound(Round round) {
for (TournamentPairing pair : round.getPairs()) { for (TournamentPairing pair : round.getPairs()) {
playMatch(pair); playMatch(pair);

View file

@ -46,8 +46,8 @@ public abstract class TournamentSwiss extends TournamentImpl {
} }
@Override @Override
protected void runTournament() { protected void runTournament() {
for (Map.Entry<UUID, TournamentPlayer> entry: players.entrySet()) { for (Map.Entry<UUID, TournamentPlayer> entry : players.entrySet()) {
if (entry.getValue().getPlayer().autoLoseGame()) { if (entry.getValue().getPlayer().autoLoseGame()) {
entry.getValue().setEliminated(); entry.getValue().setEliminated();
entry.getValue().setResults("Auto Eliminated"); entry.getValue().setResults("Auto Eliminated");
@ -57,7 +57,7 @@ public abstract class TournamentSwiss extends TournamentImpl {
while (this.getActivePlayers().size() > 1 && this.getNumberRounds() > this.getRounds().size()) { while (this.getActivePlayers().size() > 1 && this.getNumberRounds() > this.getRounds().size()) {
// check if some player got killed / disconnected meanwhile and update their state // check if some player got killed / disconnected meanwhile and update their state
tableEventSource.fireTableEvent(TableEvent.EventType.CHECK_STATE_PLAYERS); tableEventSource.fireTableEvent(TableEvent.EventType.CHECK_STATE_PLAYERS);
// Swiss pairing // Swiss pairing
Round round = createRoundSwiss(); Round round = createRoundSwiss();
playRound(round); playRound(round);
} }
@ -70,8 +70,9 @@ public abstract class TournamentSwiss extends TournamentImpl {
List<TournamentPlayer> roundPlayers = getActivePlayers(); List<TournamentPlayer> roundPlayers = getActivePlayers();
// sort players by tournament points // sort players by tournament points
Collections.sort(roundPlayers, new Comparator<TournamentPlayer>() { Collections.sort(roundPlayers, new Comparator<TournamentPlayer>() {
@Override public int compare(TournamentPlayer p1, TournamentPlayer p2) { @Override
return p2.getPoints() - p1.getPoints(); public int compare(TournamentPlayer p1, TournamentPlayer p2) {
return p2.getPoints() - p1.getPoints();
} }
}); });
@ -80,9 +81,9 @@ public abstract class TournamentSwiss extends TournamentImpl {
TournamentPlayer player1 = roundPlayers.get(0); TournamentPlayer player1 = roundPlayers.get(0);
roundPlayers.remove(0); roundPlayers.remove(0);
TournamentPlayer playerForPossibleSecondPairing = null; TournamentPlayer playerForPossibleSecondPairing = null;
for (TournamentPlayer player2: roundPlayers) { for (TournamentPlayer player2 : roundPlayers) {
if (alreadyPaired(player1, player2)) { if (alreadyPaired(player1, player2)) {
// if laready paired but equal ponts -> remember if second pairing is needed // if already paired but equal points -> remember if second pairing is needed
if (playerForPossibleSecondPairing == null) { if (playerForPossibleSecondPairing == null) {
playerForPossibleSecondPairing = player2; playerForPossibleSecondPairing = player2;
} }
@ -126,7 +127,7 @@ public abstract class TournamentSwiss extends TournamentImpl {
protected boolean alreadyPaired(TournamentPlayer player1, TournamentPlayer player2) { protected boolean alreadyPaired(TournamentPlayer player1, TournamentPlayer player2) {
for (Round round : rounds) { for (Round round : rounds) {
for (TournamentPairing pairing: round.getPairs()) { for (TournamentPairing pairing : round.getPairs()) {
if (pairing.getPlayer1().equals(player1) || pairing.getPlayer2().equals(player1)) { if (pairing.getPlayer1().equals(player1) || pairing.getPlayer2().equals(player1)) {
if (pairing.getPlayer1().equals(player2) || pairing.getPlayer2().equals(player2)) { if (pairing.getPlayer1().equals(player2) || pairing.getPlayer2().equals(player2)) {
return true; return true;