//this is for automatic scheduling. It's mutually exclusive with manual scheduling //Idea for this implementation was taken from wikipedia //https://en.wikipedia.org/wiki/Round-robin_tournament#Original_construction_of_pairing_tables_by_Richard_Schurig_(1886) public void AutoSchedule(int[] startDate, int spaceBetweenMatches) { if (rounds.Count != 0) { throw new ForbiddenAutoScheduleException(CreateCopy()); } //refNumber holds the number of referees required for a match int i = 0, j = 0, refNumber = 1; if (teams[0] is VolleyballTeam) { refNumber = 3; } //rounds.Capacity/2 + 1 is the maximum number of matches played in a round for (int index = 0; index < rounds.Capacity; index++) { Round tmp = new Round("Round " + (index + 1), startDate); startDate = IncrementDate(startDate, spaceBetweenMatches); for (int index2 = 0; index2 < rounds.Capacity / 2 + 1; index2++) { if (i != j) { tmp.AddMatch(TMatch.Match.CreateMatch(teams[i], teams[j], referees.GetRange((index2 - 1) * refNumber, refNumber))); } else { if (teams.Count != rounds.Capacity) { tmp.AddMatch(TMatch.Match.CreateMatch(teams[i], teams[^ 1], referees.GetRange(referees.Count - refNumber, refNumber)));
public string Name => "Олимпийская система"; // вместо return public Round GetNextRound(IEnumerable <Player> players, IEnumerable <Round> rounds) //IEnumerable( в метод передается самое простое) { var round = new Round(); var playerCount = players.Count(); var roundCount = rounds.Count(); var roundLimit = Math.Log(playerCount, 2); if (roundCount >= roundLimit) { return(null); } var winners = new List <Player>(); var lastRound = rounds.LastOrDefault(); if (lastRound != null) { foreach (var match in lastRound.Matches) { foreach (var raiting in match.Raitings) { if (raiting.Score == 3) { winners.Add(raiting.Player); } } } } var currentPlayers = lastRound == null ? players : winners; var matchCount = currentPlayers.Count() / 2; for (int i = 0; i < matchCount; i++) { var match = new Match(); var player1 = currentPlayers.ElementAt(i * 2); var player2 = currentPlayers.ElementAt(i * 2 + 1); match.Players.Add(player1); match.Players.Add(player2); match.Raitings.Add(new Raiting(player1)); match.Raitings.Add(new Raiting(player2)); round.AddMatch(match); } return(round); }
public void NewRound(Tournament tournament) { List <Player> participants = SortParticipants(tournament.TournamentType, tournament.Participants); Round newRound = new Round(); int j = 0; for (int i = 0; i < participants.Count / 2; i++) { Match match = new Match(participants[j], participants[++j]); j++; newRound.AddMatch(match); } tournament.rounds.Add(newRound); }
//this is for manual scheduling public void ScheduleMatch(TMatch.Match match, int[] date) { for (int i = 0; i < teams.Count; i++) { Boolean flagA = false; Boolean flagB = false; Boolean flagAnB = false; if (rounds.Capacity >= rounds.Count + 1) { flagAnB = true; } if (rounds.Capacity - rounds.Count >= 2) { flagA = true; } for (int j = 0; j < rounds.Count; j++) { /* * We have to check 3 things for each team: * 1. Is that team one of the teams participating in the match * 2. If not, has this team already played against both teams from match * 3. If not, can this team play the teams he has not played with in other round(s) * * Additionally, for both teams participating in the match we have to check n things * 1. Have they already played against each other * 2. Are they already playing against someone else in that round (checked by round) */ if (rounds[j].IsScheduled(match.TeamA, match.TeamB)) { throw new AlreadyPlayingInLeagueException(CreateCopy(), match); } if (!match.IsPlaying(teams[i])) { //check if the team from table is already schedule to play a team from this match if (rounds[j].IsScheduled(teams[i], match.TeamA)) { flagA = true; } if (rounds[j].IsScheduled(teams[i], match.TeamB)) { flagB = true; } //if not, we're checking can still play them, even if we schedule this match if (!rounds[j].IsPlaying(match.TeamA) && !rounds[j].IsPlaying(teams[i])) { if (!rounds[j].IsPlaying(match.TeamB) && !rounds[j].IsPlaying(teams[i]) && flagAnB == false) { flagAnB = true; } else { flagA = true; } } else if (!rounds[j].IsPlaying(match.TeamB) && !rounds[j].IsPlaying(teams[i])) { flagB = true; } } } if (((!flagAnB && !(flagA && flagB)) || !(flagA || flagB)) && !match.IsPlaying(teams[i])) { throw new ImpossibleScheduleException(CreateCopy()); } } //If there exists a round played on this day, match will be added to said round for (int i = 0; i < rounds.Count; i++) { if (rounds[i].Date[0] == date[0] && rounds[i].Date[1] == date[1] && rounds[i].Date[2] == date[2]) { try { rounds[i].AddMatch(match); } catch (RoundRuntimeException e) { rounds.Add(e.RecreateRound()); throw new ImpossibleScheduleException(CreateCopy()); } return; } } //if not, we're creating a new round try { Round tmp = new Round("round played on " + date[0] + "/" + date[1] + "/" + date[2], date); tmp.AddMatch(match); rounds.Add(tmp); } catch (DateException) { throw new ImpossibleScheduleException(CreateCopy()); } }