public void InsertAveragePenaltyCost(AveragePenaltyCostPerJam average) { string query = s_DeleteAveragePenaltyCostQuery + s_InsertAveragePenaltyCostQuery; using (var cmd = new SqlCommand(query, _connection, _transaction)) { cmd.Parameters.Clear(); cmd.Parameters.Add("@JammerPointCost", SqlDbType.Float).Value = average.JammerPointCost; cmd.Parameters.Add("@BlockerPointCost", SqlDbType.Float).Value = average.BlockerPointCost; cmd.Parameters.Add("@JammerValueCost", SqlDbType.Float).Value = average.JammerValueCost; cmd.Parameters.Add("@BlockerValueCost", SqlDbType.Float).Value = average.BlockerValueCost; cmd.ExecuteNonQuery(); } }
private static Dictionary<int, PlayerPerformance> GeneratePlayerPerformanceIteration(Dictionary<int, PlayerPerformance> previousIteration, IOrderedEnumerable<Jam> jams, Dictionary<int, Dictionary<int, JamTeamData>> jamData, Dictionary<int, double> jamTotalPortionMap, Dictionary<int, Dictionary<int, JamPlayerEffectiveness>> jpe, AveragePenaltyCostPerJam avgPenCost) { Dictionary<int, PlayerPerformance> pps = new Dictionary<int, PlayerPerformance>(); foreach(Jam jam in jams) { var pe = jpe[jam.ID]; var grouped = pe.Values.GroupBy(p => p.TeamID); var team1Players = grouped.First().Select(p => previousIteration[p.PlayerID]); var team2Players = grouped.Last().Select(p => previousIteration[p.PlayerID]); IEnumerable<JamPlayerEffectiveness> jammers = pe.Values.Where(eff => eff.IsJammer); double team1Score = CalculateExpectedScore(team1Players, jammers, jam.BoutID); int team1ID = grouped.First().Key; double team2Score = CalculateExpectedScore(team2Players, jammers, jam.BoutID); foreach(var eff in pe.Values) { var previousPerformance = previousIteration[eff.PlayerID]; // get/set PlayerPerformance object if (!pps.ContainsKey(eff.PlayerID)) { pps[eff.PlayerID] = new PlayerPerformance { Player = previousPerformance.Player, Bouts = new List<BoutPerformance>() }; } PlayerPerformance curPP = pps[eff.PlayerID]; // get/set BoutPerformance object var prevBout = previousPerformance.Bouts.First(b => b.BoutID == jam.BoutID); BoutPerformance bp = null; if (!curPP.Bouts.Any() || curPP.Bouts.Last().BoutID != prevBout.BoutID ) { bp = new BoutPerformance { BoutID = prevBout.BoutID, AwayTeamName = prevBout.AwayTeamName, HomeTeamName = prevBout.HomeTeamName, BoutDate = prevBout.BoutDate, Jams = new List<JamPerformance>() }; if (prevBout.BlockerPerformance != null) { bp.BlockerPerformance = new RolledUpPerformanceData { TotalJamPortions = prevBout.BlockerPerformance.TotalJamPortions, TotalPenalties = prevBout.BlockerPerformance.TotalPenalties, TotalPenaltyCost = prevBout.BlockerPerformance.TotalPenaltyCost }; } if(prevBout.JammerPerformance != null) { bp.JammerPerformance = new RolledUpPerformanceData { TotalJamPortions = prevBout.JammerPerformance.TotalJamPortions, TotalPenalties = prevBout.JammerPerformance.TotalPenalties, TotalPenaltyCost = prevBout.JammerPerformance.TotalPenaltyCost }; } curPP.Bouts.Add(bp); } else { bp = curPP.Bouts.Last(); } JamTeamData jd = jamData[jam.ID][eff.TeamID]; JamPerformance prevJamPerformance = prevBout.Jams.First(j => j.JamID == jam.ID); double pointDifferential = 0; var playerPerf = prevJamPerformance.JammerJamPercentage > 0 ? previousPerformance.JammerPerformance : previousPerformance.BlockerPerformance; double playerScore = playerPerf.TotalPointsVersusMedian / playerPerf.TotalJamPortions; if(curPP.Player.TeamID == team1ID) { pointDifferential = jd.PointDelta - team1Score + team2Score + playerScore; } else { pointDifferential = jd.PointDelta - team2Score + team1Score + playerScore; } JamPerformance jp = new JamPerformance { BlockerJamPercentage = prevJamPerformance.BlockerJamPercentage, DeltaPercentile = prevJamPerformance.DeltaPercentile, IsFirstHalf = prevJamPerformance.IsFirstHalf, JamID = prevJamPerformance.JamID, JammerJamPercentage = prevJamPerformance.JammerJamPercentage, JamNumber = prevJamPerformance.JamNumber, JamPenalties = prevJamPerformance.JamPenalties, MedianDelta = prevJamPerformance.MedianDelta, PenaltyCost = prevJamPerformance.PenaltyCost, PointDelta = jd.PointDelta, DeltaPortionVersusMedian = pointDifferential //PlayerValue }; bp.Jams.Add(jp); } } Parallel.ForEach(pps.Values, pp => { RollUpIteratedPlayerPerformance(avgPenCost, jamTotalPortionMap, pp); }); return pps; }
private static void RollUpPlayerPerformance(AveragePenaltyCostPerJam avgPenCost, Dictionary<int, double> jamTotalPortionMap, PlayerPerformance pp) { 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.JammerPointCost : avgPenCost.BlockerPointCost; double jamShare = (jp.JammerJamPercentage * 4 + jp.BlockerJamPercentage) / jamTotalPortionMap[jp.JamID]; jp.DeltaPortionVersusMedian = (jp.PointDelta - jp.MedianDelta) * 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; } }
private static Dictionary<int, PlayerPerformance> GenerateInitialPlayerPerformance(Dictionary<int, Dictionary<int, Player>> players, IOrderedEnumerable<Jam> jams, Dictionary<int, Dictionary<int, JamPlayerEffectiveness>> jpe, Dictionary<int, Dictionary<int, JamTeamData>> jamData, Dictionary<int, Team> teams, Dictionary<int, Bout> bouts, Dictionary<int, Dictionary<int, List<Penalty>>> penalties, IList<PenaltyGroup> pgs, AveragePenaltyCostPerJam avgPenCost, Dictionary<FoulComparison, float> medians, Dictionary<int, double> groupPenaltyCostMap, Dictionary<int, double> jamTotalPortionMap) { Dictionary<int, PlayerPerformance> pps = new Dictionary<int, PlayerPerformance>(); foreach (Jam jam in jams) { var pe = jpe[jam.ID]; foreach(var eff in pe.Values) { // get/set PlayerPerformance object if (!pps.ContainsKey(eff.PlayerID)) { pps[eff.PlayerID] = new PlayerPerformance { Player = players[eff.PlayerID][eff.TeamID], 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().BoutDate != bout.BoutDate || curPP.Bouts.Last().HomeTeamName != teams[bout.HomeTeamID].Name || curPP.Bouts.Last().AwayTeamName != teams[bout.AwayTeamID].Name) { 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][eff.TeamID]; 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 = pps[p.PlayerID].Bouts.SelectMany(b => b.Jams).Where(j => j.JamID == p.JamID).First(); jp.PenaltyCost += groupPenaltyCostMap[pg.GroupID]; } } Parallel.ForEach(pps.Values, pp => { RollUpPlayerPerformance(avgPenCost, jamTotalPortionMap, pp); }); return pps; }