mirror of
https://github.com/correl/mage.git
synced 2025-04-10 09:11:04 -09:00
Fix Swiss pairing for the case when some players have left the tournament
This commit is contained in:
parent
85bb13b6d8
commit
486d547f5e
2 changed files with 114 additions and 19 deletions
Mage.Tests/src/test/java/org/mage/test/serverside/tournament
Mage/src/mage/game/tournament/pairing
|
@ -82,6 +82,7 @@ public class SwissPairingMinimalWeightMatchingTest {
|
||||||
|
|
||||||
CheckPair(roundPairings.getPairings(), player1, player2);
|
CheckPair(roundPairings.getPairings(), player1, player2);
|
||||||
CheckPair(roundPairings.getPairings(), player3, player4);
|
CheckPair(roundPairings.getPairings(), player3, player4);
|
||||||
|
Assert.assertEquals(0, roundPairings.getPlayerByes().size());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -131,6 +132,46 @@ public class SwissPairingMinimalWeightMatchingTest {
|
||||||
|
|
||||||
CheckPair(roundPairings.getPairings(), player1, player4);
|
CheckPair(roundPairings.getPairings(), player1, player4);
|
||||||
CheckPair(roundPairings.getPairings(), player2, player3);
|
CheckPair(roundPairings.getPairings(), player2, player3);
|
||||||
|
Assert.assertEquals(0, roundPairings.getPlayerByes().size());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void PlayerLeftTournamentAfterFirstRound() {
|
||||||
|
// 1 > 3
|
||||||
|
// 2 > 4
|
||||||
|
// 4 left the tournament
|
||||||
|
|
||||||
|
TournamentPlayer player1 = new TournamentPlayer(new PlayerStub(), null);
|
||||||
|
TournamentPlayer player2 = new TournamentPlayer(new PlayerStub(), null);
|
||||||
|
TournamentPlayer player3 = new TournamentPlayer(new PlayerStub(), null);
|
||||||
|
TournamentPlayer player4 = new TournamentPlayer(new PlayerStub(), null);
|
||||||
|
List<TournamentPlayer> players = new ArrayList<>();
|
||||||
|
//players.add(player4); -- player 4 is not active
|
||||||
|
players.add(player2);
|
||||||
|
players.add(player3);
|
||||||
|
players.add(player1);
|
||||||
|
|
||||||
|
player1.setPoints(3);
|
||||||
|
player2.setPoints(3);
|
||||||
|
player3.setPoints(0);
|
||||||
|
player4.setPoints(0);
|
||||||
|
|
||||||
|
List<Round> rounds = new ArrayList<>();
|
||||||
|
Round round = new Round(1, new TournamentStub());
|
||||||
|
TournamentPairing pair1 = new TournamentPairing(player1, player3);
|
||||||
|
round.addPairing(pair1);
|
||||||
|
TournamentPairing pair2 = new TournamentPairing(player4, player2);
|
||||||
|
round.addPairing(pair2);
|
||||||
|
rounds.add(round);
|
||||||
|
|
||||||
|
SwissPairingMinimalWeightMatching swissPairing = new SwissPairingMinimalWeightMatching(players, rounds);
|
||||||
|
RoundPairings roundPairings = swissPairing.getRoundPairings();
|
||||||
|
|
||||||
|
Assert.assertEquals(1, roundPairings.getPairings().size());
|
||||||
|
Assert.assertEquals(1, roundPairings.getPlayerByes().size());
|
||||||
|
|
||||||
|
CheckPair(roundPairings.getPairings(), player1, player2);
|
||||||
|
Assert.assertTrue(roundPairings.getPlayerByes().contains(player3));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -190,6 +231,53 @@ public class SwissPairingMinimalWeightMatchingTest {
|
||||||
Assert.assertTrue(roundPairings.getPlayerByes().contains(player3));
|
Assert.assertTrue(roundPairings.getPlayerByes().contains(player3));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void PlayerWithByeLeftTournament() {
|
||||||
|
// 1 > 2
|
||||||
|
// 3 > 4
|
||||||
|
// 5
|
||||||
|
// 5 left the tournament
|
||||||
|
|
||||||
|
|
||||||
|
TournamentPlayer player1 = new TournamentPlayer(new PlayerStub(), null);
|
||||||
|
TournamentPlayer player2 = new TournamentPlayer(new PlayerStub(), null);
|
||||||
|
TournamentPlayer player3 = new TournamentPlayer(new PlayerStub(), null);
|
||||||
|
TournamentPlayer player4 = new TournamentPlayer(new PlayerStub(), null);
|
||||||
|
TournamentPlayer player5 = new TournamentPlayer(new PlayerStub(), null);
|
||||||
|
List<TournamentPlayer> players = new ArrayList<>();
|
||||||
|
//players.add(player5); -- player 5 is not active
|
||||||
|
players.add(player4);
|
||||||
|
players.add(player2);
|
||||||
|
players.add(player3);
|
||||||
|
players.add(player1);
|
||||||
|
|
||||||
|
player1.setPoints(3);
|
||||||
|
player2.setPoints(0);
|
||||||
|
player3.setPoints(3);
|
||||||
|
player4.setPoints(0);
|
||||||
|
player5.setPoints(3);
|
||||||
|
|
||||||
|
List<Round> rounds = new ArrayList<>();
|
||||||
|
// first round
|
||||||
|
Round round = new Round(1, new TournamentStub());
|
||||||
|
TournamentPairing pair1 = new TournamentPairing(player1, player2);
|
||||||
|
round.addPairing(pair1);
|
||||||
|
TournamentPairing pair2 = new TournamentPairing(player3, player4);
|
||||||
|
round.addPairing(pair2);
|
||||||
|
round.getPlayerByes().add(player5);
|
||||||
|
rounds.add(round);
|
||||||
|
|
||||||
|
SwissPairingMinimalWeightMatching swissPairing = new SwissPairingMinimalWeightMatching(players, rounds);
|
||||||
|
RoundPairings roundPairings = swissPairing.getRoundPairings();
|
||||||
|
|
||||||
|
Assert.assertEquals(2, roundPairings.getPairings().size());
|
||||||
|
Assert.assertEquals(0, roundPairings.getPlayerByes().size());
|
||||||
|
|
||||||
|
CheckPair(roundPairings.getPairings(), player1, player3);
|
||||||
|
CheckPair(roundPairings.getPairings(), player2, player4);
|
||||||
|
Assert.assertEquals(0, roundPairings.getPlayerByes().size());
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void SimulateDifferentTournaments() {
|
public void SimulateDifferentTournaments() {
|
||||||
int playersCount = 12;
|
int playersCount = 12;
|
||||||
|
|
|
@ -61,20 +61,19 @@ public class SwissPairingMinimalWeightMatching {
|
||||||
playersCount = players.size();
|
playersCount = players.size();
|
||||||
|
|
||||||
swissPlayers = new ArrayList<PlayerInfo>();
|
swissPlayers = new ArrayList<PlayerInfo>();
|
||||||
for (int i = 0; i < playersCount; i++) {
|
for (TournamentPlayer tournamentPlayer : players) {
|
||||||
PlayerInfo swissPlayer = new PlayerInfo();
|
PlayerInfo swissPlayer = new PlayerInfo();
|
||||||
swissPlayer.tournamentPlayer = players.get(i);
|
swissPlayer.tournamentPlayer = tournamentPlayer;
|
||||||
swissPlayer.playerId = players.get(i).getPlayer().getId();
|
swissPlayer.points = tournamentPlayer.getPoints();
|
||||||
swissPlayer.points = players.get(i).getPoints();
|
|
||||||
swissPlayers.add(swissPlayer);
|
swissPlayers.add(swissPlayer);
|
||||||
}
|
}
|
||||||
|
|
||||||
// shuffle players first to add some randomness
|
// shuffle players first to add some randomness
|
||||||
Collections.shuffle(swissPlayers);
|
Collections.shuffle(swissPlayers);
|
||||||
Map<UUID, Integer> map = new HashMap<>();
|
Map<TournamentPlayer, Integer> map = new HashMap<>();
|
||||||
for (int i = 0; i < playersCount; i++) {
|
for (int i = 0; i < playersCount; i++) {
|
||||||
swissPlayers.get(i).id = i;
|
swissPlayers.get(i).id = i;
|
||||||
map.put(swissPlayers.get(i).playerId, i);
|
map.put(swissPlayers.get(i).tournamentPlayer, i);
|
||||||
}
|
}
|
||||||
|
|
||||||
// calculate Tie Breaker points -- Sum of Opponents' Scores (SOS)
|
// calculate Tie Breaker points -- Sum of Opponents' Scores (SOS)
|
||||||
|
@ -84,11 +83,16 @@ public class SwissPairingMinimalWeightMatching {
|
||||||
TournamentPlayer player1 = pairing.getPlayer1();
|
TournamentPlayer player1 = pairing.getPlayer1();
|
||||||
TournamentPlayer player2 = pairing.getPlayer2();
|
TournamentPlayer player2 = pairing.getPlayer2();
|
||||||
|
|
||||||
int id1 = map.get(player1.getPlayer().getId());
|
Integer id1 = map.get(player1);
|
||||||
int id2 = map.get(player2.getPlayer().getId());
|
Integer id2 = map.get(player2);
|
||||||
|
|
||||||
swissPlayers.get(id1).sosPoints += player2.getPoints();
|
// a player could have left the tournament, so we should check if id is not null
|
||||||
swissPlayers.get(id2).sosPoints += player1.getPoints();
|
if (id1 != null) {
|
||||||
|
swissPlayers.get(id1).sosPoints += player2.getPoints();
|
||||||
|
}
|
||||||
|
if (id2 != null) {
|
||||||
|
swissPlayers.get(id2).sosPoints += player1.getPoints();
|
||||||
|
}
|
||||||
// todo: sos points for byes? maybe add player points?
|
// todo: sos points for byes? maybe add player points?
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -106,9 +110,10 @@ public class SwissPairingMinimalWeightMatching {
|
||||||
});
|
});
|
||||||
|
|
||||||
// order could be changed, update ids and mapping
|
// order could be changed, update ids and mapping
|
||||||
|
map.clear();
|
||||||
for (int i = 0; i < playersCount; i++) {
|
for (int i = 0; i < playersCount; i++) {
|
||||||
swissPlayers.get(i).id = i;
|
swissPlayers.get(i).id = i;
|
||||||
map.put(swissPlayers.get(i).playerId, i);
|
map.put(swissPlayers.get(i).tournamentPlayer, i);
|
||||||
}
|
}
|
||||||
|
|
||||||
// count ties and matches between players
|
// count ties and matches between players
|
||||||
|
@ -119,15 +124,19 @@ public class SwissPairingMinimalWeightMatching {
|
||||||
TournamentPlayer player1 = pairing.getPlayer1();
|
TournamentPlayer player1 = pairing.getPlayer1();
|
||||||
TournamentPlayer player2 = pairing.getPlayer2();
|
TournamentPlayer player2 = pairing.getPlayer2();
|
||||||
|
|
||||||
int id1 = map.get(player1.getPlayer().getId());
|
Integer id1 = map.get(player1);
|
||||||
int id2 = map.get(player2.getPlayer().getId());
|
Integer id2 = map.get(player2);
|
||||||
|
|
||||||
duels[id1][id2]++;
|
if (id1 != null && id2 != null) {
|
||||||
duels[id2][id1]++;
|
duels[id1][id2]++;
|
||||||
|
duels[id2][id1]++;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
for (TournamentPlayer playerBye : round.getPlayerByes()) {
|
for (TournamentPlayer playerBye : round.getPlayerByes()) {
|
||||||
int id = map.get(playerBye.getPlayer().getId());
|
Integer id = map.get(playerBye);
|
||||||
byes[id]++;
|
if (id != null) {
|
||||||
|
byes[id]++;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -273,8 +282,6 @@ public class SwissPairingMinimalWeightMatching {
|
||||||
|
|
||||||
public TournamentPlayer tournamentPlayer;
|
public TournamentPlayer tournamentPlayer;
|
||||||
|
|
||||||
public UUID playerId;
|
|
||||||
|
|
||||||
public int points;
|
public int points;
|
||||||
|
|
||||||
public int sosPoints;
|
public int sosPoints;
|
||||||
|
|
Loading…
Add table
Reference in a new issue