Exemple #1
0
        public void SaveNewEqualizationMatches(IndentedTextWriter writer, bool verbose)
        {
            if (NewEqualizationMatches.Count > 0)
            {
                EqualizationMatch.SaveEndOfTournamentBlock(this, tournamentEndBlockStart, tournamentEndBlockDuration);

                foreach (var equalizationMatch in NewEqualizationMatches)
                {
                    equalizationMatch.SaveToDatabase();
                }
                EqualizationMatch.SaveEqualizationMatchesBlock(this, NewEqualizationMatches.First().ScheduleStart.LocalDateTime, NewEqualizationMatches.Count);
            }
        }
Exemple #2
0
        // Equalization matches cannot be ties, lest that biases the scoring results. Hence,
        // we decree that matches shall be scored (manually, using ScoreKeeper) as a win
        // for Blue. Thus all blue participants in equalization matches need to be surrogates.
        protected void PlanEqualizationMatches()
        {
            int averagingMatchCountGoal = ProgramOptions.AveragingMatchCountGoal ?? MaxAveragingMatchCount;

            ISet <Team>             completedTeams      = new HashSet <Team>();
            IDictionary <Team, int> matchesNeededByTeam = new ConcurrentDictionary <Team, int>();

            foreach (Team team in Teams)
            {
                int teamAveragingMatchesNeeded = averagingMatchCountGoal - team.AveragingMatchCount;
                if (teamAveragingMatchesNeeded == 0)
                {
                    completedTeams.Add(team);
                }
                else
                {
                    matchesNeededByTeam[team] = teamAveragingMatchesNeeded;
                }
            }

            List <Team> rotating = new List <Team>(completedTeams);

            NewEqualizationMatches.Clear();
            tournamentEndBlockStart    = ThisEventNominalEnd + TimeSpan.FromDays(2); // two days: 1. haven't run eliminations yet 2. End is only day-granular
            tournamentEndBlockDuration = TimeSpan.FromMinutes(10);

            DateTimeOffset equalizationMatchStart    = tournamentEndBlockStart + tournamentEndBlockDuration + TimeSpan.FromMinutes(10);
            TimeSpan       equalizationMatchDuration = TimeSpan.FromSeconds(5);
            TimeSpan       equalizationMatchInterval = TimeSpan.FromSeconds(7); // arbitrary, but close enough that re-runs of this tool will still likely be later

            while (matchesNeededByTeam.Count > 0)
            {
                // Take at most two teams for the red side
                var teams = new List <Team>(matchesNeededByTeam.Keys.Take(2));
                var remainingIncomplete = new List <Team>(matchesNeededByTeam.Keys.Skip(2));

                // Round out to 4 with teams that will be surrogates. We can choose arbitrary teams,
                // but we need to be careful in events that have a very small team count. So, we start
                // with the remaining incomplete teams then move on to those who have completed. The
                // later we rotate, mostly just for fun.
                int numSurrogatesNeeded = 4 - teams.Count;
                var surrogates          = new List <Team>(remainingIncomplete.Take(numSurrogatesNeeded));
                var rotatingSurrogates  = new List <Team>(rotating.Take(numSurrogatesNeeded - surrogates.Count));

                surrogates.AddRange(rotatingSurrogates);
                rotating.RemoveRange(0, rotatingSurrogates.Count);
                rotating.AddRange(rotatingSurrogates);

                teams.AddRange(surrogates);
                var isSurrogates = new List <bool>(teams.Select(team => surrogates.Contains(team)));

                EqualizationMatch equalizationMatch = new EqualizationMatch(this, teams, isSurrogates, equalizationMatchStart, equalizationMatchDuration);
                NewEqualizationMatches.Add(equalizationMatch);
                equalizationMatchStart = equalizationMatchStart + equalizationMatchInterval;

                foreach (Team team in teams)
                {
                    if (!surrogates.Contains(team))
                    {
                        matchesNeededByTeam[team] = matchesNeededByTeam[team] - 1;
                        if (matchesNeededByTeam[team] == 0)
                        {
                            matchesNeededByTeam.Remove(team);
                            completedTeams.Add(team);
                            rotating.Add(team);
                        }
                    }
                }
            }
        }
Exemple #3
0
        public void LoadDataAccessLayer()
        {
            foreach (var row in Tables.LeagueMeets.Rows)
            {
                if (row.EventCode.NonNullValue == ThisEventCode)
                {
                    ThisEvent thisEvent = new ThisEvent(this, row, ThisEventType, ThisEventStatus);
                    EventsByCode[thisEvent.EventCode] = thisEvent;
                }
                else
                {
                    HistoricalLeagueMeet anEvent = new HistoricalLeagueMeet(this, row, TEventType.LEAGUE_MEET, TEventStatus.ARCHIVED);
                    EventsByCode[anEvent.EventCode] = anEvent;
                }
            }

            if (!EventsByCode.ContainsKey(ThisEventCode))
            {
                // *Always* need ThisEvent to be real. Make if we didn't previously encounter. Code path taken only in non-leagues?
                var row = Tables.LeagueMeets.NewRow();
                row.EventCode.Value = ThisEventCode;
                row.Name.Value      = ThisEventName;
                row.Start.Value     = ThisEventNominalStart;
                row.End.Value       = ThisEventNominalEnd;
                ThisEvent thisEvent = new ThisEvent(this, row, ThisEventType, ThisEventStatus);
                EventsByCode[thisEvent.EventCode] = thisEvent;
            }

            foreach (var row in Tables.Team.Rows)
            {
                Team team = new Team(this, row);
                TeamsByNumber[team.TeamNumber] = team;
                TeamsById[team.FMSTeamId]      = team;
                Teams.Add(team);
            }
            Teams.Sort((a, b) => a.TeamNumber - b.TeamNumber);

            foreach (var row in Tables.ScheduleDetail.Rows)
            {
                if (row.IsEqualizationMatch(this))
                {
                    EqualizationMatch equalizationMatch = new EqualizationMatch(this, row);
                    Trace.Assert(equalizationMatch.IsEqualizationMatch);
                    LoadedEqualizationMatches.Add(equalizationMatch);
                }
                else
                {
                    ScheduledMatch scheduledMatch = new ScheduledMatch(this, row);
                    Trace.Assert(!scheduledMatch.IsEqualizationMatch);
                }
            }

            // fmsMatch
            foreach (var row in Tables.Match.Rows)
            {
                MatchPlayedThisEvent matchPlayed = new MatchPlayedThisEvent(this, row);
                AddOrReplacePlayedMatch(matchPlayed);
            }

            // psData
            foreach (var row in Tables.QualsData.Rows.Concat(Tables.ElimsData.Rows))
            {
                if (PlayedMatchesByNumber.TryGetValue(row.MatchNumber.NonNullValue, out List <MatchPlayedThisEvent> playedMatches))
                {
                    foreach (MatchPlayedThisEvent match in playedMatches)
                    {
                        match.Load(row);
                    }
                }
            }

            // psScores
            foreach (var row in Tables.QualsScores.Rows)
            {
                if (PlayedMatchesByNumber.TryGetValue(row.MatchNumber.NonNullValue, out List <MatchPlayedThisEvent> playedMatches))
                {
                    foreach (MatchPlayedThisEvent match in playedMatches)
                    {
                        match.Load(row);
                    }
                }
            }
            foreach (var row in Tables.ElimsScores.Rows)
            {
                if (PlayedMatchesByNumber.TryGetValue(row.MatchNumber.NonNullValue, out List <MatchPlayedThisEvent> playedMatches))
                {
                    foreach (MatchPlayedThisEvent match in playedMatches)
                    {
                        match.Load(row);
                    }
                }
            }

            // psGame
            foreach (var row in Tables.QualsGameSpecific.Rows.Concat(Tables.ElimsGameSpecific.Rows))
            {
                if (PlayedMatchesByNumber.TryGetValue(row.MatchNumber.NonNullValue, out List <MatchPlayedThisEvent> playedMatches))
                {
                    foreach (MatchPlayedThisEvent match in playedMatches)
                    {
                        match.Load(row);
                    }
                }
            }

            // psResult
            foreach (var row in Tables.QualsResults.Rows.Concat(Tables.ElimsResults.Rows))
            {
                if (PlayedMatchesByNumber.TryGetValue(row.MatchNumber.NonNullValue, out List <MatchPlayedThisEvent> playedMatches))
                {
                    foreach (MatchPlayedThisEvent match in playedMatches)
                    {
                        match.Load(row);
                    }
                }
            }

            // psHistory
            foreach (var row in Tables.QualsCommitHistory.Rows.Concat(Tables.ElimsCommitHistory.Rows))
            {
                if (PlayedMatchesByNumber.TryGetValue(row.MatchNumber.NonNullValue, out List <MatchPlayedThisEvent> playedMatches))
                {
                    foreach (MatchPlayedThisEvent match in playedMatches)
                    {
                        match.Load(row);
                    }
                }
            }

            // psScoresHistory
            foreach (var row in Tables.QualsScoresHistory.Rows)
            {
                if (PlayedMatchesByNumber.TryGetValue(row.MatchNumber.NonNullValue, out List <MatchPlayedThisEvent> playedMatches))
                {
                    foreach (MatchPlayedThisEvent match in playedMatches)
                    {
                        match.Load(row);
                    }
                }
            }
            foreach (var row in Tables.ElimsScoresHistory.Rows)
            {
                if (PlayedMatchesByNumber.TryGetValue(row.MatchNumber.NonNullValue, out List <MatchPlayedThisEvent> playedMatches))
                {
                    foreach (MatchPlayedThisEvent match in playedMatches)
                    {
                        match.Load(row);
                    }
                }
            }

            // psGameHistory
            foreach (var row in Tables.QualsGameSpecificHistory.Rows.Concat(Tables.ElimsGameSpecificHistory.Rows))
            {
                if (PlayedMatchesByNumber.TryGetValue(row.MatchNumber.NonNullValue, out List <MatchPlayedThisEvent> playedMatches))
                {
                    foreach (MatchPlayedThisEvent match in playedMatches)
                    {
                        match.Load(row);
                    }
                }
            }

            LeagueSubsystem.Load();
        }