package net.olemartin.service.match; import net.olemartin.domain.*; import net.olemartin.engine.TournamentEngine; import net.olemartin.engine.TournamentEngineFactory; import net.olemartin.repository.MatchRepository; import net.olemartin.repository.PlayerRepository; import net.olemartin.repository.RoundRepository; import net.olemartin.repository.TournamentRepository; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.Set; @Service @Transactional public class MatchService { private final MatchRepository matchRepository; private final TournamentRepository tournamentRepository; private final RoundRepository roundRepository; private final PlayerRepository playerRepository; @Autowired public MatchService(MatchRepository matchRepository, TournamentRepository tournamentRepository, RoundRepository roundRepository, PlayerRepository playerRepository) { this.matchRepository = matchRepository; this.tournamentRepository = tournamentRepository; this.roundRepository = roundRepository; this.playerRepository = playerRepository; } public Set<Match> nextRound(long tournamentId) { Tournament tournament = tournamentRepository.findOne(tournamentId, 2); if (tournament.isFinished()) { throw new IllegalArgumentException("Tournament is finished."); } if (!tournament.isCurrentRoundFinished()) { throw new IllegalArgumentException("Current round is not finished."); } TournamentEngine tournamentEngine = TournamentEngineFactory.getEngine( new Randomizer(), tournament.getPlayers(), tournament.getEngine()); Round round = tournament.startNewRound(); List<Match> matches = tournamentEngine.round(round.getNumber()); matchRepository.save(matches, 2).forEach(round::addMatch); roundRepository.save(round); tournamentRepository.save(tournament); return round.getMatches(); } public List<Match> findMatchesPlayerPlayed(long playerId) { List<Match> matches = new ArrayList<>(); for (Match m : matchRepository.findMatchesPlayerPlayed(playerId)) { matches.add(m); } for (Match match : matches) { if (match.getResult() == Result.REMIS) { match.setDisplayResult("Remis"); } else { if (match.getWinner().getId() == playerId) { match.setDisplayResult("Won"); } else { match.setDisplayResult("Lost"); } } } return matches; } public Match reportResult(long matchId, Result result) { Match match = matchRepository.findOne(matchId, 1); if (match.hasResult()) { throw new IllegalStateException("Match already has result"); } match.reportResult(result); matchRepository.save(match, 2); updateMonradAndBerger(match.getWhite(), match.getBlack()); playerRepository.save(match.getBlack()); playerRepository.save(match.getWhite()); return match; } public void updateMonradAndBerger(Iterable<Player> players) { for (Player player : players) { player.setMonradAndBerger( playerRepository.findOpponentsPlayerBeat(player.getId()), playerRepository.findOpponentsRemis(player.getId())); } } public void updateMonradAndBerger(Player... players) { updateMonradAndBerger(Arrays.asList(players)); } }