public void LoadState(IEnumerable <Contestant> 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.ContestantScores.Count > 2).Any()).Any()) { throw new Exception("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.ContestantScores.Count == 0) { continue; } tryagainwithbyeslocked: bool success = rootNode.ApplyPairing(pairing); if (!success) { var teamScoreA = pairing.ContestantScores[0]; var teamScoreB = pairing.ContestantScores.Count > 1 ? pairing.ContestantScores[1] : null; if (teamScoreA == null) { teamScoreA = teamScoreB; teamScoreB = null; } if (teamScoreA == null) { continue; } var teamA = teamScoreA != null ? teamScoreA.Contestant : null; var teamB = teamScoreB != null ? teamScoreB.Contestant : 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().Identity == teamA.Identity); var nodesB = teamB == null ? null : rootNode.FindDeciders(d => d.IsDecided && !d.Locked && d.GetWinner() != null && d.GetWinner().Identity == teamB.Identity); if (nodesA == null || nodesA.Count() == 0 || nodesB == null || nodesB.Count() == 0) { if (!byesLocked) { byesLocked = true; LockByes(rootNode); goto tryagainwithbyeslocked; } throw new Exception("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 Exception("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 Exception("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 Exception("A swap was performed to match the tournament to the actual state, but applying the pairing failed."); } } } } loadedRootNode = rootNode; loadedTeams = new List <Contestant>(teams); state = PairingsGeneratorState.INITIALIZED; }
public void Reset() { loadedTeams = null; loadedRootNode = null; state = PairingsGeneratorState.NOT_INITIALIZED; }