public Dictionary <FoulComparison, Dictionary <int, float> > GetAllSituationalScores() { Dictionary <FoulComparison, Dictionary <int, float> > data = new Dictionary <FoulComparison, Dictionary <int, float> >(); using (var cmd = new SqlCommand(s_GetAllSituationalScoresQuery, _connection, _transaction)) { cmd.Parameters.Clear(); using (var reader = cmd.ExecuteReader()) { // if the team record doesn't exist, add it while (reader.Read()) { double jammerDiff = reader.GetDouble(reader.GetOrdinal("JammerBoxComparison")); double blockerDiff = reader.GetDouble(reader.GetOrdinal("BlockerBoxComparison")); int pointDelta = reader.GetInt32(reader.GetOrdinal("PointDelta")); double percentile = reader.GetDouble(reader.GetOrdinal("Percentile")); int year = reader.GetInt32(reader.GetOrdinal("Year")); FoulComparison fc = new FoulComparison { Year = year, BlockerBoxComparison = blockerDiff, JammerBoxComparison = jammerDiff }; if (!data.ContainsKey(fc)) { data[fc] = new Dictionary <int, float>(); } data[fc][pointDelta] = (float)percentile; } reader.Close(); } } return(data); }
internal static double GetEstimatedValueWithoutBoxTime(Dictionary <FoulComparison, Dictionary <int, float> > sss, JamTeamData jamData, bool isJammer) { if (!sss.ContainsKey(jamData.FoulComparison)) { throw new InvalidOperationException("This is bad data"); } // figure out the foul differential if this team did not commit fouls of this type this jam int jammerPenaltyDiff = (isJammer ? 0 : jamData.JammerBoxTime) - jamData.OppJammerBoxTime; int blockerPenaltyDiff = (isJammer ? jamData.BlockerBoxTime : 0) - jamData.OppBlockerBoxTime; double jammerBoxComp = Math.Round(jammerPenaltyDiff / 15.0, MidpointRounding.AwayFromZero) / 2.0; double blockerBoxComp = Math.Round(blockerPenaltyDiff / 15.0, MidpointRounding.AwayFromZero) / 2.0; FoulComparison foul = new FoulComparison { Year = jamData.Year, JammerBoxComparison = jammerBoxComp, BlockerBoxComparison = blockerBoxComp }; if (!sss.ContainsKey(foul)) { // lacking anything better, sum the distance of each factor from the percentile of the base JamTeamData baseJamData = new JamTeamData { Year = jamData.Year, BlockerBoxTime = 0, JammerBoxTime = 0, OppBlockerBoxTime = 0, OppJammerBoxTime = 0, PointDelta = jamData.PointDelta }; double baseDelta = GetPercentileForScore(sss[baseJamData.FoulComparison], jamData.PointDelta); // pull team 1 values baseJamData.BlockerBoxTime = isJammer ? jamData.BlockerBoxTime : 0; baseJamData.JammerBoxTime = isJammer ? 0 : jamData.JammerBoxTime; if (baseJamData.FoulComparison.Equals(foul)) { return(0); } double score1 = 0; if (!sss.ContainsKey(baseJamData.FoulComparison)) { while (baseJamData.Year > 2013) { baseJamData.Year--; if (sss.ContainsKey(baseJamData.FoulComparison)) { score1 = GetPercentileForScore(sss[baseJamData.FoulComparison], jamData.PointDelta); break; } } if (baseJamData.Year == 2013) { throw new InvalidOperationException("Bad data"); } } else { score1 = GetPercentileForScore(sss[baseJamData.FoulComparison], jamData.PointDelta); } // pull team 2 blocker baseJamData.BlockerBoxTime = 0; baseJamData.JammerBoxTime = 0; baseJamData.OppBlockerBoxTime = jamData.OppBlockerBoxTime; if (baseJamData.FoulComparison.Equals(foul)) { return(0); } double score2 = 0; if (!sss.ContainsKey(baseJamData.FoulComparison)) { while (baseJamData.Year > 2013) { baseJamData.Year--; if (sss.ContainsKey(baseJamData.FoulComparison)) { score1 = GetPercentileForScore(sss[baseJamData.FoulComparison], jamData.PointDelta); break; } } if (baseJamData.Year == 2013) { throw new InvalidOperationException("Bad data"); } } else { score2 = GetPercentileForScore(sss[baseJamData.FoulComparison], jamData.PointDelta); } // pull team 2 jammer baseJamData.OppBlockerBoxTime = 0; baseJamData.OppJammerBoxTime = jamData.OppJammerBoxTime; if (baseJamData.FoulComparison.Equals(foul)) { return(0); } double score3 = GetPercentileForScore(sss[baseJamData.FoulComparison], jamData.PointDelta); return(score1 + score2 + score3 - 2 * baseDelta); } else { return(GetPercentileForScore(sss[foul], jamData.PointDelta)); } }
private double DetermineQualityWithoutPenalty(JamTeamData jamData, bool isJammer) { // figure out the foul differential if this team did not commit fouls of this time this jam int jammerPenaltyDiff = (isJammer ? 0 : jamData.JammerBoxTime) - jamData.OppJammerBoxTime; int blockerPenaltyDiff = (isJammer ? jamData.BlockerBoxTime : 0) - jamData.OppBlockerBoxTime; double jammerBoxComp = Math.Round(jammerPenaltyDiff / 15.0, MidpointRounding.AwayFromZero) / 2.0; double blockerBoxComp = Math.Round(blockerPenaltyDiff / 15.0, MidpointRounding.AwayFromZero) / 2.0; FoulComparison foul = new FoulComparison { Year = jamData.Year, JammerBoxComparison = jammerBoxComp, BlockerBoxComparison = blockerBoxComp }; if (!_sss.ContainsKey(foul)) { // lacking anything better, sum the distance of each factor from the percentile of the base JamTeamData baseJamData = new JamTeamData { Year = jamData.Year, BlockerBoxTime = 0, JammerBoxTime = 0, OppBlockerBoxTime = 0, OppJammerBoxTime = 0, PointDelta = jamData.PointDelta }; double baseQuality = DetermineQualityWithoutPenalty(baseJamData, isJammer); // pull team 1 values baseJamData.BlockerBoxTime = isJammer ? jamData.BlockerBoxTime : 0; baseJamData.JammerBoxTime = isJammer ? 0 : jamData.JammerBoxTime; if (baseJamData.FoulComparison.Equals(foul)) { return(0.5); } double quality1 = DetermineQualityWithoutPenalty(baseJamData, isJammer) - baseQuality; // pull team 2 blocker baseJamData.BlockerBoxTime = 0; baseJamData.JammerBoxTime = 0; baseJamData.OppBlockerBoxTime = jamData.OppBlockerBoxTime; if (baseJamData.FoulComparison.Equals(foul)) { return(0.5); } double quality2 = DetermineQualityWithoutPenalty(baseJamData, isJammer) - baseQuality; // pull team 2 jammer baseJamData.OppBlockerBoxTime = 0; baseJamData.OppJammerBoxTime = jamData.OppJammerBoxTime; if (baseJamData.FoulComparison.Equals(foul)) { return(0.5); } double quality3 = DetermineQualityWithoutPenalty(baseJamData, isJammer) - baseQuality; return(baseQuality + quality1 + quality2 + quality3); } else if (!_sss[foul].ContainsKey(jamData.PointDelta)) { // extrapolate from the points we do have var bottomList = _sss[foul].Keys.Where(k => k < jamData.PointDelta); int bottom = bottomList.Any() ? bottomList.Max() : -55; double bottomPercentile = bottomList.Any() ? _sss[foul][bottom] : 0; var topList = _sss[foul].Keys.Where(k => k > jamData.PointDelta); int top = topList.Any() ? topList.Min() : 55; double topPercentile = topList.Any() ? _sss[foul][top] : 1; int distance = top - bottom; int portion = jamData.PointDelta - bottom; double ratio = ((double)portion) / distance; return(bottomPercentile + ((topPercentile - bottomPercentile) * ratio)); } else { return(_sss[foul][jamData.PointDelta]); } }