Example #1
0
 /// <summary>
 /// Toggles the inning.
 /// </summary>
 private void ToggleInning()
 {
     this.bases.ClearBases();
     this.currentInning = this.innings[this.currentInningIndex];
     if (this.currentInning.IsTopOfInning)
     {
         this.currentInning.IsTopOfInning = false;
         this.currentInning.TeamAtBat     = this.homeTeam;
         this.currentInning.FieldingTeam  = this.roadTeam;
         this.gameOver = this.IsGameOver();
         if (this.gameOver)
         {
             if (this.scoreboard.HomeTeamScore > this.scoreboard.RoadTeamScore)
             {
                 this.currentInning.BottomOfInningNotPlayed = true;
                 this.scoreboard.AddBottomOfInningNotPlayed();
             }
         }
     }
     else
     {
         this.currentInning.IsTopOfInning = true;
         this.currentInning.TeamAtBat     = this.roadTeam;
     }
 }
Example #2
0
        public IActionResult Index(int number = 1, bool top = true)
        {
            GameDataApi api_call = new GameDataApi();
            Inning      inning   = api_call.GetPopulatedInning(number, top);

            return(View(inning));
        }
Example #3
0
 /// <summary>
 /// Initializes a new instance of the <see cref="T:StatusQuoBaseball.Gameplay.InningActionEventArgs"/> class.
 /// </summary>
 /// <param name="inning">Inning</param>
 /// <param name="toggleInning">If set to <c>true</c> toggle inning.</param>
 /// <param name="isInningOver">bool</param>
 /// <param name="result">GamePlayResult</param>
 public InningActionEventArgs(Inning inning, bool toggleInning, bool isInningOver, GamePlayResult result)
 {
     this.inning       = inning;
     this.toggleInning = toggleInning;
     this.isInningOver = isInningOver;
     this.result       = result;
 }
Example #4
0
        private List <Pitch> GetPitchData(int inning_num, bool top, int pitcher_id, int batter_id)
        {
            Inning inning        = new Inning(inning_num, top);
            var    InningPitches = new GameDataApi().InningPitches(inning);

            return(CalcNumInAB(InningPitches, pitcher_id, batter_id));
        }
Example #5
0
        /// <summary>
        /// Initializes a new instance of the <see cref="T:StatusQuoBaseball.Gameplay.SacrificeFly"/> class.
        /// </summary>
        /// <param name="inning">Inning</param>
        /// <param name="controllingPlayer">Player</param>
        /// <param name="nonControllingPlayer">Player</param>
        /// <param name="batter">Player</param>
        public SacrificeFly(Inning inning, Player controllingPlayer, Player nonControllingPlayer, Player batter=null) : base(controllingPlayer, nonControllingPlayer, batter)
        {
            this.inning = inning;
#pragma warning disable RECS0021 // Warns about calls to virtual member functions occuring in the constructor
            outLocation = GetFieldLocation();
#pragma warning restore RECS0021 // Warns about calls to virtual member functions occuring in the constructor
            CheckForError();
        }
Example #6
0
        /// <summary>
        /// Initializes a new instance of the <see cref="T:StatusQuoBaseball.Gameplay.AtBat"/> class.
        /// </summary>
        /// <param name="batter">Batter</param>
        /// <param name="pitcher">Pitcher</param>
        /// <param name="inning">Inning</param>
        public AtBat(Player batter, Player pitcher, Inning inning)
        {
            this.batter           = batter;
            this.batter.IsBatting = true;
            this.pitcher          = pitcher;
            this.inning           = inning;

            ApplyPlayerAdjustments();
        }
Example #7
0
        public static Inning ScorePlay(string play, Inning inning)
        {
            var scoredInning = inning;

            switch (play)
            {
            case "out":
                scoredInning.AddOut();
                break;

            case "k":
                scoredInning.AddK();
                break;

            case "1b":
                scoredInning.AddHit(1);
                break;

            case "2b":
                scoredInning.AddHit(2);
                break;

            case "3b":
                scoredInning.AddHit(3);
                break;

            case "hr":
                scoredInning.AddHR();
                break;

            case "e":
                scoredInning.AddE();
                break;

            case "bb":
                scoredInning.AddBB();
                break;

            case "hbp":
                scoredInning.AddHBP();
                break;

            default:
                break;
            }

            return(scoredInning);
        }
Example #8
0
        /// <summary>
        /// Adds the inning.
        /// </summary>
        private void AddInning()
        {
            this.currentInningIndex++;
            if ((currentInningIndex + 1) <= this.maxInnings || this.isInExtraInnings)
            {
                this.innings.Add(new Inning(currentInningIndex + 1, this));
                this.currentInning               = this.innings[this.currentInningIndex];
                this.currentInning.TeamAtBat     = this.roadTeam;
                this.currentInning.FieldingTeam  = this.homeTeam;
                this.currentInning.IsTopOfInning = true;
                this.announcer.AnnounceToConsole($"We now go to the top of the {this.currentInning}.");

                this.announcer.AnnounceToConsole($"The {this.currentInning.TeamAtBat.Name} {this.currentInning.TeamAtBat.Mascot} are up to bat.");
                this.scoreboard.AddInning();
            }
            else
            {
                SignalGameOver();
            }
        }
Example #9
0
        public static void StartInning()
        {
            Inning inning = new Inning();

            Console.WriteLine("Play ball!");

            var playsString = Console.ReadLine();

            if (String.IsNullOrEmpty(playsString))
            {
                Console.WriteLine("You must enter comma separated plays");
                return;
            }

            String[] plays = playsString.Split(',');
            foreach (string play in plays)
            {
                inning = ScoreHelper.ScorePlay(play, inning);
            }

            Console.WriteLine(inning.ToString());
        }
Example #10
0
        public GameResult Run(string gameId)
        {
            IEnumerable <GameEvent> events = null;

            if (m_gameEvents == null)
            {
                Console.WriteLine($"Fetching game {gameId} from Datablase...");
                events = FetchGame(gameId).GetAwaiter().GetResult();
            }
            else
            {
                Console.WriteLine($"Fetching game {gameId} from loaded JSON...");
                events = m_gameEvents.Where(x => x.gameId == gameId).ToList();
            }

            if (events.Count() == 0)
            {
                using (StreamWriter invalid = new StreamWriter($"{m_outputFolderName}/invalid.txt", true))
                {
                    invalid.WriteLine($"{gameId}");
                }
                return(null);
            }

            // Sort the incoming events properly
            var sorted = events.OrderBy(x => x.eventIndex).OrderBy(x => x.outsBeforePlay).OrderBy(x => !x.topOfInning).OrderBy(x => x.inning);

            int homeBefore = (int)sorted.Last().homeScore;
            int awayBefore = (int)sorted.Last().awayScore;

            // UGLY but works, sorry
            Dictionary <int, Inning> innings = new Dictionary <int, Inning>();

            // Store a BEFORE summary for each event
            foreach (var e in sorted)
            {
                if (!innings.ContainsKey(e.inning))
                {
                    innings[e.inning] = new Inning();
                }
                innings[e.inning].Add(MakeSummary(e));
            }

            if (!Directory.Exists(m_outputFolderName))
            {
                Directory.CreateDirectory(m_outputFolderName);
            }

            #region JSON to diff
            // Write the before JSON
            using (FileStream s = new FileStream($"{m_outputFolderName}/{gameId}-before.json", FileMode.Create))
            {
                using (Utf8JsonWriter writer = new Utf8JsonWriter(s))
                {
                    JsonSerializer.Serialize <IEnumerable <GameEvent> >(writer, sorted, new JsonSerializerOptions()
                    {
                        PropertyNamingPolicy = new SnakeCaseNamingPolicy(), WriteIndented = true
                    });
                }
            }
            #endregion

            // ACTUALLY DO THE RESCORING
            FourthStrikeAnalyzer fsa = new FourthStrikeAnalyzer(m_singleAdvance, m_groundOutAdvance, m_flyOutAdvance);
            var analyzerResults      = fsa.RescoreGame(sorted);

            Console.WriteLine($"Game {gameId} had {analyzerResults.numNewStrikeouts} new strikeouts.");
            var newEvents = analyzerResults.newEvents;

            #region JSON to diff
            using (FileStream s = new FileStream($"{m_outputFolderName}/{gameId}-after.json", FileMode.Create))
            {
                using (Utf8JsonWriter writer = new Utf8JsonWriter(s))
                {
                    var options = new JsonSerializerOptions();
                    options.PropertyNamingPolicy = new SnakeCaseNamingPolicy();
                    options.WriteIndented        = true;

                    JsonSerializer.Serialize <IEnumerable <GameEvent> >(writer, newEvents, options);
                }
            }
            #endregion

            // Store an AFTER summary for each event
            foreach (var e in newEvents)
            {
                if (!innings.ContainsKey(e.inning))
                {
                    innings[e.inning] = new Inning();
                }
                innings[e.inning].Add(MakeSummary(e), true);
            }

            GameResult result = new GameResult(newEvents, awayBefore, homeBefore, analyzerResults.numDroppedAppearances);
            result.Stats.Merge(analyzerResults.statistics);

            m_gameResults.Add(result);

            var awayRecordAdjust = result.NewAwayRecord - result.OldAwayRecord;
            var homeRecordAdjust = result.NewHomeRecord - result.OldHomeRecord;

            if (!m_recordAdjustments.ContainsKey(result.AwayTeamId))
            {
                m_recordAdjustments[result.AwayTeamId] = new Record(0, 0, 0);
            }
            if (!m_recordAdjustments.ContainsKey(result.HomeTeamId))
            {
                m_recordAdjustments[result.HomeTeamId] = new Record(0, 0, 0);
            }

            m_recordAdjustments[result.AwayTeamId] += awayRecordAdjust;
            m_recordAdjustments[result.HomeTeamId] += homeRecordAdjust;

            #region HTML output
            StringBuilder sb = new StringBuilder();
            sb.Append("<html>");
            sb.Append("<head>");
            sb.Append("<link rel=\"stylesheet\" href=\"style.css\"/>");
            sb.Append("</head>");
            sb.Append("<body>");
            sb.Append($"<div class='gameHeader'>Rescorer Report for Game ID {gameId}</div>");
            sb.Append($"<div class='scoreReport'>Before: {result.OldAwayScore}-{result.OldHomeScore} After: {result.NewAwayScore}-{result.NewHomeScore}</div>");
            sb.Append($"<div class='scoreReport'>Extra strikeouts for Away: {result.NewAwayStrikeouts} Home: {result.NewHomeStrikeouts}</div>");
            sb.Append($"<div class='scoreReport'>Outcome: {result.Outcome}</div>");
            sb.Append($"<div class='scoreReport'>Dropped Appearances: {analyzerResults.numDroppedAppearances}</div>");
            if (result.WasOutcomeReversed)
            {
                sb.Append($"<span class='outcomeReversed'>OUTCOME REVERSED!</span>");
            }
            using (Html.Table table = new Html.Table(sb))
            {
                table.StartHead();
                using (var thead = table.AddRow(id: "tableHeader"))
                {
                    thead.AddCell("Event");
                    thead.AddCell("Outs");
                    thead.AddCell("Type");
                    thead.AddCell("Score");
                    thead.AddCell("Score");
                    thead.AddCell("Type");
                    thead.AddCell("Outs");
                    thead.AddCell("Event");
                }
                table.EndHead();
                table.StartBody();
                foreach (var inningNum in innings.Keys.OrderBy(x => x))
                {
                    // Inning Header
                    using (var tr = table.AddRow())
                    {
                        tr.AddCell($"Inning {inningNum+1}", colSpan: 8, id: "inningHeader");
                    }

                    Inning inning = innings[inningNum];
                    // Away events
                    int numLines = Math.Max(inning.awayBefore.Count, inning.awayAfter.Count);
                    for (int lineNum = 0; lineNum < numLines; lineNum++)
                    {
                        using (var tr = table.AddRow())
                        {
                            // Before cells
                            if (lineNum < inning.awayBefore.Count)
                            {
                                var summary = inning.awayBefore[lineNum];
                                tr.AddCell($"{summary.lastText}", classAttributes: "eventTextBefore");
                                tr.AddCell($"{summary.outs} out");
                                tr.AddCell($"{summary.type}", classAttributes: "typeBefore");
                                tr.AddCell($"{summary.awayScore}-{summary.homeScore}");
                            }
                            else
                            {
                                tr.AddCell("", colSpan: 4);
                            }

                            // After cells
                            if (lineNum < inning.awayAfter.Count)
                            {
                                var summary = inning.awayAfter[lineNum];
                                tr.AddCell($"{summary.awayScore}-{summary.homeScore}");
                                string typeClass = "typeAfter";
                                if (summary.outcomeChanged)
                                {
                                    typeClass += " changed";
                                }
                                tr.AddCell($"{summary.type}", classAttributes: typeClass);
                                tr.AddCell($"{summary.outs} out");
                                tr.AddCell($"{summary.lastText}", classAttributes: "eventTextAfter");
                            }
                            else
                            {
                                tr.AddCell("", colSpan: 4);
                            }
                        }
                    }

                    using (var tr = table.AddRow())
                    {
                        tr.AddCell("  ", colSpan: 8, id: "inningDivider");
                    }

                    // Away events
                    numLines = Math.Max(inning.homeBefore.Count, inning.homeAfter.Count);
                    for (int lineNum = 0; lineNum < numLines; lineNum++)
                    {
                        using (var tr = table.AddRow())
                        {
                            // Before cells
                            if (lineNum < inning.homeBefore.Count)
                            {
                                var summary = inning.homeBefore[lineNum];
                                tr.AddCell($"{summary.lastText}", classAttributes: "eventTextBefore");
                                tr.AddCell($"{summary.outs} out");
                                tr.AddCell($"{summary.type}", classAttributes: "typeBefore");
                                tr.AddCell($"{summary.awayScore}-{summary.homeScore}");
                            }
                            else
                            {
                                tr.AddCell("", colSpan: 4);
                            }

                            // After cells
                            if (lineNum < inning.homeAfter.Count)
                            {
                                var summary = inning.homeAfter[lineNum];
                                tr.AddCell($"{summary.awayScore}-{summary.homeScore}");
                                string typeClass = "typeAfter";
                                if (summary.outcomeChanged)
                                {
                                    typeClass += " changed";
                                }
                                tr.AddCell($"{summary.type}", classAttributes: typeClass);
                                tr.AddCell($"{summary.outs} out");
                                tr.AddCell($"{summary.lastText}", classAttributes: "eventTextAfter");
                            }
                            else
                            {
                                tr.AddCell("", colSpan: 4);
                            }
                        }
                    }
                }
                table.EndBody();
            }

            sb.Append("</body></html>");

            File.WriteAllText($"{m_outputFolderName}/{gameId}.html", sb.ToString());
            File.Copy("style.css", $"{m_outputFolderName}/style.css", true);

            return(result);

            #endregion
        }