public override CompetitorRanks GenerateResult(TournamentSimulation.MatchStrategies.MatchStrategy matchStrategy, List<Competitor> competitors)
        {
            TournamentRoundStrategy tournamentRoundStrategy = new KoTRS(_winsToClinchMatch);
            List<TournamentRound> tournamentRounds = new List<TournamentRound>();
            TournamentRound tournamentRound;

            tournamentRound = new TournamentRound(tournamentRoundStrategy, matchStrategy);
            tournamentRound.Run(competitors);
            tournamentRounds.Add(tournamentRound);

            while (tournamentRound.Matches.Count > 1)
            {
                List<Competitor> winners = tournamentRound.Matches
                    .Select(x => x.Winner)
                    .ToList<Competitor>();

                tournamentRound = new TournamentRound(tournamentRoundStrategy, matchStrategy);
                tournamentRound.Run(winners);
                tournamentRounds.Add(tournamentRound);
            }

            List<Match> matches = new List<Match>();
            foreach (TournamentRound round in tournamentRounds)
            {
                matches.AddRange(round.Matches);
            }

            Matches = matches;

            CompetitorPoints competitorPoints = AccumulateMatchPoints(matches);
            return competitorPoints.GetCompetitorRanks();
        }
        public override CompetitorRanks GenerateResult(TournamentSimulation.MatchStrategies.MatchStrategy matchStrategy, List<Competitor> competitors)
        {
            if (competitors.Count != 4)
                throw new ArgumentException("Collection count must be 4.", "competitors");

            List<TournamentRound> tournamentRounds = new List<TournamentRound>();

            // semifinal round
            TournamentRoundStrategy semifinalTRS = new KoTRS(_winsToClinchSemifinalMatch);
            TournamentRound semifinalRound = new TournamentRound(semifinalTRS, matchStrategy);
            semifinalRound.Run(competitors);
            tournamentRounds.Add(semifinalRound);

            // petit final round
            List<Competitor> losers = semifinalRound.Matches
                .Select(x => x.Loser)
                .ToList<Competitor>();

            TournamentRoundStrategy petitFinalTRS = new KoTRS(_winsToClinchPetitMatch);
            TournamentRound petitFinalRound = new TournamentRound(petitFinalTRS, matchStrategy);
            petitFinalRound.Run(losers);
            tournamentRounds.Add(petitFinalRound);

            // final round
            List<Competitor> winners = semifinalRound.Matches
                .Select(x => x.Winner)
                .ToList<Competitor>();

            TournamentRoundStrategy finalTRS = new KoTRS(_winsToClinchFinalsMatch);
            TournamentRound finalRound = new TournamentRound(finalTRS, matchStrategy);
            finalRound.Run(winners);
            tournamentRounds.Add(finalRound);

            // return the matches that were run
            // return the matches that were run
            List<Match> matches = tournamentRounds
                .SelectMany(x => x.Matches)
                .Select(x => x)
                .ToList<Match>();

            Matches = matches;

            return GetTournamentRoundRanks();
        }
        public override CompetitorRanks GenerateResult(int tournamentRunSequence, TournamentSimulation.MatchStrategies.MatchStrategy matchStrategy, List<Competitor> competitors)
        {
            // round robin to seed the quarterfinals
            TournamentRound roundRobinTR = new TournamentRound(new RrTRS(_numberOfRoundRobinRounds), matchStrategy);
            CompetitorRanks rrRanks = roundRobinTR.Run(competitors);
            List<Competitor> rr1RankedCompetitors = rrRanks
                .OrderBy(x => x.Value)
                .Select(x => x.Key)
                .ToList<Competitor>();

            // TODO: move all this complexity to a new TournamentRoundStrategy that includes multiple stages of the knockout round quarterfinals through finals
            // knockout through finals
            TournamentRoundStrategy knockoutTRS = new KoTRS(_winsToClinchKnockoutMatch);
            TournamentRound knockoutTR = new TournamentRound(knockoutTRS, matchStrategy);
            knockoutTR.Run(rr1RankedCompetitors);

            List<TournamentRound> knockoutRounds = new List<TournamentRound>();
            knockoutRounds.Add(knockoutTR);
                
            while (knockoutTR.Matches.Count > 1)
            {
                List<Competitor> winningCompetitorsToMoveOn = new List<Competitor>();
                foreach (Match match in knockoutTR.Matches)
                {
                    winningCompetitorsToMoveOn.Add(match.Winner);
                }

                knockoutTR = new TournamentRound(knockoutTRS, matchStrategy);
                knockoutTR.Run(winningCompetitorsToMoveOn);

                knockoutRounds.Add(knockoutTR);
            }

            CompetitorPoints competitorPoints = AccumulatePointsFromTournamentRounds(knockoutRounds);
            CompetitorRanks ranks = competitorPoints.GetCompetitorRanks();

            BreakTiesByRoundRobinRanks(rrRanks, ranks);

            return ranks;
        }
        public override CompetitorRanks GenerateResult(MatchStrategies.MatchStrategy matchStrategy, List<Competitor> competitors)
        {
            if (competitors.Count != 5)
                throw new ArgumentException("Collection count must be 5.", "competitors");

            List<TournamentRound> tournamentRounds = new List<TournamentRound>();

            // petit final qualifier round
            List<Competitor> petitQualifiers = new List<Competitor>();
            petitQualifiers.Add(competitors[3]);
            petitQualifiers.Add(competitors[4]);

            TournamentRoundStrategy knockoutTRS_petitQualifier = new KoTRS(_winsToClinchSemifinalMatch);
            TournamentRound petitQualifierRound = new TournamentRound(knockoutTRS_petitQualifier, matchStrategy);
            petitQualifierRound.Run(petitQualifiers);
            tournamentRounds.Add(petitQualifierRound);

            // final qualifier round
            List<Competitor> finalsQualifiers = new List<Competitor>();
            finalsQualifiers.Add(competitors[1]);
            finalsQualifiers.Add(competitors[2]);

            TournamentRoundStrategy knockoutTRS_finalQualifier = new KoTRS(_winsToClinchSemifinalMatch);
            TournamentRound finalQualifierRound = new TournamentRound(knockoutTRS_finalQualifier, matchStrategy);
            finalQualifierRound.Run(finalsQualifiers);
            tournamentRounds.Add(finalQualifierRound);

            // petit final round
            List<Competitor> petitFinalsCompetitors = petitQualifierRound.Matches
                .Select(x => x.Winner)
                .Union(finalQualifierRound.Matches
                    .Select(x => x.Loser))
                .ToList<Competitor>();

            TournamentRoundStrategy petitFinalTRS = new KoTRS(_winsToClinchPetitMatch);
            TournamentRound petitFinalRound = new TournamentRound(petitFinalTRS, matchStrategy);
            petitFinalRound.Run(petitFinalsCompetitors);
            tournamentRounds.Add(petitFinalRound);

            // final round
            List<Competitor> finalsCompetitors = finalQualifierRound.Matches
                .Select(x => x.Winner)
                .ToList<Competitor>();

            finalsCompetitors.Add(competitors[0]);

            TournamentRoundStrategy finalTRS = new KoTRS(_winsToClinchFinalsMatch);
            TournamentRound finalRound = new TournamentRound(finalTRS, matchStrategy);
            finalRound.Run(finalsCompetitors);
            tournamentRounds.Add(finalRound);

            // return the matches that were run
            List<Match> matches = tournamentRounds
                .SelectMany(x => x.Matches)
                .Select(x => x)
                .ToList<Match>();

            Matches = matches;

            return GetTournamentRoundRanks();
        }