Skip to content

Instantly share code, notes, and snippets.

@PercyODI
Created March 1, 2018 05:01
Show Gist options
  • Save PercyODI/8129ade27af2aff7e95fc7c4c00258ae to your computer and use it in GitHub Desktop.
Save PercyODI/8129ade27af2aff7e95fc7c4c00258ae to your computer and use it in GitHub Desktop.
using System;
using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;
namespace BowlingScores.Tests
{
[TestClass]
public class UnitTest1
{
[TestMethod]
public void GutterGame()
{
var sut = new Game();
for (int i = 0; i < 20; i++)
{
sut.Roll(0);
}
int finalScore = sut.Score();
Assert.AreEqual(0, finalScore);
}
[TestMethod]
public void AllOnes()
{
var sut = new Game();
for (int i = 0; i < 20; i++)
{
sut.Roll(1);
}
int finalScore = sut.Score();
Assert.AreEqual(20, finalScore);
}
[TestMethod]
public void AlternatingZeroAndTen()
{
var sut = new Game();
for (int i = 0; i < 10; i++)
{
sut.Roll(0);
sut.Roll(10);
}
sut.Roll(0);
int finalScore = sut.Score();
Assert.AreEqual(100, finalScore);
}
[TestMethod]
public void AllFives()
{
var sut = new Game();
for (int i = 0; i < 10; i++)
{
sut.Roll(5);
sut.Roll(5);
}
sut.Roll(5);
int finalScore = sut.Score();
Assert.AreEqual(150, finalScore);
}
[TestMethod]
public void AllStrikes()
{
var sut = new Game();
for (int i = 0; i < 12; i++)
{
sut.Roll(10);
}
int finalScore = sut.Score();
Assert.AreEqual(300, finalScore);
}
[TestMethod]
public void AlternatingOneTwoThree()
{
var sut = new Game();
for (int i = 0; i < 20; i++)
{
sut.Roll((i % 3) + 1);
}
int finalScore = sut.Score();
Assert.AreEqual(39, finalScore);
}
[TestMethod]
public void Alternating8254()
{
var sut = new Game();
var scoreOrder = new[] {8, 2, 5, 4};
for (int i = 0; i < 20; i++)
{
sut.Roll(scoreOrder[i % 4]);
}
int finalScore = sut.Score();
Assert.AreEqual(120, finalScore);
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace BowlingScores
{
public class Game
{
private Frame FirstFrame { get; set; }
public Game()
{
FirstFrame = new Frame(1);
}
public void Roll(int num)
{
FirstFrame.Roll(num);
}
public int Score()
{
return FirstFrame.GetScore();
}
}
public class Frame
{
private int FrameNumber { get; }
private Frame NextFrame { get; set; }
protected int? FirstRoll { get; set; }
protected int? SecondRoll { get; set; }
public Frame(int frameNumber)
{
if (frameNumber > 10)
{
throw new Exception("Too Many Frames");
}
FrameNumber = frameNumber;
}
public virtual void Roll(int num)
{
if (!FirstRoll.HasValue)
{
FirstRoll = num;
return;
}
if (FirstRoll.Value < 10 && !SecondRoll.HasValue)
{
SecondRoll = num;
return;
}
if (NextFrame == null)
{
int nextFrameNumber = FrameNumber + 1;
NextFrame = nextFrameNumber < 10
? new Frame(nextFrameNumber)
: new FinalFrame(nextFrameNumber);
}
NextFrame.Roll(num);
}
public virtual int GetScore()
{
var bonus = 0;
if (FirstRoll.GetValueOrDefault(0) >= 10)
{
bonus = NextFrame.FirstRoll.GetValueOrDefault(0) +
(NextFrame.SecondRoll.HasValue
? NextFrame.SecondRoll.GetValueOrDefault(0)
: NextFrame.NextFrame.FirstRoll.GetValueOrDefault(0));
}
else if (FirstRoll.GetValueOrDefault(0) + SecondRoll.GetValueOrDefault(0) >= 10)
{
bonus = NextFrame.FirstRoll.GetValueOrDefault(0);
}
if (NextFrame != null)
return FirstRoll.GetValueOrDefault(0) +
SecondRoll.GetValueOrDefault(0) +
bonus +
NextFrame.GetScore();
else
return FirstRoll.GetValueOrDefault(0) +
SecondRoll.GetValueOrDefault(0) +
bonus;
}
}
public class FinalFrame : Frame
{
private int? ThirdRoll { get; set; }
public FinalFrame(int frameNumber) : base(frameNumber)
{
}
public override void Roll(int num)
{
if (!FirstRoll.HasValue)
{
FirstRoll = num;
return;
}
if (!SecondRoll.HasValue)
{
SecondRoll = num;
return;
}
if (!ThirdRoll.HasValue)
{
ThirdRoll = num;
return;
}
throw new Exception("Too many rolls in Final Frame!");
}
public override int GetScore()
{
return FirstRoll.GetValueOrDefault(0) +
SecondRoll.GetValueOrDefault(0) +
ThirdRoll.GetValueOrDefault(0);
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment