/// <summary> /// Calculates the return leg based on the previously calculated first leg /// by swapping home / guest team and assigning the referee. /// </summary> private void CalcCombinationsReturnLeg() { _combinationGroupReturnLeg.Clear(); T referee = _combinationGroup[0].Referee; // just to make the compiler happy foreach (var match in _combinationGroup) { // re-assign referee according to settings: switch (_refereeType) { case RefereeType.HomeTeam: referee = match.GuestTeam; break; case RefereeType.GuestTeam: referee = match.HomeTeam; break; case RefereeType.OtherTeamOfGroup: referee = match.Referee; break; } _combinationGroupReturnLeg.Add(new TeamCombination <T>(match.GuestTeam, match.HomeTeam, referee)); } }
/// <summary> /// Groups the calculated team combinations for matches. in a way, that most matches /// can be played in parallel. /// </summary> /// <param name="legType">First leg or return leg.</param> /// <param name="optiType">Optimization type for groups. Differences can be seen be with an uneven number of teams.</param> /// <returns>Return a collection containing collections of team combinations.</returns> internal Collection <TeamCombinationGroup <T> > GetBundledGroups(LegType legType, CombinationGroupOptimization optiType) { var combinationsQueue = new Queue <TeamCombination <T> >(_group.Count); TeamCombinationGroup <T> group; var bundledGroups = new Collection <TeamCombinationGroup <T> >(); // create the FIFO queue foreach (var combination in _group) { combinationsQueue.Enqueue(combination); } switch (optiType) { case CombinationGroupOptimization.NoGrouping: // every group contains a collection with only 1 match while (combinationsQueue.Count > 0) { group = new TeamCombinationGroup <T>(); group.Add(combinationsQueue.Dequeue()); bundledGroups.Add(group); } break; case CombinationGroupOptimization.GroupWithAlternatingHomeGuest: group = new TeamCombinationGroup <T>(); while (combinationsQueue.Count > 0) { TeamCombination <T> combination = combinationsQueue.Dequeue(); if (AnyTeamExistsInGroup(combination, group)) { bundledGroups.Add(group); group = new TeamCombinationGroup <T>(); } group.Add(combination); } if (group.Count > 0) { bundledGroups.Add(group); } break; case CombinationGroupOptimization.LeastGroupsPossible: while (combinationsQueue.Count > 0) { var tmpGroup = new List <TeamCombination <T> >(); tmpGroup.AddRange(combinationsQueue); group = new TeamCombinationGroup <T>(); foreach (var combination in tmpGroup) { if (!AnyTeamExistsInGroup(combination, group)) { group.Add(combinationsQueue.Dequeue()); } } bundledGroups.Add(group); } break; } return(bundledGroups); }
/// <summary> /// Doing the job of creating matches for all teams. /// </summary> private void CalcCombinations() { /* * Round robin match calculations are as follows. * Example with 5 teams (which total in 10 matches): +- A -+ -+ -+ | | | | +- | +- B -+ -+ | | | | | | | | +- | | | C -+ -+ | -+ | | | | | | | | | +- D -+ -+ -+ | | | | +- +- +- E -+ */ if (_teams.Count < 2) { throw new Exception("Round Robin system requires at least 2 teams."); } if (_teams.Count < 3 && _refereeType == RefereeType.OtherTeamOfGroup) { throw new Exception("Round Robin system with separate referee requires at least 3 teams."); } _combinationGroup.Clear(); _maxNumOfCombinations = _teams.Count * (_teams.Count - 1) / 2; _teamCombinationsPerLeg = _teams.Count - 1; for (int count = 0; count < _maxNumOfCombinations; count++) { T homeTeam = GetHomeTeam(); T guestTeam = GetGuestTeam(homeTeam); T referee = homeTeam; int homeTeamNumOfHomeCombs = GetNumOfHomeCombinations(homeTeam); int guestTeamNumOfHomeCombs = GetNumOfHomeCombinations(guestTeam); // make sure that home matches are alternating if (homeTeamNumOfHomeCombs <= guestTeamNumOfHomeCombs) { _combinationGroup.Add(new TeamCombination <T>(homeTeam, guestTeam, referee)); } else { _combinationGroup.Add(new TeamCombination <T>(guestTeam, homeTeam, referee)); } // re-assign referee according to settings switch (_refereeType) { case RefereeType.HomeTeam: _combinationGroup[count].Referee = _combinationGroup[count].HomeTeam; break; case RefereeType.GuestTeam: _combinationGroup[count].Referee = _combinationGroup[count].GuestTeam; break; case RefereeType.OtherTeamOfGroup: _combinationGroup[count].Referee = GetReferee(homeTeam, guestTeam); break; } } CalcCombinationsReturnLeg(); }