Example #1
0
        /// <summary>
        /// Get list of fixtures when the precedent round is a group round and no random drawing is performed
        /// TODO: Currently only work when there is two qualified teams by group
        /// </summary>
        /// <param name="round">The round to draw</param>
        /// <param name="previousRound">The previous round</param>
        /// <returns></returns>
        public static List <Match> DrawNoRandomDrawing(KnockoutRound round, GroupsRound previousRound)
        {
            //We assume teams are added in round in the order of ranking and group
            List <Match> res = new List <Match>();

            RoundProgrammation programmation = round.programmation;

            for (int i = 0; i < round.clubs.Count / 2; i++)
            {
                Club home = i < round.clubs.Count / 4 ? round.clubs[i * 4] : round.clubs[((i - (round.clubs.Count / 4)) * 4) + 2];
                Club away = i < round.clubs.Count / 4 ? round.clubs[(i * 4) + 3] : round.clubs[((i - (round.clubs.Count / 4)) * 4) + 1];

                DateTime day = GetRoundProgrammationDate(round, programmation);

                if (round.rules.Contains(Rule.AtHomeIfTwoLevelDifference))
                {
                    Club[] switchedTeams = SwitchTeams(home, away);
                    home = switchedTeams[0];
                    away = switchedTeams[1];
                }
                res.Add(new Match(home, away, day, !round.twoLegs));
            }

            TVSchedule(res, round.programmation.tvScheduling, 0);
            if (round.twoLegs)
            {
                CreateSecondLegKnockOutRound(res, round, programmation);
            }

            return(res);
        }
Example #2
0
        private static DateTime GetRoundProgrammationDate(Round round, RoundProgrammation programmation)
        {
            DateTime day = programmation.gamesDays[0].ConvertToDateTime(Session.Instance.Game.date.Year);

            if (Utils.IsBeforeWithoutYear(day, round.DateInitialisationRound()))
            {
                day = programmation.gamesDays[0].ConvertToDateTime(Session.Instance.Game.date.Year + 1);
            }
            day.AddHours(programmation.defaultHour.Hours);
            day.AddMinutes(programmation.defaultHour.Minutes);
            return(day);
        }
Example #3
0
        /// <summary>
        /// Get list of fixtures when the precedent round is a knockout round and no random drawing is performed
        /// </summary>
        /// <param name="round">The round to draw</param>
        /// <param name="previousRound">The previous round</param>
        /// <returns></returns>
        public static List <Match> DrawNoRandomDrawing(KnockoutRound round, KnockoutRound previousRound)
        {
            //We assume teams are added in round in the order of the games
            List <Match> res = new List <Match>();

            List <Club> clubsList = new List <Club>();

            for (int i = previousRound.matches.Count - round.clubs.Count; i < previousRound.matches.Count; i++)
            {
                clubsList.Add(previousRound.matches[i].Winner);
            }

            RoundProgrammation programmation = round.programmation;

            for (int i = 0; i < clubsList.Count / 2; i++)
            {
                Club home = clubsList[i * 2];
                Club away = clubsList[(i * 2) + 1];

                DateTime day = GetRoundProgrammationDate(round, programmation);

                if (round.rules.Contains(Rule.AtHomeIfTwoLevelDifference))
                {
                    Club[] switchedTeams = SwitchTeams(home, away);
                    home = switchedTeams[0];
                    away = switchedTeams[1];
                }
                res.Add(new Match(home, away, day, !round.twoLegs));
            }

            TVSchedule(res, round.programmation.tvScheduling, 0);
            if (round.twoLegs)
            {
                CreateSecondLegKnockOutRound(res, round, programmation);
            }

            return(res);
        }
Example #4
0
        /// <summary>
        /// The drawing for direct-elimination round
        /// </summary>
        /// <param name="round">The round to draw</param>
        /// <returns>The list of games of this round</returns>
        public static List <Match> Draw(KnockoutRound round)
        {
            List <Match> res = new List <Match>();


            List <Club>[] hats = new List <Club>[] { new List <Club>(), new List <Club>() };

            if (round.randomDrawingMethod == RandomDrawingMethod.Ranking)
            {
                GroupsRound   previousRound       = round.Tournament.rounds[round.Tournament.rounds.IndexOf(round) - 1] as GroupsRound;
                List <Club>[] clubsByRankPosition = new List <Club> [previousRound.maxClubsInGroup];
                List <Club>   allClubs            = new List <Club>();

                for (int i = 0; i < clubsByRankPosition.Length; i++)
                {
                    clubsByRankPosition[i] = new List <Club>();
                }

                for (int i = 0; i < previousRound.groupsCount; i++)
                {
                    List <Club> ranking = previousRound.Ranking(i);
                    for (int j = 0; j < ranking.Count; j++)
                    {
                        clubsByRankPosition[j].Add(ranking[j]);
                    }
                }

                for (int i = 0; i < clubsByRankPosition.Length; i++)
                {
                    clubsByRankPosition[i].Sort(new ClubRankingComparator(previousRound.matches));
                    allClubs.AddRange(clubsByRankPosition[i]);
                }

                allClubs = new List <Club>(allClubs.GetRange(0, round.clubs.Count));
                hats[0].AddRange(allClubs.GetRange(0, round.clubs.Count / 2));
                hats[1].AddRange(allClubs.GetRange(round.clubs.Count / 2, round.clubs.Count / 2));
            }
            else if (round.randomDrawingMethod == RandomDrawingMethod.Coefficient)
            {
                List <Club> allClubs = new List <Club>(round.clubs);
                allClubs.Sort(new ClubComparator(ClubAttribute.CONTINENTAL_COEFFICIENT));
                hats[0].AddRange(allClubs.GetRange(0, round.clubs.Count / 2));
                hats[1].AddRange(allClubs.GetRange(round.clubs.Count / 2, round.clubs.Count / 2));
            }
            else if (round.randomDrawingMethod == RandomDrawingMethod.Geographic)
            {
                List <Club> allClubs             = new List <Club>(round.clubs);
                int         currentClubsByGroups = allClubs.Count;
                int         groupsNumber         = 1;
                while ((currentClubsByGroups / 2) % 2 == 0 && (allClubs.Count / groupsNumber) > 20)
                {
                    currentClubsByGroups /= 2;
                    groupsNumber         *= 2;
                }
                KMeansClustering kmeans = new KMeansClustering(allClubs, groupsNumber);
                hats = kmeans.CreateClusters();
            }
            //Random
            else
            {
                List <Club> allClubs = new List <Club>(round.clubs);
                allClubs.Shuffle();
                for (int i = 0; i < allClubs.Count; i++)
                {
                    hats[i < allClubs.Count / 2 ? 0 : 1].Add(allClubs[i]);
                }
            }


            RoundProgrammation programmation = round.programmation;
            int currentGeographicHat         = 0;

            for (int i = 0; i < round.clubs.Count / 2; i++)
            {
                Club home;
                Club away;
                if (round.randomDrawingMethod != RandomDrawingMethod.Geographic)
                {
                    int hat = Session.Instance.Random(0, 2);
                    home = DrawClub(hats[hat]);
                    away = DrawClub(hats[hat == 1 ? 0 : 1]);
                }
                else
                {
                    if (hats[currentGeographicHat].Count < 2)
                    {
                        currentGeographicHat++;
                    }
                    home = DrawClub(hats[currentGeographicHat]);
                    away = DrawClub(hats[currentGeographicHat]);
                }

                DateTime day = GetRoundProgrammationDate(round, programmation);

                if (round.rules.Contains(Rule.AtHomeIfTwoLevelDifference))
                {
                    Club[] switchedTeams = SwitchTeams(home, away);
                    home = switchedTeams[0];
                    away = switchedTeams[1];
                }
                res.Add(new Match(home, away, day, !round.twoLegs));
            }

            TVSchedule(res, round.programmation.tvScheduling, 0);
            if (round.twoLegs)
            {
                CreateSecondLegKnockOutRound(res, round, programmation);
            }
            return(res);
        }
Example #5
0
        private static void CreateSecondLegKnockOutRound(List <Match> gamesList, Round round, RoundProgrammation programmation)
        {
            List <Match> games      = new List <Match>();
            List <Match> firstRound = new List <Match>(gamesList);

            foreach (Match m in firstRound)
            {
                DateTime day = programmation.gamesDays[1].ConvertToDateTime(Session.Instance.Game.date.Year);
                if (Utils.IsBeforeWithoutYear(day, round.DateInitialisationRound()))
                {
                    day = programmation.gamesDays[1].ConvertToDateTime(Session.Instance.Game.date.Year + 1);
                }
                day.AddHours(programmation.defaultHour.Hours);
                day.AddMinutes(programmation.defaultHour.Minutes);

                Match secondRound = new Match(m.away, m.home, day, !round.twoLegs, m);
                games.Add(secondRound);
                gamesList.Add(secondRound);
            }
            TVSchedule(games, round.programmation.tvScheduling, 0);
        }
Example #6
0
        /// <summary>
        /// Round robin algorithm to generate games
        /// </summary>
        /// <param name="clubs">List of clubs</param>
        /// <param name="programmation">TV / Federation schedule for games</param>
        /// <param name="twoLegged">One or two games</param>
        /// <returns></returns>
        public static List <Match> GenerateCalendar(List <Club> clubs, Round tournamentRound, bool twoLegged)
        {
            RoundProgrammation programmation = tournamentRound.programmation;
            List <Match>       res           = new List <Match>();
            bool ghost = false;
            int  teams = clubs.Count;

            if (teams % 2 == 1)
            {
                ghost = true;
                teams++;
            }

            int totalRound    = teams - 1;
            int gamesPerRound = teams / 2;

            string[,] rounds = new string[totalRound, gamesPerRound];

            for (int round = 0; round < totalRound; round++)
            {
                for (int match = 0; match < gamesPerRound; match++)
                {
                    int home = (round + match) % (teams - 1);
                    int away = (teams - 1 - match + round) % (teams - 1);

                    if (match == 0)
                    {
                        away = teams - 1;
                    }

                    rounds[round, match] = (home + 1) + " v " + (away + 1);
                }
            }

            string[,] interleaved = new string[totalRound, gamesPerRound];
            int evn = 0;
            int odd = (teams / 2);

            for (int i = 0; i < totalRound; i++)
            {
                if (i % 2 == 0)
                {
                    for (int j = 0; j < gamesPerRound; j++)
                    {
                        interleaved[i, j] = rounds[evn, j];
                    }
                    evn++;
                }
                else
                {
                    for (int j = 0; j < gamesPerRound; j++)
                    {
                        interleaved[i, j] = rounds[odd, j];
                    }
                    odd++;
                }
            }

            rounds = interleaved;

            for (int round = 0; round < totalRound; round++)
            {
                if (round % 2 == 1)
                {
                    rounds[round, 0] = flip(rounds[round, 0]);
                }
            }

            for (int i = 0; i < totalRound; i++)
            {
                List <Match> matchs = new List <Match>();
                for (int j = 0; j < gamesPerRound; j++)
                {
                    string[] compenents = rounds[i, j].Split(new string[] { " v " }, StringSplitOptions.None);
                    int      a          = int.Parse(compenents[0]);
                    int      b          = int.Parse(compenents[1]);

                    if (!ghost || (a != teams && b != teams))
                    {
                        //-1 car index dans liste de 0 à n-1, et des clubs de 1 à n
                        Club e1 = clubs[a - 1];
                        Club e2 = clubs[b - 1];

                        //Game day
                        DateTime jour = programmation.gamesDays[i].ConvertToDateTime(Session.Instance.Game.date.Year);
                        if (Utils.IsBeforeWithoutYear(jour, tournamentRound.DateInitialisationRound()))
                        {
                            jour = programmation.gamesDays[i].ConvertToDateTime(Session.Instance.Game.date.Year + 1);
                        }
                        jour = jour.AddHours(programmation.defaultHour.Hours);
                        jour = jour.AddMinutes(programmation.defaultHour.Minutes);

                        Match m = new Match(e1, e2, jour, false);
                        res.Add(m);
                        matchs.Add(m);
                    }
                }
                TVSchedule(matchs, programmation.tvScheduling, i + 1);
            }
            if (twoLegged)
            {
                if (ghost)
                {
                    gamesPerRound--;
                }
                //Part 1 : manager Journey [2-end]
                int          nbGamesFirstRound = res.Count / gamesPerRound;
                List <Match> games;
                for (int i = 1; i < nbGamesFirstRound; i++)
                {
                    games = new List <Match>();
                    for (int j = 0; j < gamesPerRound; j++)
                    {
                        Match mbase = res[gamesPerRound * i + j];

                        DateTime jour = programmation.gamesDays[nbGamesFirstRound + i - 1].ConvertToDateTime(Session.Instance.Game.date.Year);
                        if (Utils.IsBeforeWithoutYear(jour, tournamentRound.DateInitialisationRound()))
                        {
                            jour = programmation.gamesDays[nbGamesFirstRound + i - 1].ConvertToDateTime(Session.Instance.Game.date.Year + 1);
                        }
                        jour = jour.AddHours(programmation.defaultHour.Hours);
                        jour = jour.AddMinutes(programmation.defaultHour.Minutes);

                        Match retour = new Match(mbase.away, mbase.home, jour, false);
                        games.Add(retour);
                        res.Add(retour);
                    }

                    if (nbGamesFirstRound - i >= programmation.lastMatchDaysSameDayNumber)
                    {
                        TVSchedule(games, programmation.tvScheduling, nbGamesFirstRound + i);
                    }
                }
                //Last journey : first journey inverted
                games = new List <Match>();
                for (int i = 0; i < gamesPerRound; i++)
                {
                    Match mbase = res[i];

                    DateTime jour = programmation.gamesDays[programmation.gamesDays.Count - 1].ConvertToDateTime(Session.Instance.Game.date.Year);
                    if (Utils.IsBeforeWithoutYear(jour, tournamentRound.DateInitialisationRound()))
                    {
                        jour = programmation.gamesDays[programmation.gamesDays.Count - 1].ConvertToDateTime(Session.Instance.Game.date.Year + 1);
                    }
                    jour = jour.AddHours(programmation.defaultHour.Hours);
                    jour = jour.AddMinutes(programmation.defaultHour.Minutes);
                    Match retour = new Match(mbase.away, mbase.home, jour, false);
                    games.Add(retour);
                    res.Add(retour);
                }

                if (programmation.lastMatchDaysSameDayNumber < 1)
                {
                    TVSchedule(games, programmation.tvScheduling, nbGamesFirstRound * 2);
                }
            }

            return(res);
        }