public void Reset() { this.loadedTeams = null; this.loadedPairings = null; this.loadedRounds = null; this.state = PairingsGeneratorState.NotInitialized; }
public void Reset() { this.loadedTeams = null; this.loadedRounds = null; this.loadedEliminated = null; this.loadedCanContinue = false; this.state = PairingsGeneratorState.NotInitialized; }
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; }
public void Reset() { this.loadedTeams = null; this.loadedPairings = null; this.loadedRounds = null; this.PoolGroups = null; this.state = PairingsGeneratorState.NotInitialized; }
private void LoadRoundRobinDefault(IEnumerable<TournamentTeam> teams, IList<TournamentRound> 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.TeamId == pair[0].Team.TeamId && p.B.TeamId == pair[1].Team.TeamId) || (p.A.TeamId == pair[1].Team.TeamId && p.B.TeamId == pair[0].Team.TeamId); RRPairing remove = newPairings.SingleOrDefault(filter); if (remove == null) { if (pair[0].Team.TeamId == pair[1].Team.TeamId) { 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.Where(x => x.TeamId == pair[0].Team.TeamId).FirstOrDefault() == null || newTeams.Where(x => x.TeamId == pair[1].Team.TeamId).FirstOrDefault() == null) { 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."); } } var isRemoved = newPairings.Remove(remove); if (isRemoved == false) isRemoved = false; } } } this.loadedTeams = newTeams; this.loadedPairings = newPairings; this.loadedRounds = new List<TournamentRound>(rounds); this.state = PairingsGeneratorState.Initialized; }
private void LoadRoundRobinPoolPlay(IEnumerable<TournamentTeam> teams, IList<TournamentRound> rounds) { this.loadedPairings = new List<RRPairing>(); this.loadedRounds = new List<TournamentRound>(); PoolGroups = new List<TournamentPoolGroup>(); GroupIds = teams.Select(x => x.GroupId).Distinct().ToList(); foreach (var id in GroupIds) { TournamentPoolGroup group = new TournamentPoolGroup(); group.GroupId = id.Value; group.AddTeams(teams.Where(x => x.GroupId.HasValue && x.GroupId == id).ToList()); PoolGroups.Add(group); } foreach (var group in PoolGroups) { // Build our total list of pairings. List<RRPairing> newPairings = new List<RRPairing>(); for (int i = 0; i < group.teamsInGroup.Count; i++) { for (int j = i + 1; j < group.teamsInGroup.Count; j++) { newPairings.Add(new RRPairing() { A = group.teamsInGroup[i], B = group.teamsInGroup[j], GroupId = group.GroupId }); } } // Remove from the pairings list each pairing that has already been executed foreach (TournamentRound round in rounds) { foreach (TournamentPairing pairing in round.Pairings.Where(x => x.GroupId == group.GroupId)) { 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.TeamId == pair[0].Team.TeamId && p.B.TeamId == pair[1].Team.TeamId) || (p.A.TeamId == pair[1].Team.TeamId && p.B.TeamId == pair[0].Team.TeamId); RRPairing remove = newPairings.SingleOrDefault(filter); if (remove == null) { if (pair[0].Team.TeamId == pair[1].Team.TeamId) { 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 (group.teamsInGroup.Where(x => x.TeamId == pair[0].Team.TeamId).FirstOrDefault() == null || group.teamsInGroup.Where(x => x.TeamId == pair[1].Team.TeamId).FirstOrDefault() == null) { 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."); } } var isRemoved = newPairings.Remove(remove); if (isRemoved == false) isRemoved = false; } } } this.loadedPairings.AddRange(newPairings); this.loadedRounds.AddRange(new List<TournamentRound>(rounds)); } this.loadedTeams = teams.ToList(); this.state = PairingsGeneratorState.Initialized; }
public void LoadState(IEnumerable <TournamentTeam> teams, IList <TournamentRound> rounds) { if (teams == null) { throw new ArgumentNullException("teams"); } if (rounds == null) { throw new ArgumentNullException("rounds"); } if (rounds.Where(r => r.Pairings.Where(p => p.TeamScores.Count > 2).Any()).Any()) { throw new InvalidTournamentStateException("At least one pairing had more than two teams competing. This is invalid in a single elimination tournament."); } var rootNode = BuildTree(teams); bool byesLocked = false; foreach (var round in rounds) { foreach (var pairing in round.Pairings) { // TODO: We must sort the byes to the top. if (pairing.TeamScores.Count == 0) { continue; } tryagainwithbyeslocked: bool success = rootNode.ApplyPairing(pairing); if (!success) { var teamScoreA = pairing.TeamScores[0]; var teamScoreB = pairing.TeamScores.Count > 1 ? pairing.TeamScores[1] : null; if (teamScoreA == null) { teamScoreA = teamScoreB; teamScoreB = null; } if (teamScoreA == null) { continue; } var teamA = teamScoreA != null ? teamScoreA.Team : null; var teamB = teamScoreB != null ? teamScoreB.Team : null; var scoreA = teamScoreA != null ? teamScoreA.Score : null; var scoreB = teamScoreB != null ? teamScoreB.Score : null; var nodesA = teamA == null ? null : rootNode.FindDeciders(d => d.IsDecided && !d.Locked && d.GetWinner() != null && d.GetWinner().TeamId == teamA.TeamId); var nodesB = teamB == null ? null : rootNode.FindDeciders(d => d.IsDecided && !d.Locked && d.GetWinner() != null && d.GetWinner().TeamId == teamB.TeamId); if (nodesA == null || nodesA.Count() == 0 || nodesB == null || nodesB.Count() == 0) { if (!byesLocked) { byesLocked = true; LockByes(rootNode); goto tryagainwithbyeslocked; } throw new InvalidTournamentStateException("There was at least one pairing that could not be matched: The requested team was not available to play."); } if (nodesA.Count() > 1 || nodesB.Count() > 1) { if (!byesLocked) { byesLocked = true; LockByes(rootNode); goto tryagainwithbyeslocked; } throw new InvalidTournamentStateException("There was at least one pairing that could not be matched: The requested team was not able to be decided unambiguously."); } var deciderA = nodesA.Single(); var deciderB = nodesB.Single(); var parentDecider = deciderA.PrimaryParent.PrimaryParent as ContinuationDecider; if (parentDecider == null) { parentDecider = deciderB.PrimaryParent.PrimaryParent as ContinuationDecider; if (parentDecider == null) { if (!byesLocked) { byesLocked = true; LockByes(rootNode); goto tryagainwithbyeslocked; } throw new InvalidTournamentStateException("There was at least one pairing that could not be matched: The requested pairing was not compatible with the state of the tournament."); } } if (parentDecider.ChildA.Decider == deciderA || parentDecider.ChildA.Decider == deciderB) { if (parentDecider.ChildA.Decider == deciderA) { SwapDeciders(parentDecider.ChildB.Decider, deciderB); } else { SwapDeciders(parentDecider.ChildB.Decider, deciderA); } } else { if (parentDecider.ChildB.Decider == deciderA) { SwapDeciders(parentDecider.ChildA.Decider, deciderB); } else { SwapDeciders(parentDecider.ChildA.Decider, deciderA); } } success = rootNode.ApplyPairing(pairing); if (!success) { if (!byesLocked) { byesLocked = true; LockByes(rootNode); goto tryagainwithbyeslocked; } throw new InvalidTournamentStateException("A swap was performed to match the tournament to the actual state, but applying the pairing failed."); } } } } this.loadedRootNode = rootNode; this.loadedTeams = new List <TournamentTeam>(teams); this.state = PairingsGeneratorState.Initialized; }
public void Reset() { this.loadedTeams = null; this.loadedRootNode = null; this.state = PairingsGeneratorState.NotInitialized; }
public void LoadState(IEnumerable<TournamentTeam> teams, IList<TournamentRound> rounds) { if (teams == null) { throw new ArgumentNullException("teams"); } if (rounds == null) { throw new ArgumentNullException("rounds"); } if (rounds.Where(r => r.Pairings.Where(p => p.TeamScores.Count > 2).Any()).Any()) { throw new InvalidTournamentStateException("At least one pairing had more than two teams competing. This is invalid in a single elimination tournament."); } var rootNode = BuildTree(teams); bool byesLocked = false; foreach (var round in rounds) { foreach (var pairing in round.Pairings) { // TODO: We must sort the byes to the top. if (pairing.TeamScores.Count == 0) { continue; } tryagainwithbyeslocked: bool success = rootNode.ApplyPairing(pairing); if (!success) { var teamScoreA = pairing.TeamScores[0]; var teamScoreB = pairing.TeamScores.Count > 1 ? pairing.TeamScores[1] : null; if (teamScoreA == null) { teamScoreA = teamScoreB; teamScoreB = null; } if (teamScoreA == null) continue; var teamA = teamScoreA != null ? teamScoreA.Team : null; var teamB = teamScoreB != null ? teamScoreB.Team : null; var scoreA = teamScoreA != null ? teamScoreA.Score : null; var scoreB = teamScoreB != null ? teamScoreB.Score : null; var nodesA = teamA == null ? null : rootNode.FindDeciders(d => d.IsDecided && !d.Locked && d.GetWinner() != null && d.GetWinner().TeamId == teamA.TeamId); var nodesB = teamB == null ? null : rootNode.FindDeciders(d => d.IsDecided && !d.Locked && d.GetWinner() != null && d.GetWinner().TeamId == teamB.TeamId); if (nodesA == null || nodesA.Count() == 0 || nodesB == null || nodesB.Count() == 0) { if (!byesLocked) { byesLocked = true; LockByes(rootNode); goto tryagainwithbyeslocked; } throw new InvalidTournamentStateException("There was at least one pairing that could not be matched: The requested team was not available to play."); } if (nodesA.Count() > 1 || nodesB.Count() > 1) { if (!byesLocked) { byesLocked = true; LockByes(rootNode); goto tryagainwithbyeslocked; } throw new InvalidTournamentStateException("There was at least one pairing that could not be matched: The requested team was not able to be decided unambiguously."); } var deciderA = nodesA.Single(); var deciderB = nodesB.Single(); var parentDecider = deciderA.PrimaryParent.PrimaryParent as ContinuationDecider; if (parentDecider == null) { parentDecider = deciderB.PrimaryParent.PrimaryParent as ContinuationDecider; if (parentDecider == null) { if (!byesLocked) { byesLocked = true; LockByes(rootNode); goto tryagainwithbyeslocked; } throw new InvalidTournamentStateException("There was at least one pairing that could not be matched: The requested pairing was not compatible with the state of the tournament."); } } if (parentDecider.ChildA.Decider == deciderA || parentDecider.ChildA.Decider == deciderB) { if (parentDecider.ChildA.Decider == deciderA) { SwapDeciders(parentDecider.ChildB.Decider, deciderB); } else { SwapDeciders(parentDecider.ChildB.Decider, deciderA); } } else { if (parentDecider.ChildB.Decider == deciderA) { SwapDeciders(parentDecider.ChildA.Decider, deciderB); } else { SwapDeciders(parentDecider.ChildA.Decider, deciderA); } } success = rootNode.ApplyPairing(pairing); if (!success) { if (!byesLocked) { byesLocked = true; LockByes(rootNode); goto tryagainwithbyeslocked; } throw new InvalidTournamentStateException("A swap was performed to match the tournament to the actual state, but applying the pairing failed."); } } } } this.loadedRootNode = rootNode; this.loadedTeams = new List<TournamentTeam>(teams); this.state = PairingsGeneratorState.Initialized; }
public void LoadState(IEnumerable<TournamentTeam> teams, IList<TournamentRound> rounds) { if (teams == null) { throw new ArgumentNullException("teams"); } if (rounds == null) { throw new ArgumentNullException("rounds"); } if (!(teams.Count() < 1073741824)) { throw new InvalidTournamentStateException("A boil off competition can not handle more than 1073741823 competitors."); } List<TournamentTeam> newTeams = new List<TournamentTeam>(teams); List<TournamentRound> newRounds = new List<TournamentRound>(rounds); List<BORank> newEliminated = new List<BORank>(); int ordinalRoundNumber = 1; bool canContinue = true; foreach (var round in newRounds) { if (!canContinue) { throw new InvalidTournamentStateException("At least one round was not completed before another was started."); } List<BORank> rankings = new List<BORank>(GetRoundRankings(round, ordinalRoundNumber)); if (rankings.Count == 0) { canContinue = false; continue; } var rankingTeams = (from ranking in rankings select ranking.Team).ToList(); var ineligible = from rt in rankingTeams where !newTeams.Contains(rt) select rt; if (ineligible.Any()) { throw new InvalidTournamentStateException("The rounds alread executed in this tournament make it invalid as a boil-off tournament for the following reason: There is at least one competitor who should not have competed in a round who did."); } var required = (from nt in newTeams where (rankingTeams.Where(x=>x.TeamId == nt.TeamId).FirstOrDefault() == null) select nt).ToList(); if (required.Any()) { // If not in the first round, allow additional eliminations. (Given that all players in a tie must be eliminated/kept together.) if (ordinalRoundNumber > 1) { // TODO: Allow additional eliminations, given that all players in a tie must be kept together. } throw new InvalidTournamentStateException("There is at least one competitor who should have competed in a round who did not."); } int roundNumber = GetRoundNumber(newTeams.Count, BoilOffPairingsGenerator.lastRound); newTeams.Clear(); if (roundNumber > 0) { int maxRank = TeamsInRound(roundNumber - 1, BoilOffPairingsGenerator.lastRound); var teamsEliminated = from ranking in rankings where ranking.Rank > maxRank select ranking; var teamsLeft = from ranking in rankings where ranking.Rank <= maxRank select ranking.Team; newEliminated.AddRange(teamsEliminated); newTeams.AddRange(teamsLeft); } ordinalRoundNumber++; } this.loadedTeams = newTeams; this.loadedRounds = newRounds; this.loadedEliminated = newEliminated; this.loadedCanContinue = canContinue; this.state = PairingsGeneratorState.Initialized; }
public void LoadState(IEnumerable <TournamentTeam> teams, IList <TournamentRound> rounds) { if (teams == null) { throw new ArgumentNullException(nameof(teams)); } if (rounds == null) { throw new ArgumentNullException(nameof(rounds)); } if (!(teams.Count() < 1073741824)) { throw new InvalidTournamentStateException("A boil off competition can not handle more than 1073741823 competitors."); } List <TournamentTeam> newTeams = new List <TournamentTeam>(teams); List <TournamentRound> newRounds = new List <TournamentRound>(rounds); List <BORank> newEliminated = new List <BORank>(); int ordinalRoundNumber = 1; bool canContinue = true; foreach (var round in newRounds) { if (!canContinue) { throw new InvalidTournamentStateException("At least one round was not completed before another was started."); } List <BORank> rankings = new List <BORank>(GetRoundRankings(round, ordinalRoundNumber)); if (rankings.Count == 0) { canContinue = false; continue; } var rankingTeams = (from ranking in rankings select ranking.Team).ToList(); var ineligible = from rt in rankingTeams where !newTeams.Contains(rt) select rt; if (ineligible.Any()) { throw new InvalidTournamentStateException("The rounds alread executed in this tournament make it invalid as a boil-off tournament for the following reason: There is at least one competitor who should not have competed in a round who did."); } var required = (from nt in newTeams where !rankingTeams.Contains(nt) select nt).ToList(); if (required.Any()) { // If not in the first round, allow additional eliminations. (Given that all players in a tie must be eliminated/kept together.) if (ordinalRoundNumber > 1) { // TODO: Allow additional eliminations, given that all players in a tie must be kept together. } throw new InvalidTournamentStateException("There is at least one competitor who should have competed in a round who did not."); } int roundNumber = GetRoundNumber(newTeams.Count, BoilOffPairingsGenerator.lastRound); newTeams.Clear(); if (roundNumber > 0) { int maxRank = TeamsInRound(roundNumber - 1, BoilOffPairingsGenerator.lastRound); var teamsEliminated = from ranking in rankings where ranking.Rank > maxRank select ranking; var teamsLeft = from ranking in rankings where ranking.Rank <= maxRank select ranking.Team; newEliminated.AddRange(teamsEliminated); newTeams.AddRange(teamsLeft); } ordinalRoundNumber++; } this.loadedTeams = newTeams; this.loadedRounds = newRounds; this.loadedEliminated = newEliminated; this.loadedCanContinue = canContinue; this.state = PairingsGeneratorState.Initialized; }
public void Reset() { loadedTeams = null; loadedRootNode = null; state = PairingsGeneratorState.NOT_INITIALIZED; }