/// <summary> /// The method to calculate the score of a frame. /// </summary> /// <returns>integer Score of the frame</returns> /// <exception cref="FrameNotReadyToScoreException">FrameNotReadyToScoreException</exception> public virtual int CalculateScore() { int score = (null != PreviousFrame) ? PreviousFrame.FrameScore : 0; if (IsReadyToScore) { //In this case the score is being calculated for a full frame of balls. if (BallScores.Count == CommonFrame.BallCount) { score += BowlingNumber.Sum(BallScores[0], BallScores[1]); //If the ball made a spare then the next ball also needs to be added to the ball. if (IsSpare(BallScores)) { //find the next ball BowlingNumber nextBall = (null != NextTwoFrames && null != NextTwoFrames[0].BallScores) ? NextTwoFrames[0].BallScores[0] : null; if (null != nextBall) { score += nextBall.Value; } } } else { //In this case the frame is finished in the first frame. ///<TODO> /// Not required for this release however It could be interesting to check how this would work in a higher number of ballCount. /// </TODO> if (BallScores.Count == 1) { score += BallScores[0].Value; if (BallScores[0].IsStrike()) { //find the next two balls and add the scores. BowlingNumber nextBall = (null != NextTwoFrames && null != NextTwoFrames[0].BallScores) ? NextTwoFrames[0].BallScores[0] : null; score += null != nextBall ? nextBall.Value : 0; if ((null != NextTwoFrames && (null != NextTwoFrames[0].BallScores || null != NextTwoFrames[1].BallScores))) { BowlingNumber nextNextBall = (NextTwoFrames[0].BallScores.Count == 1) ? NextTwoFrames[1].BallScores[0] : NextTwoFrames[0].BallScores[1]; score += nextNextBall.Value; } } } } FrameScore = score; return(FrameScore); } else { throw new FrameNotReadyToScoreException("Frame is not ready to be scored. Please continue to bowl."); } }
/// <summary> /// confirms a strike. Also known as all pins are down with only one ball thrown. /// </summary> /// <returns>true for all pins down and false for any other value.</returns> public bool IsStrike() { return(BowlingNumber.Sum(this, this) / 2 == Constant.NUMBER_OF_PINS); }
/// <summary> /// Confirm if a frame is a spare. /// </summary> /// <param name="ballScores">The BowlingNumber list of scores for the frame.</param> /// <returns>True when the balls scores are a spare, otherwise false.</returns> public bool IsSpare(List <BowlingNumber> ballScores) { return(BallScores.Count == 2 && BowlingNumber.Sum(BallScores[0], BallScores[1]) == Constant.NUMBER_OF_PINS); }