All checks were successful
Gitea/swiss-backend/pipeline/head This commit looks good
166 lines
5.1 KiB
Java
166 lines
5.1 KiB
Java
package nl.connectedit.swiss.service;
|
|
|
|
import jakarta.transaction.Transactional;
|
|
import java.util.ArrayList;
|
|
import java.util.Comparator;
|
|
import java.util.HashMap;
|
|
import java.util.Iterator;
|
|
import java.util.List;
|
|
import java.util.Map;
|
|
import java.util.Objects;
|
|
import lombok.RequiredArgsConstructor;
|
|
import nl.connectedit.swiss.domain.EventType;
|
|
import nl.connectedit.swiss.domain.Status;
|
|
import nl.connectedit.swiss.domain.TournamentStatus;
|
|
import nl.connectedit.swiss.domain.entity.Event;
|
|
import nl.connectedit.swiss.domain.entity.Group;
|
|
import nl.connectedit.swiss.domain.entity.Registration;
|
|
import nl.connectedit.swiss.domain.entity.Team;
|
|
import nl.connectedit.swiss.domain.entity.Tournament;
|
|
import nl.connectedit.swiss.repository.TournamentRepository;
|
|
import org.springframework.stereotype.Service;
|
|
|
|
@Service
|
|
@RequiredArgsConstructor
|
|
public class TournamentDivideService {
|
|
|
|
private final TournamentValidationService tournamentValidationService;
|
|
|
|
private final TournamentRepository tournamentRepository;
|
|
|
|
@Transactional
|
|
public Tournament divide(Tournament tournament) {
|
|
if (tournamentValidationService.validate(tournament).hasErrors()) {
|
|
return tournament;
|
|
}
|
|
|
|
for (var event : tournament.getEvents()) {
|
|
if ((event.getType().isDoublesEvent() && event.getRegistrations().size() >= 8)
|
|
|| (!event.getType().isDoublesEvent() && event.getRegistrations().size() >= 4)) {
|
|
divide(event);
|
|
}
|
|
}
|
|
|
|
tournament.setStatus(TournamentStatus.DIVIDED);
|
|
|
|
tournamentRepository.save(tournament);
|
|
|
|
return tournament;
|
|
}
|
|
|
|
public void divide(Event event) {
|
|
List<Registration> registrations;
|
|
if (event.getType().isDoublesEvent()) {
|
|
registrations = groupRegistrations(event.getRegistrations());
|
|
} else {
|
|
registrations = event.getRegistrations();
|
|
}
|
|
|
|
event.setGroups(new ArrayList<>());
|
|
|
|
if (registrations.size() <= 16) {
|
|
var group = getGroup(registrations, event.getType());
|
|
group.setEvent(event);
|
|
event.getGroups().add(group);
|
|
} else {
|
|
var groups = getGroups(registrations, event.getType());
|
|
groups.forEach(group -> group.setEvent(event));
|
|
event.getGroups().addAll(groups);
|
|
}
|
|
}
|
|
|
|
private List<Registration> groupRegistrations(List<Registration> registrations) {
|
|
var groupedRegistrations = new ArrayList<Registration>();
|
|
|
|
nextRegistration:
|
|
for (var registration : registrations) {
|
|
for (var groupedRegistration : groupedRegistrations) {
|
|
if (Objects.equals(groupedRegistration.getPartner(), registration.getPlayer())) {
|
|
continue nextRegistration;
|
|
}
|
|
}
|
|
groupedRegistrations.add(registration);
|
|
}
|
|
return groupedRegistrations;
|
|
}
|
|
|
|
private Group getGroup(List<Registration> registrations, EventType type) {
|
|
var group = new Group();
|
|
group.setName(type.getText());
|
|
group.setType(type);
|
|
group.setStatus(Status.IN_PROGRESS);
|
|
group.setTeams(new ArrayList<>());
|
|
for (var registration : registrations) {
|
|
group.getTeams().add(getTeam(registration, group));
|
|
}
|
|
|
|
return group;
|
|
}
|
|
|
|
private List<Group> getGroups(List<Registration> orgRegistrations, EventType type) {
|
|
var registrations = new ArrayList<>(orgRegistrations);
|
|
|
|
var group1 = new Group();
|
|
group1.setName(type.getText() + " 1");
|
|
group1.setType(type);
|
|
group1.setStatus(Status.IN_PROGRESS);
|
|
group1.setTeams(new ArrayList<>());
|
|
|
|
var group2 = new Group();
|
|
group2.setName(type.getText() + " 2");
|
|
group2.setType(type);
|
|
group2.setStatus(Status.IN_PROGRESS);
|
|
group2.setTeams(new ArrayList<>());
|
|
|
|
var registrationStrengthMap = new HashMap<Registration, Integer>();
|
|
for (var registration : registrations) {
|
|
var strength = registration.getPlayer().getStrength().getCoefficient();
|
|
if (registration.getPartner() != null) {
|
|
strength += registration.getPartner().getStrength().getCoefficient();
|
|
}
|
|
registrationStrengthMap.put(registration, strength);
|
|
}
|
|
|
|
var sortedRegistrations = registrationStrengthMap
|
|
.entrySet()
|
|
.stream()
|
|
.sorted(Map.Entry.comparingByValue(Comparator.reverseOrder()))
|
|
.map(Map.Entry::getKey)
|
|
.toList();
|
|
|
|
for (Iterator<Registration> i = sortedRegistrations.iterator(); i.hasNext(); ) {
|
|
group1.getTeams().add(getTeam(i.next(), group1));
|
|
if (i.hasNext()) {
|
|
group2.getTeams().add(getTeam(i.next(), group2));
|
|
}
|
|
}
|
|
|
|
if (group1.getTeams().size() % 2 == 1 && group2.getTeams().size() % 2 == 1) {
|
|
group1.getTeams().add(group2.getTeams().getLast());
|
|
group2.getTeams().removeLast();
|
|
}
|
|
|
|
return List.of(group1, group2);
|
|
}
|
|
|
|
private Team getTeam(Registration registration, Group group) {
|
|
var team = new Team();
|
|
team.setPlayer1(registration.getPlayer());
|
|
team.setPlayer2(registration.getPartner());
|
|
team.setGroups(List.of(group));
|
|
|
|
return team;
|
|
}
|
|
|
|
public Tournament clear(Tournament tournament) {
|
|
for (var event : tournament.getEvents()) {
|
|
event.getGroups().clear();
|
|
}
|
|
tournament.setStatus(TournamentStatus.UPCOMING);
|
|
|
|
tournamentRepository.save(tournament);
|
|
|
|
return tournament;
|
|
}
|
|
}
|