예제 #1
0
        public Dictionary <FoulComparison, Dictionary <int, float> > CalculateSituationalScores(int year, out IList <JamTeamData> jamTeamData, out Dictionary <int, JamData> jamDataMap)
        {
            SqlConnection connection = new SqlConnection(_connectionString);

            connection.Open();
            SqlTransaction transaction = connection.BeginTransaction();

            jamTeamData = null;

            JamDataGateway gateway = new JamDataGateway(connection, transaction);

            jamDataMap = gateway.GetAllJamData().ToDictionary(m => m.JamID, m => m);
            if (_jamTeamData == null)
            {
                _jamTeamData = gateway.GetJamTeamDataForYear(year);
                jamTeamData  = _jamTeamData;
            }

            Dictionary <FoulComparison, SortedList <int, int> >   bigMap = CreateBigMap(jamDataMap);
            Dictionary <FoulComparison, Dictionary <int, float> > sss    = CreateSituationalScores(bigMap);

            new SituationalScoreGateway(connection, transaction).InsertSituationalScoresForYear(year, sss);
            transaction.Commit();
            connection.Close();
            return(sss);
        }
        public IList <PlayerPerformance> GetPlayerPointPerformancesForTeam(int teamID)
        {
            // pull data
            SqlConnection connection = new SqlConnection(_connectionString);

            connection.Open();
            SqlTransaction transaction = connection.BeginTransaction();
            var            players     = new PlayerGateway(connection, transaction).GetPlayersForTeam(teamID).ToDictionary(p => p.ID);
            var            jams        = new JamGateway(connection, transaction).GetJamsForTeamAfterDate(teamID, STATS_START_DATE).OrderBy(j => j.ID);
            var            jamBoutMap  = jams.ToDictionary(j => j.ID, j => j.BoutID);
            var            jpe         = new JamPlayerEffectivenessGateway(connection, transaction).GetJamPlayerEffectivenessForTeam(teamID);
            var            jdg         = new JamDataGateway(connection, transaction);
            var            jamTeamData = jdg.GetJamDataForTeam(teamID).ToDictionary(jd => jd.JamID);
            var            jamData     = jdg.GetAllJamData().ToDictionary(jd => jd.JamID);

            foreach (JamTeamData jtd in jamTeamData.Values)
            {
                jtd.Year = jamData[jtd.JamID].PlayDate.Year;
            }
            var teams     = new TeamGateway(connection, transaction).GetAllTeams().ToDictionary(t => t.ID);
            var bouts     = new BoutGateway(connection, transaction).GetBouts().ToDictionary(t => t.ID);
            var penalties = new PenaltyGateway(connection, transaction).GetPenaltiesForTeam(teamID)
                            .GroupBy(p => p.JamID)
                            .ToDictionary(
                g => g.Key,
                g => g.GroupBy(g2 => g2.PlayerID).ToDictionary(g3 => g3.Key, g3 => g3.ToList()));
            var pgs = new PenaltyGroupGateway(connection, transaction).GetPenaltyGroupsForTeamAfterDate(teamID, STATS_START_DATE);
            Dictionary <int, int> boxTimeEstimates = new BoxTimeEstimateGateway(connection, transaction).GetAllBoxTimeEstimates();
            Dictionary <FoulComparison, Dictionary <int, float> > sss = new SituationalScoreGateway(connection, transaction).GetAllSituationalScores();
            AveragePenaltyCostPerJam avgPenCost = new AveragePenaltyCostGateway(connection, transaction).GetAveragePenaltyCost();

            transaction.Commit();
            connection.Close();

            Dictionary <FoulComparison, float> medians              = CalculateMedianScores(sss);
            PenaltyCostCalculator               ppcCalc             = new PenaltyCostCalculator(_connectionString);
            Dictionary <int, double>            groupPenaltyCostMap = ppcCalc.CalculatePointCostsForTeam(jamTeamData, pgs, boxTimeEstimates, sss);
            Dictionary <int, PlayerPerformance> pps = new Dictionary <int, PlayerPerformance>(25);
            Dictionary <int, double>            jamTotalPortionMap = new Dictionary <int, double>(300);

            // we use "jam portions" to divide up the total value of the jam among participating players
            // we give jammers an additional multiplier to their jam portions, based on year, to represent their greater impact on team success

            foreach (Jam jam in jams)
            {
                var pe = jpe[jam.ID];
                foreach (JamPlayerEffectiveness eff in pe.Values)
                {
                    // get/set PlayerPerformance object
                    if (!pps.ContainsKey(eff.PlayerID))
                    {
                        pps[eff.PlayerID] = new PlayerPerformance
                        {
                            Player = players[eff.PlayerID],
                            Bouts  = new List <BoutPerformance>()
                        };
                    }
                    PlayerPerformance curPP = pps[eff.PlayerID];

                    // get/set BoutPerformance object
                    Bout            bout = bouts[jam.BoutID];
                    BoutPerformance bp   = null;
                    if (!curPP.Bouts.Any() ||
                        curPP.Bouts.Last().BoutID != bout.ID)
                    {
                        bp = new BoutPerformance
                        {
                            BoutID       = bout.ID,
                            AwayTeamName = teams[bout.AwayTeamID].Name,
                            HomeTeamName = teams[bout.HomeTeamID].Name,
                            BoutDate     = bout.BoutDate,
                            Jams         = new List <JamPerformance>()
                        };
                        curPP.Bouts.Add(bp);
                    }
                    else
                    {
                        bp = curPP.Bouts.Last();
                    }

                    JamTeamData    jd           = jamTeamData[jam.ID];
                    int            penaltyCount = penalties.ContainsKey(jam.ID) && penalties[jam.ID].ContainsKey(eff.PlayerID) ? penalties[jam.ID][eff.PlayerID].Count() : 0;
                    JamPerformance jp           = new JamPerformance
                    {
                        BlockerJamPercentage = eff.IsJammer ? 0 : eff.JamPortion,
                        DeltaPercentile      = eff.BaseQuality,
                        IsFirstHalf          = jam.IsFirstHalf,
                        JamID = jam.ID,
                        JammerJamPercentage = eff.IsJammer ? eff.JamPortion : 0,
                        JamNumber           = jam.JamNumber,
                        JamPenalties        = penaltyCount,
                        MedianDelta         = medians[jd.FoulComparison],
                        PenaltyCost         = 0,
                        PointDelta          = jd.PointDelta
                    };
                    double jammerRatio = bouts[jamBoutMap[jam.ID]].BoutDate.Year == 2019 ? 2.0 : 4.0;
                    if (jamTotalPortionMap.ContainsKey(jam.ID))
                    {
                        jamTotalPortionMap[jam.ID] += eff.IsJammer ? eff.JamPortion * jammerRatio : eff.JamPortion;
                    }
                    else
                    {
                        jamTotalPortionMap[jam.ID] = eff.IsJammer ? eff.JamPortion * jammerRatio : eff.JamPortion;
                    }
                    bp.Jams.Add(jp);
                }
            }

            foreach (PenaltyGroup pg in pgs)
            {
                foreach (Penalty p in pg.Penalties)
                {
                    if (jams.Any(j => j.ID == p.JamID))
                    {
                        JamPerformance jp = pps[p.PlayerID].Bouts.SelectMany(b => b.Jams).Where(j => j.JamID == p.JamID).First();
                        jp.PenaltyCost += groupPenaltyCostMap[pg.GroupID];
                    }
                }
            }

            foreach (PlayerPerformance pp in pps.Values)
            {
                RollUpPlayerPerformance(avgPenCost, jamTotalPortionMap, pp);
            }

            CalculateTeamAverages(pps, bouts);
            foreach (PlayerPerformance pp in pps.Values)
            {
                pp.BlockerPerformance.PlayerValueVersusTeamAverage = pp.Bouts.Sum(b => b.BlockerPerformance.PlayerValueVersusTeamAverage);
                pp.JammerPerformance.PlayerValueVersusTeamAverage  = pp.Bouts.Sum(b => b.JammerPerformance.PlayerValueVersusTeamAverage);
            }

            return(pps.Values.ToList());
        }