Example #1
0
        /// <summary>
        /// This method creates the pool structure and adds it to the database.
        /// Teams are divided into groups of 4, based on their MMR.
        ///
        /// Only works when there are 2^N with N >= 4 teams.
        /// </summary>
        public static void CreatePoolStructure()
        {
            // Get competing teams
            var validTeams = Mongo.Teams.Find(Query <Team> .Where(x => !x.Cancelled))
                             .OrderByDescending(x => x.MMR).ToList();

            // For each pool
            for (int i = 0; i < validTeams.Count() / 4; i++)
            {
                Team[] teams =
                {
                    validTeams[i],
                    validTeams[validTeams.Count / 2 - i - 1],
                    validTeams[validTeams.Count / 2 + i],
                    validTeams[(int)(validTeams.Count * 0.75) + i]
                };

                List <int>[] availabilityLists =
                {
                    new List <int> {
                        0, 1, 2
                    },
                    new List <int> {
                        0, 1, 2
                    },
                    new List <int> {
                        0, 1, 2
                    },
                    new List <int> {
                        0, 1, 2
                    }
                };

                // For each team
                for (int j = 0; j < 4; j++)
                {
                    // Set pool in team objects
                    teams[j].Pool = i;
                    Mongo.Teams.Save(teams[j]);

                    // For each team below team j
                    for (int k = j + 1; k < 4; k++)
                    {
                        // Determine priority
                        var intersect = availabilityLists[j].Intersect(availabilityLists[k]);
                        var p         = intersect.Min();

                        // Remove chosen priority from team availability lists
                        availabilityLists[j].Remove(p);
                        availabilityLists[k].Remove(p);

                        // Determine sides at random
                        var sides = ShuffleTeamIds(teams[j].Id, teams[k].Id);
                        var blue  = sides.Item1;
                        var red   = sides.Item2;

                        // Create match and add to database
                        var allowedSummoners =
                            Mongo.Teams.Find(Query <Team> .Where(team => team.Id == blue || team.Id == red))
                            .SelectMany(team => team.Participants.Select(participant => participant.Summoner.Id))
                            .ToList();

                        var match = new Match
                        {
                            BlueTeamId          = blue,
                            RedTeamId           = red,
                            Phase               = Phase.Pool,
                            Priority            = p,
                            TournamentCode      = TournamentCodeFactory.GetTournamentCode(allowedSummoners),
                            TournamentCodeBlind = TournamentCodeFactory.GetTournamentCodeBlind(allowedSummoners)
                        };
                        Mongo.Matches.Save(match);
                    }
                }
            }
        }
Example #2
0
        /// <summary>
        /// Checks whether the match that was just played has consequences for the structure of the rest of the tournament. If so, push these consequences into the database.
        /// </summary>
        /// <param name="finishedMatch">The match that was just finished.</param>
        public static void NewMatch(Match finishedMatch)
        {
            var finishedMatchWinner = finishedMatch.Winner;

            if (finishedMatch.Phase == Phase.Pool)
            {
                var pool = finishedMatch.BlueTeam.Pool;

                // Check whether the pool is finished
                if (PoolFinished(pool))
                {
                    // Pool is finished
                    // To create brackets, one of the other pools also needs to be finished.
                    // Pools are coupled as follows: 1,2 | 3,4 | etc.

                    int otherPool;

                    // If this is an even pool
                    if (pool % 2 == 0)
                    {
                        otherPool = pool + 1;
                    }
                    else
                    {
                        otherPool = pool - 1;
                    }

                    // If coupled pool is also finished
                    if (PoolFinished(otherPool))
                    {
                        // Get ranking for pools
                        var poolARanking = GetPoolRanking(pool);
                        var poolBRanking = GetPoolRanking(otherPool);

                        // We can now create the brackets for these pools
                        // Winner bracket
                        var allowedSummoners =
                            Mongo.Teams.Find(Query <Team> .Where(team => team.Id == poolARanking[0].Id || team.Id == poolBRanking[1].Id))
                            .SelectMany(team => team.Participants.Select(participant => participant.Summoner.Id))
                            .ToList();

                        var sides = ShuffleTeamIds(poolARanking[0].Id, poolBRanking[1].Id);
                        var match = new Match
                        {
                            BlueTeamId          = sides.Item1,
                            RedTeamId           = sides.Item2,
                            Phase               = Phase.WinnerBracket,
                            Priority            = Math.Min(pool, otherPool),
                            TournamentCode      = TournamentCodeFactory.GetTournamentCode(allowedSummoners),
                            TournamentCodeBlind = TournamentCodeFactory.GetTournamentCodeBlind(allowedSummoners)
                        };

                        allowedSummoners =
                            Mongo.Teams.Find(Query <Team> .Where(team => team.Id == poolBRanking[0].Id || team.Id == poolARanking[1].Id))
                            .SelectMany(team => team.Participants.Select(participant => participant.Summoner.Id))
                            .ToList();

                        var sides2 = ShuffleTeamIds(poolBRanking[0].Id, poolARanking[1].Id);
                        var match2 = new Match
                        {
                            BlueTeamId          = sides2.Item1,
                            RedTeamId           = sides2.Item2,
                            Phase               = Phase.WinnerBracket,
                            Priority            = Math.Max(pool, otherPool),
                            TournamentCode      = TournamentCodeFactory.GetTournamentCode(allowedSummoners),
                            TournamentCodeBlind = TournamentCodeFactory.GetTournamentCodeBlind(allowedSummoners)
                        };

                        Mongo.Matches.Save(match);
                        Mongo.Matches.Save(match2);

                        // Loser bracket
                        // DISABLED FOR 2016 TOURNAMENT
                        // var sides3 = ShuffleTeamIds(poolARanking[2].Id, poolBRanking[3].Id);
                        // var sides4 = ShuffleTeamIds(poolBRanking[2].Id, poolARanking[3].Id);
                        // var match3 = new Match { BlueTeamId = sides3.Item1, RedTeamId = sides3.Item2, Phase = Phase.LoserBracket, Priority = Math.Min(pool, otherPool) };
                        // var match4 = new Match { BlueTeamId = sides4.Item1, RedTeamId = sides4.Item2, Phase = Phase.LoserBracket, Priority = Math.Max(pool, otherPool) };
                        // Mongo.Matches.Save(match3);
                        // Mongo.Matches.Save(match4);

                        // Set the teams to the correct phase
                        poolARanking[0].Phase  = Phase.WinnerBracket;
                        poolARanking[0].OnHold = false;
                        poolARanking[1].Phase  = Phase.WinnerBracket;
                        poolARanking[1].OnHold = false;
                        poolARanking[2].Phase  = Phase.LoserBracket;
                        poolARanking[2].OnHold = false;
                        poolARanking[3].Phase  = Phase.LoserBracket;
                        poolARanking[3].OnHold = false;

                        poolBRanking[0].Phase  = Phase.WinnerBracket;
                        poolBRanking[0].OnHold = false;
                        poolBRanking[1].Phase  = Phase.WinnerBracket;
                        poolBRanking[1].OnHold = false;
                        poolBRanking[2].Phase  = Phase.LoserBracket;
                        poolBRanking[2].OnHold = false;
                        poolBRanking[3].Phase  = Phase.LoserBracket;
                        poolBRanking[3].OnHold = false;

                        // Save all to database
                        Mongo.Teams.Save(poolARanking[0]);
                        Mongo.Teams.Save(poolARanking[1]);
                        Mongo.Teams.Save(poolARanking[2]);
                        Mongo.Teams.Save(poolARanking[3]);

                        Mongo.Teams.Save(poolBRanking[0]);
                        Mongo.Teams.Save(poolBRanking[1]);
                        Mongo.Teams.Save(poolBRanking[2]);
                        Mongo.Teams.Save(poolBRanking[3]);
                    }
                    else
                    {
                        // Set all teams in pool to Hold
                        var teams = Mongo.Teams.Find(Query <Team> .Where(x => x.Pool == pool && !x.Cancelled));
                        foreach (var t in teams)
                        {
                            t.OnHold = true;
                            Mongo.Teams.Save(t);
                        }
                    }
                }
                // If this was the final match in the pool for this team
                else if (finishedMatch.Priority == 2)
                {
                    // Set match teams on hold since they don't have any matches left
                    Team[] teams = { finishedMatch.BlueTeam, finishedMatch.RedTeam };
                    foreach (var t in teams)
                    {
                        t.OnHold = true;
                        Mongo.Teams.Save(t);
                    }
                }
            }
            else if (finishedMatch.Phase == Phase.WinnerBracket || finishedMatch.Phase == Phase.LoserBracket)
            {
                // First phase
                if (finishedMatch.Priority <= 7)
                {
                    int[] couples =
                    {
                        4,
                        5,
                        6,
                        7,
                        0,
                        1,
                        2,
                        3
                    };

                    // Check if other match is also finished
                    var otherPrio     = couples[finishedMatch.Priority];
                    var matchFinished =
                        Mongo.Matches.Find(
                            Query <Match> .Where(
                                x => x.Finished && x.Phase == finishedMatch.Phase && x.Priority == otherPrio));

                    // It's finished, add new bracket match
                    if (matchFinished.Count() == 1)
                    {
                        var otherTeam = matchFinished.First().Winner;

                        var allowedSummoners =
                            Mongo.Teams.Find(Query <Team> .Where(team => team.Id == finishedMatch.WinnerId || team.Id == otherTeam.Id))
                            .SelectMany(team => team.Participants.Select(participant => participant.Summoner.Id))
                            .ToList();

                        var sides = ShuffleTeamIds(finishedMatch.WinnerId, otherTeam.Id);
                        var match = new Match
                        {
                            BlueTeamId          = sides.Item1,
                            RedTeamId           = sides.Item2,
                            Phase               = finishedMatch.Phase,
                            Priority            = Math.Min(finishedMatch.Priority, otherPrio) + 8,
                            TournamentCode      = TournamentCodeFactory.GetTournamentCode(allowedSummoners),
                            TournamentCodeBlind = TournamentCodeFactory.GetTournamentCodeBlind(allowedSummoners)
                        };

                        Mongo.Matches.Save(match);

                        // Set OnHold = false for teams
                        finishedMatchWinner.OnHold = false;
                        otherTeam.OnHold           = false;

                        Mongo.Teams.Save(finishedMatch.Winner);
                        Mongo.Teams.Save(otherTeam);
                    }
                    else
                    {
                        // Not finished, put team on hold
                        finishedMatchWinner.OnHold = true;
                        Mongo.Teams.Save(finishedMatchWinner);
                    }
                }
                // Second phase
                else if (finishedMatch.Priority >= 8 && finishedMatch.Priority <= 11)
                {
                    var couples = new Dictionary <int, int>
                    {
                        { 8, 10 },
                        { 10, 8 },
                        { 9, 11 },
                        { 11, 9 }
                    };

                    // Check if other match is also finished
                    var otherPrio     = couples[finishedMatch.Priority];
                    var matchFinished =
                        Mongo.Matches.Find(
                            Query <Match> .Where(
                                x => x.Finished && x.Phase == finishedMatch.Phase && x.Priority == otherPrio));

                    // It's finished, add new bracket match
                    if (matchFinished.Count() == 1)
                    {
                        var otherTeam = matchFinished.First().Winner;

                        var allowedSummoners =
                            Mongo.Teams.Find(Query <Team> .Where(team => team.Id == finishedMatch.WinnerId || team.Id == otherTeam.Id))
                            .SelectMany(team => team.Participants.Select(participant => participant.Summoner.Id))
                            .ToList();

                        var sides = ShuffleTeamIds(finishedMatch.WinnerId, otherTeam.Id);
                        var match = new Match
                        {
                            BlueTeamId          = sides.Item1,
                            RedTeamId           = sides.Item2,
                            Phase               = finishedMatch.Phase,
                            Priority            = Math.Min(finishedMatch.Priority, otherPrio) + 4,
                            TournamentCode      = TournamentCodeFactory.GetTournamentCode(allowedSummoners),
                            TournamentCodeBlind = TournamentCodeFactory.GetTournamentCodeBlind(allowedSummoners)
                        };

                        Mongo.Matches.Save(match);

                        // Set OnHold = false for teams
                        finishedMatchWinner.OnHold = false;
                        otherTeam.OnHold           = false;

                        Mongo.Teams.Save(finishedMatch.Winner);
                        Mongo.Teams.Save(otherTeam);
                    }
                    else
                    {
                        // Not finished, put team on hold
                        finishedMatchWinner.OnHold = true;
                        Mongo.Teams.Save(finishedMatchWinner);
                    }
                }
                // Third phase, don't do this for loser bracket
                else if ((finishedMatch.Priority == 12 || finishedMatch.Priority == 13) && finishedMatch.Phase == Phase.WinnerBracket)
                {
                    // Check if other match is also finished
                    var otherPrio     = finishedMatch.Priority == 12 ? 13 : 12;
                    var matchFinished =
                        Mongo.Matches.Find(
                            Query <Match> .Where(
                                x => x.Finished && x.Phase == Phase.WinnerBracket && x.Priority == otherPrio));

                    // It's finished, set finale match
                    if (matchFinished.Count() == 1)
                    {
                        var otherId          = matchFinished.First().WinnerId;
                        var allowedSummoners =
                            Mongo.Teams.Find(Query <Team> .Where(team => team.Id == finishedMatch.WinnerId || team.Id == otherId))
                            .SelectMany(team => team.Participants.Select(participant => participant.Summoner.Id))
                            .ToList();

                        var sides = ShuffleTeamIds(finishedMatch.WinnerId, matchFinished.First().WinnerId);
                        var match = Mongo.Matches.Find(Query <Match> .Where(x => x.Phase == Phase.Finale && x.Priority == 0)).First();
                        match.BlueTeamId          = sides.Item1;
                        match.RedTeamId           = sides.Item2;
                        match.TournamentCode      = TournamentCodeFactory.GetTournamentCode(allowedSummoners);
                        match.TournamentCodeBlind = TournamentCodeFactory.GetTournamentCodeBlind(allowedSummoners);
                        Mongo.Matches.Save(match);

                        // Switch sides
                        match                     = Mongo.Matches.Find(Query <Match> .Where(x => x.Phase == Phase.Finale && x.Priority == 1)).First();
                        match.BlueTeamId          = sides.Item2;
                        match.RedTeamId           = sides.Item1;
                        match.TournamentCode      = TournamentCodeFactory.GetTournamentCode(allowedSummoners);
                        match.TournamentCodeBlind = TournamentCodeFactory.GetTournamentCodeBlind(allowedSummoners);
                        Mongo.Matches.Save(match);

                        // Switch sides again
                        match                     = Mongo.Matches.Find(Query <Match> .Where(x => x.Phase == Phase.Finale && x.Priority == 2)).First();
                        match.BlueTeamId          = sides.Item1;
                        match.RedTeamId           = sides.Item2;
                        match.TournamentCode      = TournamentCodeFactory.GetTournamentCode(allowedSummoners);
                        match.TournamentCodeBlind = TournamentCodeFactory.GetTournamentCodeBlind(allowedSummoners);
                        Mongo.Matches.Save(match);

                        // Set team phases
                        var blueTeam = match.BlueTeam;
                        var redTeam  = match.RedTeam;

                        blueTeam.Phase  = Phase.Finale;
                        blueTeam.OnHold = false;
                        redTeam.Phase   = Phase.Finale;
                        redTeam.OnHold  = false;

                        // Save all to database
                        Mongo.Teams.Save(blueTeam);
                        Mongo.Teams.Save(redTeam);

                        // Also set bronze finale match
                        match = Mongo.Matches.Find(Query <Match> .Where(x => x.Phase == Phase.BronzeFinale)).First();
                        var team1       = finishedMatch.BlueTeamId == finishedMatch.WinnerId ? finishedMatch.RedTeamId : finishedMatch.BlueTeamId;
                        var team2       = matchFinished.First().BlueTeamId == matchFinished.First().WinnerId ? matchFinished.First().RedTeamId : matchFinished.First().BlueTeamId;
                        var sidesBronze = ShuffleTeamIds(team1, team2);
                        match.BlueTeamId = sidesBronze.Item1;
                        match.RedTeamId  = sidesBronze.Item2;

                        allowedSummoners =
                            Mongo.Teams.Find(Query <Team> .Where(team => team.Id == match.BlueTeamId || team.Id == match.RedTeamId))
                            .SelectMany(team => team.Participants.Select(participant => participant.Summoner.Id))
                            .ToList();

                        match.TournamentCode      = TournamentCodeFactory.GetTournamentCode(allowedSummoners);
                        match.TournamentCodeBlind = TournamentCodeFactory.GetTournamentCodeBlind(allowedSummoners);
                        Mongo.Matches.Save(match);

                        // And set their teams to the correct phase
                        blueTeam = match.BlueTeam;
                        redTeam  = match.RedTeam;

                        blueTeam.Phase  = Phase.BronzeFinale;
                        blueTeam.OnHold = false;
                        redTeam.Phase   = Phase.BronzeFinale;
                        redTeam.OnHold  = false;

                        // Save all to database
                        Mongo.Teams.Save(blueTeam);
                        Mongo.Teams.Save(redTeam);
                    }
                    else
                    {
                        // Not finished, put team on hold
                        finishedMatchWinner.OnHold = true;
                        var loser = finishedMatchWinner.Id == finishedMatch.BlueTeamId
                            ? finishedMatch.RedTeam
                            : finishedMatch.BlueTeam;
                        loser.OnHold = true;
                        Mongo.Teams.Save(finishedMatchWinner);
                        Mongo.Teams.Save(loser);
                    }
                }
                // Set up loser finale
                // DISABLED FOR 2016 TOURNAMENT

                /*else if ((finishedMatch.Priority == 12 || finishedMatch.Priority == 13) && finishedMatch.Phase == Phase.LoserBracket)
                 * {
                 *  // Check if other match is also finished
                 *  var otherPrio = finishedMatch.Priority == 12 ? 13 : 12;
                 *  var matchFinished =
                 *      Mongo.Matches.Find(
                 *          Query<Match>.Where(
                 *              x => x.Finished && x.Phase == Phase.LoserBracket && x.Priority == otherPrio));
                 *
                 *  // It's finished, set loser finale match
                 *  if (matchFinished.Count() == 1)
                 *  {
                 *      var sides = ShuffleTeamIds(finishedMatch.WinnerId, matchFinished.First().WinnerId);
                 *      var match = Mongo.Matches.Find(Query<Match>.Where(x => x.Phase == Phase.LoserFinale && x.Priority == 0)).First();
                 *      match.BlueTeamId = sides.Item1;
                 *      match.RedTeamId = sides.Item2;
                 *      Mongo.Matches.Save(match);
                 *
                 *      // Set team phases
                 *      var blueTeam = match.BlueTeam;
                 *      var purpleTeam = match.RedTeam;
                 *
                 *      blueTeam.Phase = Phase.LoserFinale;
                 *      blueTeam.OnHold = false;
                 *      purpleTeam.Phase = Phase.LoserFinale;
                 *      purpleTeam.OnHold = false;
                 *
                 *      // Save all to database
                 *      Mongo.Teams.Save(blueTeam);
                 *      Mongo.Teams.Save(purpleTeam);
                 *  }
                 *  else
                 *  {
                 *      // Not finished, put team on hold
                 *      finishedMatchWinner.OnHold = true;
                 *      var loser = finishedMatchWinner.Id == finishedMatch.BlueTeamId
                 *          ? finishedMatch.RedTeam
                 *          : finishedMatch.BlueTeam;
                 *      loser.OnHold = true;
                 *      Mongo.Teams.Save(finishedMatchWinner);
                 *      Mongo.Teams.Save(loser);
                 *  }
                 * }*/
            }
            else if (finishedMatch.Phase == Phase.BronzeFinale)
            {
                // Add third and fourth place to database
                var winner = finishedMatch.Winner;
                var loser  = finishedMatch.BlueTeamId == winner.Id ? finishedMatch.RedTeam : finishedMatch.BlueTeam;
                winner.FinalRanking = 3;
                loser.FinalRanking  = 4;

                Mongo.Teams.Save(winner);
                Mongo.Teams.Save(loser);
            }
            else if (finishedMatch.Phase == Phase.Finale)
            {
                if (finishedMatch.Priority == 2)
                {
                    // We have played all three matches, add final rankings to database
                    var winsBlueTeam = Mongo.Matches.Count(Query <Match> .Where(x => x.Phase == Phase.Finale && x.WinnerId == finishedMatch.BlueTeamId));
                    var winner       = winsBlueTeam >= 2 ? finishedMatch.BlueTeam : finishedMatch.RedTeam;
                    var loser        = winner.Id == finishedMatch.BlueTeamId ? finishedMatch.RedTeam : finishedMatch.BlueTeam;

                    winner.FinalRanking = 1;
                    loser.FinalRanking  = 2;

                    Mongo.Teams.Save(winner);
                    Mongo.Teams.Save(loser);
                }
                else if (finishedMatch.Priority == 1)
                {
                    // We have played two matches so far
                    var winsBlueTeam = Mongo.Matches.Count(Query <Match> .Where(x => x.Phase == Phase.Finale && x.WinnerId == finishedMatch.BlueTeamId));
                    if (winsBlueTeam == 0 || winsBlueTeam == 2)
                    {
                        // It's already decided, scratch third match
                        Mongo.Matches.Remove(Query <Match> .Where(x => x.Phase == Phase.Finale && x.Priority == 2));

                        var winner = finishedMatch.Winner; // winner is always also the winner of the previous match
                        var loser  = winner.Id == finishedMatch.BlueTeamId ? finishedMatch.RedTeam : finishedMatch.BlueTeam;

                        winner.FinalRanking = 1;
                        loser.FinalRanking  = 2;

                        Mongo.Teams.Save(winner);
                        Mongo.Teams.Save(loser);
                    }
                }
                else if (finishedMatch.Priority == 0)
                {
                    // This was the first match, do nothing
                }
            }
        }