From 17c9f4e685af60a64d2e4f6518f95a2dc49c71cb Mon Sep 17 00:00:00 2001 From: Michel ten Voorde Date: Wed, 6 Nov 2024 18:06:47 +0100 Subject: [PATCH] Prevent players playing one 1 event from getting drawn out --- .../swiss/domain/entity/Tournament.java | 16 ++++++++++++++++ .../swiss/service/TournamentDrawService.java | 14 ++++++++++---- .../swiss/service/TournamentPlayService.java | 5 +++-- 3 files changed, 29 insertions(+), 6 deletions(-) diff --git a/src/main/java/nl/connectedit/swiss/domain/entity/Tournament.java b/src/main/java/nl/connectedit/swiss/domain/entity/Tournament.java index 60425f8..7bd4f83 100644 --- a/src/main/java/nl/connectedit/swiss/domain/entity/Tournament.java +++ b/src/main/java/nl/connectedit/swiss/domain/entity/Tournament.java @@ -1,7 +1,9 @@ package nl.connectedit.swiss.domain.entity; import jakarta.persistence.*; +import java.util.HashMap; import java.util.HashSet; +import java.util.Map; import lombok.Getter; import lombok.Setter; import nl.connectedit.swiss.domain.EventType; @@ -91,4 +93,18 @@ public class Tournament extends AbstractEntity { var drawnOutPlayers = this.getDrawnOutPlayers(); return drawnOutPlayers.size() == new HashSet<>(drawnOutPlayers).size(); } + + public List getPlayersPlayingOnlyOneEvent() { + var playerEvents = new HashMap>(); + for (var registration : getRegistrations()) { + if (!playerEvents.containsKey(registration.getPlayer())) { + playerEvents.put(registration.getPlayer(), new ArrayList<>()); + } + playerEvents.get(registration.getPlayer()).add(registration.getEvent().getType()); + } + return playerEvents.entrySet().stream() + .filter(entry -> entry.getValue().size() == 1) + .map(Map.Entry::getKey) + .toList(); + } } diff --git a/src/main/java/nl/connectedit/swiss/service/TournamentDrawService.java b/src/main/java/nl/connectedit/swiss/service/TournamentDrawService.java index 1664d39..1586bc0 100644 --- a/src/main/java/nl/connectedit/swiss/service/TournamentDrawService.java +++ b/src/main/java/nl/connectedit/swiss/service/TournamentDrawService.java @@ -25,7 +25,7 @@ public class TournamentDrawService { round.setName("Ronde 1"); round.setGroup(group); do { - round.setMatches(createMatchList(group, round)); + round.setMatches(createMatchList(tournament, group, round)); } while (!tournament.hasPlayersDrawnOutMaxOnce()); round.setStatus(Status.NOT_STARTED); } @@ -87,7 +87,7 @@ public class TournamentDrawService { return tournament; } - private List createMatchList(Group group, Round round) { + private List createMatchList(Tournament tournament, Group group, Round round) { List matches; var drawCounter = 0; do { @@ -112,12 +112,18 @@ public class TournamentDrawService { match.setRound(round); matches.add(match); } - } while (!drawIsValid(matches) || drawCounter == 1000); + } while (!drawIsValid(tournament, matches, round) || drawCounter == 1000); return matches; } - private boolean drawIsValid(List matches) { + private boolean drawIsValid(Tournament tournament, List matches, Round round) { + var playersNotToBeDrawnOut = tournament.getPlayersPlayingOnlyOneEvent(); + if (round.getDrawnOut() != null && + (playersNotToBeDrawnOut.contains(round.getDrawnOut().getPlayer1()) || + (round.getDrawnOut().getPlayer2() != null && playersNotToBeDrawnOut.contains(round.getDrawnOut().getPlayer2())))) { + return false; + } for (var match : matches) { var clubs = getClubsFromMatch(match); var distinctClubs = new HashSet<>(clubs).size(); diff --git a/src/main/java/nl/connectedit/swiss/service/TournamentPlayService.java b/src/main/java/nl/connectedit/swiss/service/TournamentPlayService.java index ade2a14..47cdf69 100644 --- a/src/main/java/nl/connectedit/swiss/service/TournamentPlayService.java +++ b/src/main/java/nl/connectedit/swiss/service/TournamentPlayService.java @@ -67,11 +67,12 @@ public class TournamentPlayService { round.setStatus(Status.NOT_STARTED); if (remainingTeams.size() % 2 == 1) { - var drawnOutPlayers = tournament.getDrawnOutPlayers(); + var playersNotToBeDrawnOut = tournament.getDrawnOutPlayers(); + playersNotToBeDrawnOut.addAll(tournament.getPlayersPlayingOnlyOneEvent()); var tryPosition = remainingTeams.size() - 1; do { var tryDrawOutTeam = remainingTeams.get(tryPosition); - if (!drawnOutPlayers.contains(tryDrawOutTeam.getPlayer1()) && (tryDrawOutTeam.getPlayer2() == null || !drawnOutPlayers.contains(tryDrawOutTeam.getPlayer2()))) { + if (!playersNotToBeDrawnOut.contains(tryDrawOutTeam.getPlayer1()) && (tryDrawOutTeam.getPlayer2() == null || !playersNotToBeDrawnOut.contains(tryDrawOutTeam.getPlayer2()))) { remainingTeams.remove(tryDrawOutTeam); round.setDrawnOut(tryDrawOutTeam); break;