public override CompetitorRanks GenerateResult(MatchStrategies.MatchStrategy matchStrategy, List<Competitor> competitors) { if (competitors.Count == 1) { CompetitorRanks singleRank = new CompetitorRanks(); singleRank.Add(competitors[0], 1); return singleRank; } List<Match> matches = new List<Match>(); for (int i = 0; i < Convert.ToInt32(Math.Round(_numberOfRounds.Value)); i++) { matches.AddRange(GenerateSingleRoundResult(matchStrategy, competitors, 1.0)); } // now run the partial round, if there are any double fractionOfPartialRound = (_numberOfRounds.Value - Math.Round(_numberOfRounds.Value)); if (fractionOfPartialRound > 0.0) matches.AddRange(GenerateSingleRoundResult(matchStrategy, competitors, fractionOfPartialRound)); Matches = matches; return GetTournamentRoundRanks(); }
public override CompetitorRanks GenerateResult(int tournamentRunSequence, MatchStrategies.MatchStrategy matchStrategy, List<Competitor> competitors) { CompetitorPoints randomPoints = new CompetitorPoints(); foreach (Competitor competitor in competitors) { randomPoints.Add(competitor, _randomPointsGenerator.Next(1, 1000)); } return randomPoints.GetCompetitorRanks(); }
// TODO: change the signature to accept a number of additional rounds, rather than the fraction private List<Match> GenerateSingleRoundResult(MatchStrategies.MatchStrategy matchStrategy, List<Competitor> competitors, double fractionOfPartialRound) { if (fractionOfPartialRound > 1.0 || fractionOfPartialRound < 0 || fractionOfPartialRound == 0) throw new ArgumentException("Must be greater than 0.0 and less than or equal to 1.0.", "fractionOfPartialRound"); List<Match> matches = new List<Match>(); // The standard algorithm is to write competitor numbers in a 2-row grid with // numbers going clockwise. Then, fixing one of the team numbers in place, rotate the // others around it until done. Match-ups are top and bottom in the column. // fill the indexes the first time, including anything to make an even number of indexes List<int> competitorIndexes = new List<int>(); for (int i = 0; i < competitors.Count + (competitors.Count % 2); i++) { competitorIndexes.Add(i); } int numberOfRounds = Convert.ToInt32(Math.Round((competitorIndexes.Count - 1) * fractionOfPartialRound)); // for each round, advance the indexes in the list, except for the last one for (int i = 0; i < numberOfRounds; i++) { // run the matches for the round for (int j = 0; j < competitorIndexes.Count / 2; j++) { // if the number of competitors is odd, give the first competitor a bye if ((competitors.Count % 2) == 1 && j == 0) continue; // choose the first and last, second and second-to-last, etc. Competitor competitorA = competitors[competitorIndexes[j]]; Competitor competitorB = competitors[competitorIndexes[competitorIndexes.Count - j - 1]]; Match match = new Match(matchStrategy, WinsToClinchMatch); match.Run(competitorA, competitorB); matches.Add(match); } // increment the indexes for the next round for (int j = 0; j < competitorIndexes.Count - 1; j++) { competitorIndexes[j] = (competitorIndexes[j] + 1) % (competitorIndexes.Count - 1); } } return matches; }
public override CompetitorRanks GenerateResult(int tournamentRunSequence, MatchStrategies.MatchStrategy matchStrategy, List<Competitor> competitors) { // round robin to seed the semifinals TournamentRound roundRobinTR = new TournamentRound(new RrTRS(_numberOfRoundRobinRounds), matchStrategy); CompetitorRanks rrRanks = roundRobinTR.Run(competitors); List<Competitor> rrRankedCompetitors = rrRanks .OrderBy(x => x.Value) .Select(x => x.Key) .ToList<Competitor>(); // semifinals round TournamentRound semifinals5TR = new TournamentRound(new KoSf5PfFiTRS(_winsToClinchKnockoutSemifinalsMatch, _winsToClinchKnockoutFinalsMatch, _winsToClinchKnockoutPetitFinalsMatch), matchStrategy); return semifinals5TR.Run(rrRankedCompetitors); }
public override CompetitorRanks GenerateResult(int tournamentRunSequence, MatchStrategies.MatchStrategy matchStrategy, List<Competitor> competitors) { // round robin to seed the semifinals TournamentRound rrTR = new TournamentRound(new RrTRS(_numberOfRoundRobinRounds), matchStrategy); CompetitorRanks rrRanks = rrTR.Run(competitors); // run single semifinal knockout round TournamentRound koTR = new TournamentRound(new KoTRS(_winsToClinchKnockoutMatch), matchStrategy); CompetitorRanks koRanks = koTR.Run(rrRanks.OrderBy(x => x.Value).Select(x => x.Key).ToList<Competitor>()); // rank the results first by how they did in the semifinals, then by how they did in the round robin var untypedRanks = koRanks.OrderBy(x => x.Value).ThenBy(x => rrRanks[x.Key]); CompetitorRanks ranks = new CompetitorRanks(); int i = 1; foreach (KeyValuePair<Competitor, int> untypedRank in untypedRanks) { ranks.Add(untypedRank.Key, i++); } return ranks; }
public override CompetitorRanks GenerateResult(int tournamentRunSequence, MatchStrategies.MatchStrategy matchStrategy, List<Competitor> competitors) { if (competitors.Count % 2 != 0) throw new ArgumentException("Collection count must be even.", "competitors"); // round robin to seed the semifinals TournamentRound rrTR = new TournamentRound(new RrTRS(_numberOfRoundRobinRounds), matchStrategy); CompetitorRanks rrRanks = rrTR.Run(competitors); List<Competitor> rankedCompetitors = rrRanks.OrderBy(x => x.Value).Select(x => x.Key).ToList<Competitor>(); CompetitorRanks ranks = new CompetitorRanks(); // run single knockout round for nearby competitors for (int i = 0; i < competitors.Count / 2; i++) { TournamentRound koTR = new TournamentRound(new KoTRS(_winsToClinchKnockoutMatch), matchStrategy); CompetitorRanks koRanks = koTR.Run(new List<Competitor>() { rankedCompetitors[i * 2], rankedCompetitors[(i * 2) + 1] }); ranks.Add(koRanks.First(x => x.Value == 1).Key, (i * 2) + 1); ranks.Add(koRanks.First(x => x.Value == 2).Key, (i * 2) + 2); } return ranks; }
public override CompetitorRanks GenerateResult(int tournamentRunSequence, MatchStrategies.MatchStrategy matchStrategy, List<Competitor> competitors) { // round robin to seed the semifinals TournamentRound roundRobinTR = new TournamentRound(new RrTRS(_numberOfRoundRobinRounds), matchStrategy); CompetitorRanks rrRanks = roundRobinTR.Run(competitors); List<Competitor> rrRankedCompetitors = rrRanks .OrderBy(x => x.Value) .Select(x => x.Key) .ToList<Competitor>(); List<Competitor> top4 = rrRankedCompetitors .Take(4) .ToList<Competitor>(); // semifinals round TournamentRound semifinalsTR = new TournamentRound(new KoSfPfFiTRS(_winsToClinchKnockoutSemifinalsMatch, _winsToClinchKnockoutFinalsMatch, _winsToClinchKnockoutPetitFinalsMatch), matchStrategy); CompetitorRanks semiRanks = semifinalsTR.Run(top4); List<Competitor> bottom4 = rrRankedCompetitors .Skip(4) .Take(4) .ToList<Competitor>(); // single round robin for consolation round TournamentRound consolationRR = new TournamentRound(new RrTRS(_numberOfConsolationRoundRobinRounds), matchStrategy); CompetitorRanks consolationRanks = consolationRR.Run(bottom4); int place = 5; foreach (Competitor competitor in consolationRanks.OrderBy(x => x.Value).Select(x => x.Key)) { semiRanks.Add(competitor, place++); } return semiRanks; }
public override CompetitorRanks GenerateResult(int tournamentRunSequence, MatchStrategies.MatchStrategy matchStrategy, List<Competitor> competitors) { throw new NotImplementedException(); }
public override CompetitorRanks GenerateResult(int tournamentRunSequence, MatchStrategies.MatchStrategy matchStrategy, List<Competitor> competitors) { if (competitors.Count != 8) throw new ArgumentException("Collection count must be 8.", "competitors"); // round robin to seed 2 separate round robins TournamentRound rr1 = new TournamentRound(new RrTRS(_numberOfRr1Rounds), matchStrategy); CompetitorRanks rr1Ranks = rr1.Run(competitors); List<Competitor> rrACompetitors = rr1Ranks .OrderBy(x => x.Value) .Take(4) .Select(x => x.Key) .ToList<Competitor>(); List<Competitor> rrBCompetitors = rr1Ranks .OrderBy(x => x.Value) .Skip(4) .Take(4) .Select(x => x.Key) .ToList<Competitor>(); // round robin to determine 1, 2, 3 TournamentRound rrA = new TournamentRound(new RrTRS(_numberOfRr2Rounds), matchStrategy); CompetitorRanks rrARanks = rrA.Run(rrACompetitors); // round robin to determine 4 TournamentRound rrB = new TournamentRound(new RrTRS(_numberOfRr2Rounds), matchStrategy); CompetitorRanks rrBRanks = rrB.Run(rrBCompetitors); // finals List<Competitor> finalsCompetitors = rrARanks .OrderBy(x => x.Value) .Take(2) .Select(x => x.Key) .ToList<Competitor>(); TournamentRound finals = new TournamentRound(new KoTRS(_winsToClinchFinalMatch), matchStrategy); CompetitorRanks finalsRanks = finals.Run(finalsCompetitors); // petit finals List<Competitor> petitFinalsCompetitors = rrARanks .OrderBy(x => x.Value) .Skip(2) .Take(1) .Select(x => x.Key) .ToList<Competitor>(); Competitor rrBWinner = rrBRanks .OrderBy(x => x.Value) .Take(1) .Select(x => x.Key) .First(); petitFinalsCompetitors.Add(rrBWinner); TournamentRound petitFinals = new TournamentRound(new KoTRS(_winsToClinchPetitFinalMatch), matchStrategy); CompetitorRanks petitFinalsRanks = petitFinals.Run(petitFinalsCompetitors); // consolation round List<Competitor> consolationCompetitors = rrBRanks .OrderBy(x => x.Value) .Skip(1) .Select(x => x.Key) .ToList<Competitor>(); Competitor rrALoser = rrARanks .OrderBy(x => x.Value) .Skip(3) .Take(1) .Select(x => x.Key) .First(); consolationCompetitors.Add(rrALoser); TournamentRound consolationRound = new TournamentRound(new RrTRS(_numberOfRr3Rounds), matchStrategy); CompetitorRanks consolationRanks = consolationRound.Run(consolationCompetitors); CompetitorRanks ranks = new CompetitorRanks(); int i = 1; foreach (var rank in finalsRanks.OrderBy(x => x.Value)) { ranks.Add(rank.Key, i++); } foreach (var rank in petitFinalsRanks.OrderBy(x => x.Value)) { ranks.Add(rank.Key, i++); } foreach (var rank in consolationRanks.OrderBy(x => x.Value)) { ranks.Add(rank.Key, i++); } 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(); }