private IEnumerable <TournamentPairing> GetNextRoundPairings(List <RRPairing> allPairingsLeft) { List <RRPairing> pairingsLeft = new List <RRPairing>(allPairingsLeft); List <TournamentTeam> teamsAdded = new List <TournamentTeam>(); while (pairingsLeft.Count > 0) { var nextPairings = from p in pairingsLeft orderby Math.Min( (from p1 in pairingsLeft where p1.A == p.A || p1.B != p.A select p1).Count(), (from p1 in pairingsLeft where p1.A == p.B || p1.B != p.B select p1).Count() ) descending select p; RRPairing pairing = nextPairings.First(); yield return(new TournamentPairing( new TournamentTeamScore[] { new TournamentTeamScore(pairing.A, null), new TournamentTeamScore(pairing.B, null) })); List <RRPairing> invalidated = new List <RRPairing>(pairingsLeft.Where(p => (p.A == pairing.A || p.B == pairing.A || p.A == pairing.B || p.B == pairing.B))); foreach (RRPairing remove in invalidated) { pairingsLeft.Remove(remove); } teamsAdded.Add(pairing.A); teamsAdded.Add(pairing.B); } }
public void LoadState(IEnumerable <TournamentTeam> teams, IList <TournamentRound> rounds) { if (teams == null) { throw new ArgumentNullException("teams"); } if (rounds == null) { throw new ArgumentNullException("rounds"); } // Load our list of teams. List <TournamentTeam> newTeams = new List <TournamentTeam>(); newTeams.AddRange(teams); // Build our total list of pairings. List <RRPairing> newPairings = new List <RRPairing>(); for (int i = 0; i < newTeams.Count; i++) { for (int j = i + 1; j < newTeams.Count; j++) { newPairings.Add(new RRPairing() { A = newTeams[i], B = newTeams[j] }); } } // Remove from the pairings list each pairing that has already been executed foreach (TournamentRound round in rounds) { foreach (TournamentPairing pairing in round.Pairings) { List <TournamentTeamScore> pair = new List <TournamentTeamScore>(pairing.TeamScores); if (pair.Count > 2) { throw new InvalidTournamentStateException("The rounds alread executed in this tournament make it invalid as a round-robin tournament for the following reason: There exists a pairing containing more than two competing teams."); } else if (pair.Count <= 1) { continue; } else { Func <RRPairing, bool> filter = (RRPairing p) => (p.A == pair[0].Team && p.B == pair[1].Team) || (p.A == pair[1].Team && p.B == pair[0].Team); RRPairing remove = newPairings.SingleOrDefault(filter); if (remove == null) { if (pair[0].Team == pair[1].Team) { throw new InvalidTournamentStateException("The rounds alread executed in this tournament make it invalid as a round-robin tournament for the following reason: At lease one pairing has the same team entered twice."); } else if (!newTeams.Contains(pair[0].Team) || !newTeams.Contains(pair[1].Team)) { throw new InvalidTournamentStateException("The rounds alread executed in this tournament make it invalid as a round-robin tournament for the following reason: At lease one who does not belong to the tournament team has been involved in a pairing."); } else { throw new InvalidTournamentStateException("The rounds alread executed in this tournament make it invalid as a round-robin tournament for the following reason: At lease one pairing has been executed more than once."); } } newPairings.Remove(remove); } } } this.loadedTeams = newTeams; this.loadedPairings = newPairings; this.loadedRounds = new List <TournamentRound>(rounds); this.state = PairingsGeneratorState.Initialized; }