Example #1
0
        public string Save(Penalty aPenalty)
        {
            PenaltyGateway aPenaltyGateway = new PenaltyGateway();
            int            rowAffected     = aPenaltyGateway.Save(aPenalty);

            if (rowAffected > 0)
            {
                return("Penalty Create Successfuly");
            }
            return("Penalty Create Fail");
        }
        public IList <Dictionary <int, PlayerPerformance> > GetAllPlayerPointPerformances(int numberOfIterations)
        {
            // pull data
            SqlConnection connection = new SqlConnection(_connectionString);

            connection.Open();
            SqlTransaction transaction = connection.BeginTransaction();
            var            players     = new PlayerGateway(connection, transaction).GetAllPlayers().GroupBy(p => p.ID).ToDictionary(g => g.Key, g => g.ToDictionary(g2 => g2.TeamID));
            var            jams        = new JamGateway(connection, transaction).GetAllJams().OrderBy(j => j.ID);
            var            jamBoutMap  = jams.ToDictionary(j => j.ID, j => j.BoutID);
            var            jpe         = new JamPlayerEffectivenessGateway(connection, transaction).GetAllJamPlayerEffectiveness();
            var            jamData     = new JamDataGateway(connection, transaction).GetJamTeamDataForYear(STATS_START_DATE.Year)
                                         .GroupBy(jd => jd.JamID)
                                         .ToDictionary(g => g.Key, g => g.ToDictionary(g2 => g2.TeamID));
            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).GetAllPenalties()
                            .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).GetAllPenaltyGroups();
            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();
            Dictionary <int, Dictionary <int, JamPlayer> > jamPlayerMap = new JamPlayerGateway(connection, transaction).GetJamPlayers()
                                                                          .GroupBy(jp => jp.JamID)
                                                                          .ToDictionary(g => g.Key, g => g.ToDictionary(g2 => g2.PlayerID));

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

            Dictionary <FoulComparison, float> medians   = CalculateMedianScores(sss);
            PenaltyCostCalculator    ppcCalc             = new PenaltyCostCalculator(_connectionString);
            Dictionary <int, double> groupPenaltyCostMap = PenaltyCostCalculator.CalculatePointCosts(jamData, jamPlayerMap, pgs, boxTimeEstimates, sss);
            Dictionary <int, double> jamTotalPortionMap  = new Dictionary <int, double>(300);

            var previousResult = GenerateInitialPlayerPerformance(players, jams, jpe, jamData, teams, bouts, penalties, pgs, avgPenCost, medians, groupPenaltyCostMap, jamTotalPortionMap);

            List <Dictionary <int, PlayerPerformance> > result = new List <Dictionary <int, PlayerPerformance> >(numberOfIterations);

            result.Add(previousResult);
            int i = 0;

            while (i < numberOfIterations)
            {
                previousResult = GeneratePlayerPerformanceIteration(previousResult, jams, jamData, jamTotalPortionMap, jpe, avgPenCost);
                result.Add(previousResult);
                i++;
            }

            return(result);
        }
        public IList<Dictionary<int, PlayerPerformance>> GetAllPlayerPointPerformances(int numberOfIterations)
        {
            // pull data
            SqlConnection connection = new SqlConnection(_connectionString);
            connection.Open();
            SqlTransaction transaction = connection.BeginTransaction();
            var players = new PlayerGateway(connection, transaction).GetAllPlayers().GroupBy(p => p.ID).ToDictionary(g => g.Key, g => g.ToDictionary(g2 => g2.TeamID));
            var jams = new JamGateway(connection, transaction).GetAllJams().OrderBy(j => j.ID);
            var jamBoutMap = jams.ToDictionary(j => j.ID, j => j.BoutID);
            var jpe = new JamPlayerEffectivenessGateway(connection, transaction).GetAllJamPlayerEffectiveness();
            var jamData = new JamDataGateway(connection, transaction).GetAllJamData()
                .GroupBy(jd => jd.JamID)
                .ToDictionary(g => g.Key, g => g.ToDictionary(g2 => g2.TeamID));
            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).GetAllPenalties()
                .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).GetAllPenaltyGroups();
            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();
            Dictionary<int, Dictionary<int, JamPlayer>> jamPlayerMap = new JamPlayerGateway(connection, transaction).GetJamPlayers()
                .GroupBy(jp => jp.JamID)
                .ToDictionary(g => g.Key, g => g.ToDictionary(g2 => g2.PlayerID));
            transaction.Commit();
            connection.Close();

            Dictionary<FoulComparison, float> medians = CalculateMedianScores(sss);
            PenaltyCostCalculator ppcCalc = new PenaltyCostCalculator(_connectionString);
            Dictionary<int, double> groupPenaltyCostMap = PenaltyCostCalculator.CalculatePointCosts(jamData, jamPlayerMap, pgs, boxTimeEstimates, sss);
            Dictionary<int, double> jamTotalPortionMap = new Dictionary<int, double>(300);

            var previousResult = GenerateInitialPlayerPerformance(players, jams, jpe, jamData, teams, bouts, penalties, pgs, avgPenCost, medians, groupPenaltyCostMap, jamTotalPortionMap);

            List<Dictionary<int, PlayerPerformance>> result = new List<Dictionary<int, PlayerPerformance>>(numberOfIterations);
            result.Add(previousResult);
            int i = 0;
            while(i < numberOfIterations)
            {
                previousResult = GeneratePlayerPerformanceIteration(previousResult, jams, jamData, jamTotalPortionMap, jpe, avgPenCost);
                result.Add(previousResult);
                i++;
            }

            return result;
        }
Example #4
0
        private void AddTeamPenalties(IList <Jam> jams, Dictionary <string, Player> players, Dictionary <int, PlayerPenaltiesModel> playerPenalties)
        {
            //PenaltyProcessor processor = new PenaltyProcessor(jams, players);
            PenaltyGateway penaltyGateway = new PenaltyGateway(_connection, _transaction);
            bool           isSuccess      = true;

            foreach (KeyValuePair <int, PlayerPenaltiesModel> kvp in playerPenalties)
            {
                int penaltyCount = 0;
                foreach (PenaltyModel penalty in kvp.Value.Penalties)
                {
                    Jam jam = jams.FirstOrDefault(j => j.IsFirstHalf == penalty.IsFirstHalf && j.JamNumber == penalty.JamNumber);
                    if (jam == null)
                    {
                        Console.WriteLine(string.Format("Unknown jam number {0} on penalty for player {1}.", penalty.JamNumber, kvp.Value.PlayerNumber));
                        isSuccess = false;
                    }
                    penaltyCount++;
                    Penalty pen = new Penalty
                    {
                        JamID         = jam.ID,
                        PlayerID      = kvp.Key,
                        PenaltyCode   = penalty.PenaltyCode,
                        PenaltyNumber = penaltyCount,
                        MatchingKey   = penalty.SpecificKey
                    };
                    if (pen.MatchingKey != null)
                    {
                        Console.WriteLine(string.Format("Special case penalty {0}{1} encountered in {2}", penalty.PenaltyCode, penalty.SpecificKey, penalty.JamNumber));
                    }
                    penaltyGateway.AddBasicPenalty(pen);
                }
            }
            if (!isSuccess)
            {
                throw new InvalidOperationException("Bad penalty data");
            }
        }
Example #5
0
        private void AddPenaltyServices(Dictionary<string, Player> homePlayerMap, Dictionary<string, Player> awayPlayerMap, 
                                        IList<Jam> jams, IList<JamLineupModel> lineups, IList<JamScoreModel> scores, PenaltiesModel penalties)
        {
            Dictionary<int, Dictionary<int, IList<Models.BoxTimeModel>>> homePlayerBoxTimeMap = new Dictionary<int, Dictionary<int, IList<Models.BoxTimeModel>>>();
            Dictionary<int, Dictionary<int, IList<Models.BoxTimeModel>>> awayPlayerBoxTimeMap = new Dictionary<int, Dictionary<int, IList<Models.BoxTimeModel>>>();
            Dictionary<int, int> homeEndJammerMap = new Dictionary<int, int>();
            Dictionary<int, int> awayEndJammerMap = new Dictionary<int, int>();
            foreach (JamLineupModel jamLineup in lineups)
            {
                Jam jam = jams.First(j => j.IsFirstHalf == jamLineup.IsFirstHalf && j.JamNumber == jamLineup.JamNumber);
                JamScoreModel jsm = scores.First(s => s.IsFirstHalf == jam.IsFirstHalf && s.JamNumber == jam.JamNumber);
                foreach (PlayerLineupModel playerLineup in jamLineup.HomeLineup)
                {
                    if(playerLineup == null)
                    {
                        continue;
                    }
                    int playerID = homePlayerMap[playerLineup.PlayerNumber].ID;
                    if (playerLineup.IsJammer && jsm.HomeStarPass == null)
                    {
                        homeEndJammerMap[jam.ID] = playerID;
                    }
                    else if(playerLineup.IsPivot && jsm.HomeStarPass != null)
                    {
                        homeEndJammerMap[jam.ID] = playerID;
                    }
                    if (playerLineup.BoxTimes != null && playerLineup.BoxTimes.Any())
                    {

                        if (!homePlayerBoxTimeMap.ContainsKey(playerID))
                        {
                            homePlayerBoxTimeMap[playerID] = new Dictionary<int, IList<Models.BoxTimeModel>>();
                        }
                        homePlayerBoxTimeMap[playerID][jam.ID] = playerLineup.BoxTimes;
                    }
                }
                foreach (PlayerLineupModel playerLineup in jamLineup.AwayLineup)
                {
                    if (playerLineup == null)
                    {
                        continue;
                    }
                    int playerID = awayPlayerMap[playerLineup.PlayerNumber].ID;
                    if (playerLineup.IsJammer && jsm.HomeStarPass == null)
                    {
                        awayEndJammerMap[jam.ID] = playerID;
                    }
                    else if (playerLineup.IsPivot && jsm.HomeStarPass != null)
                    {
                        awayEndJammerMap[jam.ID] = playerID;
                    }
                    if (playerLineup.BoxTimes != null && playerLineup.BoxTimes.Any())
                    {
                        if (!awayPlayerBoxTimeMap.ContainsKey(playerID))
                        {
                            awayPlayerBoxTimeMap[playerID] = new Dictionary<int, IList<Models.BoxTimeModel>>();
                        }
                        awayPlayerBoxTimeMap[playerID][jam.ID] = playerLineup.BoxTimes;
                    }
                }
            }

            Dictionary<int, PlayerPenaltiesModel> homePlayerPenalties = penalties.HomePlayerPenalties.ToDictionary(pp => homePlayerMap[pp.PlayerNumber].ID);
            Dictionary<int, PlayerPenaltiesModel> awayPlayerPenalties = penalties.AwayPlayerPenalties.ToDictionary(pp => awayPlayerMap[pp.PlayerNumber].ID);

            PenaltyProcessor processor = new PenaltyProcessor(jams, homePlayerMap, awayPlayerMap);
            var service = processor.ProcessPenalties(homePlayerBoxTimeMap, homePlayerPenalties, homeEndJammerMap, awayPlayerBoxTimeMap, awayPlayerPenalties, awayEndJammerMap);
            PenaltyGateway penaltyGateway = new PenaltyGateway(_connection, _transaction);
            penaltyGateway.AddPenalties(service);
        }
Example #6
0
        private void AddPenaltyServices(Dictionary <string, Player> homePlayerMap, Dictionary <string, Player> awayPlayerMap,
                                        IList <Jam> jams, IList <JamLineupModel> lineups, IList <JamScoreModel> scores, PenaltiesModel penalties)
        {
            Dictionary <int, Dictionary <int, IList <Models.BoxTimeModel> > > homePlayerBoxTimeMap = new Dictionary <int, Dictionary <int, IList <Models.BoxTimeModel> > >();
            Dictionary <int, Dictionary <int, IList <Models.BoxTimeModel> > > awayPlayerBoxTimeMap = new Dictionary <int, Dictionary <int, IList <Models.BoxTimeModel> > >();
            Dictionary <int, int> homeEndJammerMap = new Dictionary <int, int>();
            Dictionary <int, int> awayEndJammerMap = new Dictionary <int, int>();

            foreach (JamLineupModel jamLineup in lineups)
            {
                Jam           jam = jams.First(j => j.IsFirstHalf == jamLineup.IsFirstHalf && j.JamNumber == jamLineup.JamNumber);
                JamScoreModel jsm = scores.First(s => s.IsFirstHalf == jam.IsFirstHalf && s.JamNumber == jam.JamNumber);
                foreach (PlayerLineupModel playerLineup in jamLineup.HomeLineup)
                {
                    if (playerLineup == null)
                    {
                        continue;
                    }
                    int playerID = homePlayerMap[playerLineup.PlayerNumber].ID;
                    if (playerLineup.IsJammer && jsm.HomeStarPass == null)
                    {
                        homeEndJammerMap[jam.ID] = playerID;
                    }
                    else if (playerLineup.IsPivot && jsm.HomeStarPass != null)
                    {
                        homeEndJammerMap[jam.ID] = playerID;
                    }
                    if (playerLineup.BoxTimes != null && playerLineup.BoxTimes.Any())
                    {
                        if (!homePlayerBoxTimeMap.ContainsKey(playerID))
                        {
                            homePlayerBoxTimeMap[playerID] = new Dictionary <int, IList <Models.BoxTimeModel> >();
                        }
                        homePlayerBoxTimeMap[playerID][jam.ID] = playerLineup.BoxTimes;
                    }
                }
                foreach (PlayerLineupModel playerLineup in jamLineup.AwayLineup)
                {
                    if (playerLineup == null)
                    {
                        continue;
                    }
                    int playerID = awayPlayerMap[playerLineup.PlayerNumber].ID;
                    if (playerLineup.IsJammer && jsm.AwayStarPass == null)
                    {
                        awayEndJammerMap[jam.ID] = playerID;
                    }
                    else if (playerLineup.IsPivot && jsm.AwayStarPass != null)
                    {
                        awayEndJammerMap[jam.ID] = playerID;
                    }
                    if (playerLineup.BoxTimes != null && playerLineup.BoxTimes.Any())
                    {
                        if (!awayPlayerBoxTimeMap.ContainsKey(playerID))
                        {
                            awayPlayerBoxTimeMap[playerID] = new Dictionary <int, IList <Models.BoxTimeModel> >();
                        }
                        awayPlayerBoxTimeMap[playerID][jam.ID] = playerLineup.BoxTimes;
                    }
                }
            }

            Dictionary <int, PlayerPenaltiesModel> homePlayerPenalties = penalties.HomePlayerPenalties.ToDictionary(pp => homePlayerMap[pp.PlayerNumber].ID);
            Dictionary <int, PlayerPenaltiesModel> awayPlayerPenalties = penalties.AwayPlayerPenalties.ToDictionary(pp => awayPlayerMap[pp.PlayerNumber].ID);

            PenaltyProcessor processor    = new PenaltyProcessor(jams, homePlayerMap, awayPlayerMap);
            var            service        = processor.ProcessPenalties(homePlayerBoxTimeMap, homePlayerPenalties, homeEndJammerMap, awayPlayerBoxTimeMap, awayPlayerPenalties, awayEndJammerMap);
            PenaltyGateway penaltyGateway = new PenaltyGateway(_connection, _transaction);

            penaltyGateway.AddPenalties(service);
        }
Example #7
0
 private void AddTeamPenalties(IList<Jam> jams, Dictionary<string, Player> players, Dictionary<int, PlayerPenaltiesModel> playerPenalties)
 {
     //PenaltyProcessor processor = new PenaltyProcessor(jams, players);
     PenaltyGateway penaltyGateway = new PenaltyGateway(_connection, _transaction);
     bool isSuccess = true;
     foreach(KeyValuePair<int, PlayerPenaltiesModel> kvp in playerPenalties)
     {
         int penaltyCount = 0;
         foreach(PenaltyModel penalty in kvp.Value.Penalties)
         {
             Jam jam = jams.FirstOrDefault(j => j.IsFirstHalf == penalty.IsFirstHalf && j.JamNumber == penalty.JamNumber);
             if(jam == null)
             {
                 Console.WriteLine(string.Format("Unknown jam number {0} on penalty for player {1}.", penalty.JamNumber, kvp.Value.PlayerNumber));
                 isSuccess = false;
             }
             penaltyCount++;
             Penalty pen = new Penalty
             {
                 JamID = jam.ID,
                 PlayerID = kvp.Key,
                 PenaltyCode = penalty.PenaltyCode,
                 PenaltyNumber = penaltyCount,
                 MatchingKey = penalty.SpecificKey
             };
             if(pen.MatchingKey != null)
             {
                 Console.WriteLine(string.Format("Special case penalty {0}{1} encountered in {2}", penalty.PenaltyCode, penalty.SpecificKey, penalty.JamNumber));
             }
             penaltyGateway.AddBasicPenalty(pen);
         }
     }
     if(!isSuccess)
     {
         throw new InvalidOperationException("Bad penalty data");
     }
 }
        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());
        }
        public IList <PlayerPerformance> GetPlayerValuePerformancesForTeam(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, new DateTime(2016, 1, 1)).OrderBy(j => j.ID);
            var            jamBoutMap  = jams.ToDictionary(j => j.ID, j => j.BoutID);
            var            jpe         = new JamPlayerEffectivenessGateway(connection, transaction).GetJamPlayerEffectivenessForTeam(teamID);
            var            jamData     = new JamDataGateway(connection, transaction).GetJamDataForTeam(teamID).ToDictionary(jd => jd.JamID);
            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).GetPenaltyGroupsForTeam(teamID);
            Dictionary <int, int> boxTimeEstimates = new BoxTimeEstimateGateway(connection, transaction).GetAllBoxTimeEstimates();
            Dictionary <FoulComparison, Dictionary <int, float> > sss = new SituationalScoreGateway(connection, transaction).GetAllSituationalScores();
            Dictionary <int, double> jte        = new JamTeamEffectivenessGateway(connection, transaction).GetJamTeamEffectivenessForTeam(teamID);
            AveragePenaltyCostPerJam avgPenCost = new AveragePenaltyCostGateway(connection, transaction).GetAveragePenaltyCost();

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

            Dictionary <FoulComparison, float> medians = CalculateMedianScores(sss);
            PenaltyCostCalculator               pcCalc = new PenaltyCostCalculator(_connectionString);
            Dictionary <int, double>            groupPenaltyCostMap = pcCalc.CalculateValueCostsForTeam(jamData, pgs, boxTimeEstimates, sss, jte);
            Dictionary <int, PlayerPerformance> ppMap = new Dictionary <int, PlayerPerformance>(25);
            Dictionary <int, double>            jamTotalPortionMap = new Dictionary <int, double>(300);

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

                    // get/set BoutPerformance object
                    Bout            bout = bouts[jam.BoutID];
                    BoutPerformance bp   = null;
                    if (!curPP.Bouts.Any() ||
                        curPP.Bouts.Last().BoutDate != bout.BoutDate ||
                        curPP.Bouts.Last().HomeTeamName != teams[bout.HomeTeamID].Name ||
                        curPP.Bouts.Last().AwayTeamName != teams[bout.AwayTeamID].Name)
                    {
                        bp = new BoutPerformance
                        {
                            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           = jamData[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
                    };
                    if (jamTotalPortionMap.ContainsKey(jam.ID))
                    {
                        jamTotalPortionMap[jam.ID] += eff.IsJammer ? eff.JamPortion * 4 : eff.JamPortion;
                    }
                    else
                    {
                        jamTotalPortionMap[jam.ID] = eff.IsJammer ? eff.JamPortion * 4 : eff.JamPortion;
                    }
                    bp.Jams.Add(jp);
                }
            }

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

            foreach (PlayerPerformance pp in ppMap.Values)
            {
                pp.BlockerPerformance = new RolledUpPerformanceData();
                pp.JammerPerformance  = new RolledUpPerformanceData();
                foreach (BoutPerformance bp in pp.Bouts)
                {
                    bp.BlockerPerformance = new RolledUpPerformanceData();
                    bp.JammerPerformance  = new RolledUpPerformanceData();
                    foreach (JamPerformance jp in bp.Jams)
                    {
                        double averagePenaltyCost = jp.JammerJamPercentage > 0 ? avgPenCost.JammerValueCost : avgPenCost.BlockerValueCost;
                        double jamShare           = (jp.JammerJamPercentage * 4 + jp.BlockerJamPercentage) / jamTotalPortionMap[jp.JamID];
                        jp.DeltaPortionVersusMedian = (jp.DeltaPercentile - 0.5) * jamShare;
                        jp.PlayerValue = jp.DeltaPortionVersusMedian + jp.PenaltyCost - averagePenaltyCost;
                        var rollUp = jp.JammerJamPercentage > 0 ? bp.JammerPerformance : bp.BlockerPerformance;
                        rollUp.TotalJamPortions        += jp.JammerJamPercentage + jp.BlockerJamPercentage;
                        rollUp.TotalPenalties          += jp.JamPenalties;
                        rollUp.TotalPenaltyCost        += jp.PenaltyCost;
                        rollUp.TotalPointsVersusMedian += jp.DeltaPortionVersusMedian;
                        rollUp.TotalPlayerValue        += jp.PlayerValue;
                    }

                    pp.BlockerPerformance.TotalJamPortions        += bp.BlockerPerformance.TotalJamPortions;
                    pp.BlockerPerformance.TotalPenalties          += bp.BlockerPerformance.TotalPenalties;
                    pp.BlockerPerformance.TotalPenaltyCost        += bp.BlockerPerformance.TotalPenaltyCost;
                    pp.BlockerPerformance.TotalPointsVersusMedian += bp.BlockerPerformance.TotalPointsVersusMedian;
                    pp.BlockerPerformance.TotalPlayerValue        += bp.BlockerPerformance.TotalPlayerValue;

                    pp.JammerPerformance.TotalJamPortions        += bp.JammerPerformance.TotalJamPortions;
                    pp.JammerPerformance.TotalPenalties          += bp.JammerPerformance.TotalPenalties;
                    pp.JammerPerformance.TotalPenaltyCost        += bp.JammerPerformance.TotalPenaltyCost;
                    pp.JammerPerformance.TotalPointsVersusMedian += bp.JammerPerformance.TotalPointsVersusMedian;
                    pp.JammerPerformance.TotalPlayerValue        += bp.JammerPerformance.TotalPlayerValue;
                }
            }

            return(ppMap.Values.ToList());
        }
        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, new DateTime(2016,1,1)).OrderBy(j => j.ID);
            var jamBoutMap = jams.ToDictionary(j => j.ID, j => j.BoutID);
            var jpe = new JamPlayerEffectivenessGateway(connection, transaction).GetJamPlayerEffectivenessForTeam(teamID);
            var jamData = new JamDataGateway(connection, transaction).GetJamDataForTeam(teamID).ToDictionary(jd => jd.JamID);
            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).GetPenaltyGroupsForTeam(teamID);
            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(jamData, pgs, boxTimeEstimates, sss);
            Dictionary<int, PlayerPerformance> pps = new Dictionary<int, PlayerPerformance>(25);
            Dictionary<int, double> jamTotalPortionMap = new Dictionary<int, double>(300);

            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 = jamData[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
                    };
                    if (jamTotalPortionMap.ContainsKey(jam.ID))
                    {
                        jamTotalPortionMap[jam.ID] += eff.IsJammer ? eff.JamPortion * 4 : eff.JamPortion;
                    }
                    else
                    {
                        jamTotalPortionMap[jam.ID] = eff.IsJammer ? eff.JamPortion * 4 : 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();
        }