public InningState Transition(PlateAppearanceOutcome outcome) { var(rbis, newBaseState, outs) = GetNewValues(outcome, BaseState, Outs); this.Score += rbis; this.BaseState = newBaseState; this.Outs = outs; return(this); }
private (int rbis, BaseState newBaseState, int outs) GetNewValues(PlateAppearanceOutcome outcome, BaseState baseState, int outs) { var rbis = 0; var newBaseState = baseState; switch (outcome) { case PlateAppearanceOutcome.Strikeout: outs++; break; case PlateAppearanceOutcome.Walk: if (baseState == BaseState.Full) { rbis++; } newBaseState = HandleWalk(baseState); break; case PlateAppearanceOutcome.Single: if (baseState.RunnerOnSecond()) { rbis++; } if (baseState.RunnerOnThird()) { rbis++; } newBaseState = HandleSingle(baseState); break; case PlateAppearanceOutcome.Double: rbis = baseState.RunnersOnBase(); newBaseState = BaseState.Second; break; case PlateAppearanceOutcome.Triple: rbis = baseState.RunnersOnBase(); newBaseState = BaseState.Third; break; case PlateAppearanceOutcome.HomeRun: rbis = baseState.RunnersOnBase() + 1; newBaseState = BaseState.Empty; break; case PlateAppearanceOutcome.FlyOut: var sf = baseState.RunnerOnThird() && outs < 2; if (sf) { rbis++; } newBaseState = HandleFlyOut(baseState); outs++; break; case PlateAppearanceOutcome.GroundOut: var first = baseState.RunnerOnFirst(); var second = baseState.RunnerOnSecond(); var third = baseState.RunnerOnThird(); var dp = (first || second) && !third; if (dp) { outs += 2; } else { outs++; } newBaseState = HandleGroundOut(baseState); break; } return(rbis, newBaseState, outs); }