예제 #1
0
        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;
        }
예제 #2
0
 public void Reset()
 {
     loadedTeams    = null;
     loadedRootNode = null;
     state          = PairingsGeneratorState.NOT_INITIALIZED;
 }