public DBData( Dictionary<int, TeamStats> tst, Dictionary<int, TeamStats> tstOpp, Dictionary<int, Dictionary<string, TeamStats>> splitTeamStats, TeamRankings seasonTeamRankings, TeamRankings playoffTeamRankings, Dictionary<int, PlayerStats> pst, Dictionary<int, Dictionary<string, PlayerStats>> splitPlayerStats, PlayerRankings seasonPlayerRankings, PlayerRankings playoffPlayerRankings, List<BoxScoreEntry> bsHist, Dictionary<int, string> displayNames) { BSHist = bsHist; DisplayNames = displayNames; PST = pst; SeasonPlayerRankings = seasonPlayerRankings; PlayoffPlayerRankings = playoffPlayerRankings; PlayoffTeamRankings = playoffTeamRankings; SplitPlayerStats = splitPlayerStats; SplitTeamStats = splitTeamStats; TST = tst; TSTOpp = tstOpp; SeasonTeamRankings = seasonTeamRankings; }
public DBData() { BSHist = new List<BoxScoreEntry>(); DisplayNames = new Dictionary<int, string>(); PST = new Dictionary<int, PlayerStats>(); SeasonPlayerRankings = new PlayerRankings(); PlayoffPlayerRankings = new PlayerRankings(); PlayoffTeamRankings = new TeamRankings(); SplitPlayerStats = new Dictionary<int, Dictionary<string, PlayerStats>>(); SplitTeamStats = new Dictionary<int, Dictionary<string, TeamStats>>(); TST = new Dictionary<int, TeamStats>(); TSTOpp = new Dictionary<int, TeamStats>(); SeasonTeamRankings = new TeamRankings(); }
/// <summary>Returns a well-formatted multi-line string presenting a scouting report for the team in natural language.</summary> /// <param name="tst">The team stats dictionary.</param> /// <param name="psrList"> </param> /// <returns></returns> public string ScoutingReport( Dictionary<int, TeamStats> tst, ObservableCollection<PlayerStatsRow> psrList, TeamRankings teamRankings, bool playoffs = false) { var tempRecord = playoffs ? PlRecord : Record; var tempTotals = playoffs ? PlTotals : Totals; var tempPerGame = playoffs ? PlPerGame : PerGame; var pgList = psrList.Where(ps => ps.Position1 == Position.PG).ToList(); pgList.Sort((ps1, ps2) => ps1.GmSc.CompareTo(ps1.GmSc)); pgList.Reverse(); var sgList = psrList.Where(ps => ps.Position1 == Position.SG).ToList(); sgList.Sort((ps1, ps2) => ps1.GmSc.CompareTo(ps2.GmSc)); sgList.Reverse(); var sfList = psrList.Where(ps => ps.Position1 == Position.SF).ToList(); sfList.Sort((ps1, ps2) => ps1.GmSc.CompareTo(ps2.GmSc)); sfList.Reverse(); var pfList = psrList.Where(ps => ps.Position1 == Position.PF).ToList(); pfList.Sort((ps1, ps2) => ps1.GmSc.CompareTo(ps2.GmSc)); pfList.Reverse(); var cList = psrList.Where(ps => ps.Position1 == Position.C).ToList(); cList.Sort((ps1, ps2) => ps1.GmSc.CompareTo(ps2.GmSc)); cList.Reverse(); var roster = "Team Roster\n"; roster += "\nPG: "; pgList.ForEach(ps => roster += ps.FirstName + " " + ps.LastName + ", "); roster = roster.Remove(roster.Length - 2); roster += "\nSG: "; sgList.ForEach(ps => roster += ps.FirstName + " " + ps.LastName + ", "); roster = roster.Remove(roster.Length - 2); roster += "\nSF: "; sfList.ForEach(ps => roster += ps.FirstName + " " + ps.LastName + ", "); roster = roster.Remove(roster.Length - 2); roster += "\nPF: "; pfList.ForEach(ps => roster += ps.FirstName + " " + ps.LastName + ", "); roster = roster.Remove(roster.Length - 2); roster += "\nC: "; cList.ForEach(ps => roster += ps.FirstName + " " + ps.LastName + ", "); roster = roster.Remove(roster.Length - 2); var rating = teamRankings.RankingsPerGame; var teamCount = tst.Count; var divpos = 0; var confpos = 0; var divTeams = tst.Where(pair => pair.Value.Division == Division).ToList(); divTeams.Sort((t1, t2) => t1.Value.GetWinningPercentage(Span.Season).CompareTo(t2.Value.GetWinningPercentage(Span.Season))); divTeams.Reverse(); for (var i = 0; i < divTeams.Count; i++) { if (divTeams[i].Value.ID == ID) { divpos = i + 1; break; } } var confTeams = tst.Where(pair => pair.Value.Conference == Conference).ToList(); confTeams.Sort( (t1, t2) => t1.Value.GetWinningPercentage(Span.Season).CompareTo(t2.Value.GetWinningPercentage(Span.Season))); confTeams.Reverse(); for (var i = 0; i < confTeams.Count; i++) { if (confTeams[i].Value.ID == ID) { confpos = i + 1; break; } } var msg = roster + "\n\n===================================================\n\n"; msg += String.Format("{0}, the {1}{2}", DisplayName, rating[ID][17], Misc.GetRankingSuffix(rating[ID][17])); var topThird = teamCount / 3; var secondThird = teamCount / 3 * 2; var topHalf = teamCount / 2; msg += string.Format( " strongest team in the league right now, after having played {0} games. Their record is currently at {1}-{2}", (tempRecord[0] + tempRecord[1]), tempRecord[0], tempRecord[1]); if (!playoffs && MainWindow.Divisions.Count > 1) { msg += ", putting them at #" + divpos + " in their division and at #" + confpos + " in their conference"; } msg += ".\n\n"; if ((rating[ID][3] <= 5) && (rating[ID][5] <= 5)) { if (rating[ID][7] <= 5) { msg += "This team just can't be beaten offensively. One of the strongest in the league in all aspects."; } else { msg += "Great team offensively. Even when they don't get to the line, they know how to raise the bar with " + "efficiency in both 2 and 3 pointers."; } } else if ((rating[ID][3] <= topThird) && (rating[ID][5] <= topThird)) { if (rating[ID][7] <= topThird) { msg += "Top third of the league in everything offense, and they're one to worry about."; } else { msg += "Although their free throwing is not on par with their other offensive qualities, you can't relax " + "when playing against them. Top third of the league in field goals and 3 pointers."; } } else if ((rating[ID][3] <= secondThird) && (rating[ID][5] <= secondThird)) { if (rating[ID][7] <= topThird) { msg += "Although an average offensive team (they can't seem to remain consistent from both inside and " + "outside the arc), they can get back at you with their efficiency from the line."; } else { msg += "Average offensive team. Not really efficient in anything they do when they bring the ball down " + "the court."; } } else { if (rating[ID][7] <= topThird) { msg += "They aren't consistent from the floor, but still manage to get to the line enough times and " + "be good enough to make a difference."; } else { msg += "One of the most inconsistent teams at the offensive end, and they aren't efficient enough from " + "the line to make up for it."; } } msg += "\n\n"; if (rating[ID][3] <= 5) { msg += "Top scoring team, one of the top 5 in field goal efficiency."; } else if (rating[ID][3] <= topThird) { msg += "You'll have to worry about their scoring efficiency, as they're in the top third of the league."; } else if (rating[ID][3] <= secondThird) { msg += "Scoring is not their virtue, but they're not that bad either."; } else if (rating[ID][3] <= teamCount) { msg += "You won't have to worry about their scoring, one of the least 10 efficient in the league."; } var comp = rating[ID][TAbbrPG.FGeff] - rating[ID][TAbbrPG.FGp]; if (comp < -topHalf) { msg += "\nThey score more baskets than their FG% would have you guess, but they need to work on getting more consistent."; } else if (comp > topHalf) { msg += "\nThey can be dangerous whenever they shoot the ball. Their offense just doesn't get them enough chances to shoot it, though."; } msg += String.Format( " (#{0} in FG%: {1:F3} - #{2} in FGeff: {3:F2})", rating[ID][TAbbrPG.FGp], tempPerGame[TAbbrPG.FGp], rating[ID][TAbbrPG.FGeff], tempPerGame[TAbbrPG.FGeff]); msg += "\n"; if (rating[ID][5] <= 5) { msg += "You'll need to always have an eye on the perimeter. They can turn a game around with their 3 pointers. " + "They score well, they score a lot."; } else if (rating[ID][5] <= topThird) { msg += "Their 3pt shooting is bad news. They're in the top third of the league, and you can't relax playing against them."; } else if (rating[ID][5] <= secondThird) { msg += "Not much to say about their 3pt shooting. Average, but it is there."; } else if (rating[ID][5] <= teamCount) { msg += "Definitely not a threat from 3pt land, one of the worst in the league. They waste too many shots from there."; } comp = rating[ID][TAbbrPG.TPeff] - rating[ID][TAbbrPG.TPp]; if (comp < -topHalf) { msg += "\nThey'll get enough 3 pointers to go down each night, but not on a good enough percentage for that amount."; } else if (comp > topHalf) { msg += "\nWith their accuracy from the 3PT line, you'd think they'd shoot more of those."; } msg += String.Format( " (#{0} in 3P%: {1:F3} - #{2} in 3Peff: {3:F2})", rating[ID][TAbbrPG.TPp], tempPerGame[TAbbrPG.TPp], rating[ID][TAbbrPG.TPeff], tempPerGame[TAbbrPG.TPeff]); msg += "\n"; if (rating[ID][7] <= 5) { msg += "They tend to attack the lanes hard, getting to the line and making the most of it. They're one of the best " + "teams in the league at it."; } else if (rating[ID][7] <= topThird) { msg += "One of the best teams in the league at getting to the line. They get enough free throws to punish the opposing team every night. Top third of the league."; } else if (rating[ID][7] <= secondThird) { msg += "Average free throw efficiency, you don't have to worry about sending them to the line; at least as much as other aspects of their game."; } else if (rating[ID][7] <= teamCount) { if (rating[ID][TAbbrPG.FTp] < topHalf) { msg += "A team that you'll enjoy playing hard and aggressively against on defense. They don't know how to get to the line."; } else { msg += "A team that doesn't know how to get to the line, or how to score from there. You don't have to worry about freebies against them."; } } msg += String.Format( " (#{0} in FT%: {1:F3} - #{2} in FTeff: {3:F2})", rating[ID][TAbbrPG.FTp], tempPerGame[TAbbrPG.FTp], rating[ID][TAbbrPG.FTeff], tempPerGame[TAbbrPG.FTeff]); comp = rating[ID][TAbbrPG.FTeff] - rating[ID][TAbbrPG.FTp]; if (comp < -topHalf) { msg += "\nAlthough they get to the line a lot and make some free throws, they have to put up a lot to actually get that amount each night."; } else if (comp > topHalf) { msg += "\nThey're lethal when shooting free throws, but they need to play harder and get there more often."; } msg += "\n"; if (rating[ID][14] <= topHalf) { msg += "They know how to find the open man, and they get their offense going by getting it around the perimeter until a clean shot is there."; } else if ((rating[ID][14] > topHalf) && (rating[ID][3] < topThird)) { msg += "A team that prefers to run its offense through its core players in isolation. Not very good in assists, but they know how to get the job " + "done more times than not."; } else { msg += "A team that seems to have some selfish players around, nobody really that efficient to carry the team into high percentages."; } msg += String.Format(" (#{0} in APG: {1:F1})", rating[ID][TAbbrPG.APG], tempPerGame[TAbbrPG.APG]); msg += "\n\n"; if (rating[ID][TAbbrPG.PAPG] <= 5) { msg += "Don't expect to get your score high against them. An elite defensive team, top 5 in points against them each night."; } else if (rating[ID][TAbbrPG.PAPG] <= topThird) { msg += "One of the better defensive teams out there, limiting their opponents to low scores night in, night out."; } else if (rating[ID][TAbbrPG.PAPG] <= secondThird) { msg += "Average defensively, not much to show for it, but they're no blow-outs."; } else if (rating[ID][TAbbrPG.PAPG] <= teamCount) { msg += "This team has just forgotten what defense is. They're one of the 10 easiest teams to score against."; } msg += String.Format(" (#{0} in PAPG: {1:F1})", rating[ID][TAbbrPG.PAPG], tempPerGame[TAbbrPG.PAPG]); msg += "\n\n"; if ((rating[ID][9] <= topThird) && (rating[ID][11] <= topThird) && (rating[ID][12] <= topThird)) { msg += "Hustle is their middle name. They attack the offensive glass, they block, they steal. Don't even dare to blink or get complacent.\n\n"; } else if ((rating[ID][9] >= secondThird) && (rating[ID][11] >= secondThird) && (rating[ID][12] >= secondThird)) { msg += "This team just doesn't know what hustle means. You'll be doing circles around them if you're careful.\n\n"; } if (rating[ID][8] <= 5) { msg += "Sensational rebounding team, everybody jumps for the ball, no missed shot is left loose."; } else if (rating[ID][8] <= topThird) { msg += "You can't ignore their rebounding ability, they work together and are in the top third of the league in rebounding."; } else if (rating[ID][8] <= secondThird) { msg += "They crash the boards as much as the next guy, but they won't give up any freebies."; } else if (rating[ID][8] <= teamCount) { msg += "Second chance points? One of their biggest fears. Low low LOW rebounding numbers; just jump for the ball and you'll keep your score high."; } msg += " "; if ((rating[ID][9] <= topThird) && (rating[ID][10] <= topThird)) { msg += "The work they put on rebounding on both sides of the court is commendable. Both offensive and defensive rebounds, their bread and butter."; } msg += String.Format( " (#{0} in RPG: {1:F1}, #{2} in ORPG: {3:F1}, #{4} in DRPG: {5:F1})", rating[ID][TAbbrPG.RPG], tempPerGame[TAbbrPG.RPG], rating[ID][TAbbrPG.ORPG], tempPerGame[TAbbrPG.ORPG], rating[ID][TAbbrPG.DRPG], tempPerGame[TAbbrPG.DRPG]); msg += "\n\n"; if ((rating[ID][11] <= topThird) && (rating[ID][12] <= topThird)) { msg += "A team that knows how to play defense. They're one of the best in steals and blocks, and they make you work hard on offense."; } else if (rating[ID][11] <= topThird) { msg += "Be careful dribbling and passing. They won't be much trouble once you shoot the ball, but the trouble is getting there. Great in steals."; } else if (rating[ID][12] <= topThird) { msg += "Get that thing outta here! Great blocking team, they turn the lights off on any mismatched jumper or drive; sometimes even when you least expect it."; } else { msg += "Nothing too significant as far as blocks and steals go."; } msg += String.Format( " (#{0} in SPG: {1:F1}, #{2} in BPG: {3:F1})\n", rating[ID][TAbbrPG.SPG], tempPerGame[TAbbrPG.SPG], rating[ID][TAbbrPG.BPG], tempPerGame[TAbbrPG.BPG]); if ((rating[ID][13] > topHalf) && (rating[ID][15] > topHalf)) { msg += "Clumsy team to say the least. They're not careful with the ball, and they foul too much. Keep your eyes open and play hard."; } else if (rating[ID][13] > topHalf) { msg += "Not good ball handlers, and that's being polite. Bottom 10 in turnovers, they have work to do until they get their offense going."; } else if (rating[ID][15] > topHalf) { msg += "A team that's prone to fouling. You better drive the lanes as hard as you can, you'll get to the line a lot."; } else { msg += "This team is careful with and without the ball. They're good at keeping their turnovers down, and don't foul too much.\nDon't throw " + "your players into steals or fouls against them, because they play smart, and you're probably going to see the opposite call than the " + "one you expected."; } msg += String.Format( " (#{0} in TPG: {1:F1}, #{2} in FPG: {3:F1})", rating[ID][TAbbrPG.TPG], tempPerGame[TAbbrPG.TPG], rating[ID][TAbbrPG.FPG], tempPerGame[TAbbrPG.FPG]); msg += "\n\n"; msg += "In summary, their best areas are "; var dict = new Dictionary<int, int>(); for (var k = 0; k < rating[ID].Length; k++) { dict.Add(k, rating[ID][k]); } var strengths = (from entry in dict orderby entry.Value ascending select entry.Key).ToList(); var m = 0; var j = 5; while (true) { if (m == j) { break; } switch (strengths[m]) { case TAbbrPG.APG: msg += String.Format("assists (#{0}, {1:F1}), ", rating[ID][TAbbrPG.APG], tempPerGame[TAbbrPG.APG]); break; case TAbbrPG.BPG: msg += String.Format("blocks (#{0}, {1:F1}), ", rating[ID][TAbbrPG.BPG], tempPerGame[TAbbrPG.BPG]); break; case TAbbrPG.DRPG: msg += String.Format( "defensive rebounds (#{0}, {1:F1}), ", rating[ID][TAbbrPG.DRPG], tempPerGame[TAbbrPG.DRPG]); break; case TAbbrPG.FGeff: msg += String.Format( "field goals (#{0}, {1:F1} per game on {2:F3}), ", rating[ID][TAbbrPG.FGeff], (double) tempTotals[TAbbrT.FGM] / GetGames(), tempPerGame[TAbbrPG.FGp]); break; case TAbbrPG.FPG: msg += String.Format("fouls (#{0}, {1:F1}), ", rating[ID][TAbbrPG.FPG], tempPerGame[TAbbrPG.FPG]); break; case TAbbrPG.FTeff: msg += String.Format( "free throws (#{0}, {1:F1} per game on {2:F3}), ", rating[ID][TAbbrPG.FTeff], (double) tempTotals[TAbbrT.FTM] / GetGames(), tempPerGame[TAbbrPG.FTp]); break; case TAbbrPG.ORPG: msg += String.Format( "offensive rebounds (#{0}, {1:F1}), ", rating[ID][TAbbrPG.ORPG], tempPerGame[TAbbrPG.ORPG]); break; case TAbbrPG.PAPG: msg += String.Format( "points allowed per game (#{0}, {1:F1}), ", rating[ID][TAbbrPG.PAPG], tempPerGame[TAbbrPG.PAPG]); break; case TAbbrPG.PPG: msg += String.Format("scoring (#{0}, {1:F1}), ", rating[ID][TAbbrPG.PPG], tempPerGame[TAbbrPG.PPG]); break; case TAbbrPG.RPG: msg += String.Format("rebounds (#{0}, {1:F1}), ", rating[ID][TAbbrPG.RPG], tempPerGame[TAbbrPG.RPG]); break; case TAbbrPG.SPG: msg += String.Format("steals (#{0}, {1:F1}), ", rating[ID][TAbbrPG.SPG], tempPerGame[TAbbrPG.SPG]); break; case TAbbrPG.TPG: msg += String.Format("turnovers (#{0}, {1:F1}), ", rating[ID][TAbbrPG.TPG], tempPerGame[TAbbrPG.TPG]); break; case TAbbrPG.TPeff: msg += String.Format( "three-pointers (#{0}, {1:F1} per game on {2:F3}), ", rating[ID][TAbbrPG.TPeff], (double) tempTotals[TAbbrT.TPM] / GetGames(), tempPerGame[TAbbrPG.TPp]); break; default: j++; break; } m++; } msg = msg.TrimEnd(new[] { ' ', ',' }); msg += "."; return msg; }
private void linkInternalsToMainWindow(Task task = null) { _tst = MainWindow.TST; _tstOpp = MainWindow.TSTOpp; _pst = MainWindow.PST; _seasonRankings = MainWindow.SeasonTeamRankings; _playoffRankings = MainWindow.PlayoffTeamRankings; }
private List<string> getFacts(int id, TeamRankings rankings, bool playoffs = false) { var count = 0; var facts = new List<string>(); var topThird = MainWindow.TST.Count / 3; for (var i = 0; i < rankings.RankingsTotal[id].Length; i++) { if (i == 3) { continue; } var rank = rankings.RankingsTotal[id][i]; if (rank <= topThird) { var fact = String.Format("{0}{1} in {2}: ", rank, Misc.GetRankingSuffix(rank), TeamStatsHelper.Totals[i]); fact += String.Format("{0}", !playoffs ? _tst[id].Totals[i] : _tst[id].PlTotals[i]); facts.Add(fact); count++; } } for (var i = 0; i < rankings.RankingsPerGame[id].Length; i++) { if (double.IsNaN(!playoffs ? _tst[id].PerGame[i] : _tst[id].PlPerGame[i])) { continue; } var rank = rankings.RankingsPerGame[id][i]; if (rank <= topThird) { var fact = String.Format("{0}{1} in {2}: ", rank, Misc.GetRankingSuffix(rank), TeamStatsHelper.PerGame[i]); if (TeamStatsHelper.PerGame[i].EndsWith("%")) { fact += String.Format("{0:F3}", !playoffs ? _tst[id].PerGame[i] : _tst[id].PlPerGame[i]); } else if (TeamStatsHelper.PerGame[i].EndsWith("eff")) { fact += String.Format("{0:F2}", !playoffs ? _tst[id].PerGame[i] : _tst[id].PlPerGame[i]); } else { fact += String.Format("{0:F1}", !playoffs ? _tst[id].PerGame[i] : _tst[id].PlPerGame[i]); } facts.Add(fact); count++; } } for (var i = 0; i < rankings.RankingsMetrics[id].Keys.Count; i++) { var metricName = rankings.RankingsMetrics[id].Keys.ToList()[i]; if (double.IsNaN(!playoffs ? _tst[id].Metrics[metricName] : _tst[id].PlMetrics[metricName])) { continue; } var rank = rankings.RankingsMetrics[id][metricName]; if (rank <= topThird) { var fact = String.Format("{0}{1} in {2}: ", rank, Misc.GetRankingSuffix(rank), metricName.Replace("p", "%")); if (metricName.EndsWith("p") || metricName.EndsWith("%")) { fact += String.Format("{0:F3}", !playoffs ? _tst[id].Metrics[metricName] : _tst[id].PlMetrics[metricName]); } else if (metricName.EndsWith("eff")) { fact += String.Format("{0:F2}", !playoffs ? _tst[id].Metrics[metricName] : _tst[id].PlMetrics[metricName]); } else { fact += String.Format("{0:F1}", !playoffs ? _tst[id].Metrics[metricName] : _tst[id].PlMetrics[metricName]); } facts.Add(fact); count++; } } facts.Sort( (f1, f2) => Convert.ToInt32(f1.Substring(0, f1.IndexOfAny(new[] { 's', 'n', 'r', 't' }))) .CompareTo(Convert.ToInt32(f2.Substring(0, f2.IndexOfAny(new[] { 's', 'n', 'r', 't' }))))); return facts; }
private static void parseDBData(DBData dbData) { TST = dbData.TST; TSTOpp = dbData.TSTOpp; PST = dbData.PST; SeasonTeamRankings = dbData.SeasonTeamRankings; PlayoffTeamRankings = dbData.PlayoffTeamRankings; SplitTeamStats = dbData.SplitTeamStats; SplitPlayerStats = dbData.SplitPlayerStats; SeasonPlayerRankings = dbData.SeasonPlayerRankings; PlayoffPlayerRankings = dbData.PlayoffPlayerRankings; DisplayNames = dbData.DisplayNames; BSHist = dbData.BSHist; }
/// <summary>Calculates the difference in a team's stats rankingsPerGame between two TeamRankings instances.</summary> /// <param name="oldR">The old team rankingsPerGame.</param> /// <param name="newR">The new team rankingsPerGame.</param> /// <returns></returns> private int[][] calculateDifferenceRanking(TeamRankings oldR, TeamRankings newR) { var diff = new int[30][]; for (var i = 0; i < 30; i++) { diff[i] = new int[18]; for (var j = 0; j < 18; j++) { diff[i][j] = newR.RankingsPerGame[i][j] - oldR.RankingsPerGame[i][j]; } } return diff; }