The Bowling Game With NBehave
May 29th, 2009Experimenting with NBehave.
Here’s an implementation of The bowling game with NBehave:
using NBehave.Spec.MbUnit;
using Context = MbUnit.Framework.TestFixtureAttribute;
using Specification = MbUnit.Framework.TestAttribute;
using Concerning = MbUnit.Framework.CategoryAttribute;
namespace TheBowlingGame
{
[Context, Concerning(”Bowling game score calculation”)]
public class BowlingGameSpec
{
Game g = null;
[Specification]
public void Should_calculate_bowling_score()
{
var story = new Story(”Bowling score calculation”);
story.AsA(”Bowler”)
.IWant(”The score of my game to be calculated”)
.SoThat(”I can know my total score”);
story.WithScenario(”Gutter game”)
.Given(”In a game of bowling”, ()=> g= new Game())
.When(”All my $rolls rolls are $pins”, 20, 0, RollMany)
.Then(”My score should be $score”, 0, (expectedScore) => g.Score().ShouldEqual(expectedScore));
story.WithScenario(”All once”)
.Given(”In a game of bowling”, ()=> g= new Game())
.When(”All my $rolls rolls are $pins”, 20, 1, RollMany)
.Then(”My score should be $score”, 20, (expectedScore) => g.Score().ShouldEqual(expectedScore));
story.WithScenario(”One spare”)
.Given(”In a game of bowling”, ()=> g= new Game())
.When(”I role one spare”,RollSpare)
.And(”The first preceding role is $pins”,3,g.Roll)
.And(”The rest of my $rolls roles are $pins”,17,0,RollMany)
.Then(”My score should be $score”, 16, (expectedScore) => g.Score().ShouldEqual(expectedScore));
story.WithScenario(”One strike”)
.Given(”In a game of bowling”, () => g = new Game())
.When(”I role one strike”, RollStrike)
.And(”The first preceding role is $pins”, 3, g.Roll)
.And(”The second preceding role is $pins”, 4, g.Roll)
.And(”The rest of my $rolls roles are $pins”, 16, 0, RollMany)
.Then(”My score should be $score”, 24, (expectedScore) => g.Score().ShouldEqual(expectedScore));
story.WithScenario(”Perfect game”)
.Given(”In a game of bowling”, () => g = new Game())
.When(”All my $rolls rolls knoks down $pins pins”, 12, 10, RollMany)
.Then(”My score should be $score”, 300, (expectedScore) => g.Score().ShouldEqual(expectedScore));
}
{
g.Roll(10);
}
private void RollSpare()
{
g.Roll(5);
g.Roll(5);
}
private void RollMany(int rolls, int pins)
{
for (int i = 0; i < rolls; i++)
{
g.Roll(pins);
}
}
}
}
{
public class Game
{
private int[] rolls = new int[21];
private int curentRoll = 0;
public void Roll(int pins)
{
rolls[curentRoll++] = pins;
}
public int Score()
{
int score = 0;
int frameIndex = 0;
for (int frame = 0; frame < 10; frame++)
{
if (IsStrike(frameIndex))
{
score += 10 + StrikeBonus(frameIndex);
frameIndex++;
}
else if (IsSpare(frameIndex))
{
score += 10 + SpareBonus(frameIndex);
frameIndex += 2;
}
else
{
score += SumOfBallsInFrame(frameIndex);
frameIndex += 2;
}
}
return score;
}
private bool IsStrike(int frameIndex)
{
return rolls[frameIndex] == 10;
}
private int SumOfBallsInFrame(int frameIndex)
{
return rolls[frameIndex] + rolls[frameIndex + 1];
}
private int SpareBonus(int frameIndex)
{
return rolls[frameIndex + 2];
}
private int StrikeBonus(int frameIndex)
{
return rolls[frameIndex + 1]
+ rolls[frameIndex + 2];
}
private bool IsSpare(int frameIndex)
{
return rolls[frameIndex] + rolls[frameIndex + 1] == 10;
}
}
}
Narrative:
As a Bowler
I want The score of my game to be calculated
So that I can know my total score
Scenario 1: Gutter game
Given In a game of bowling
When All my 20 rolls are 0
Then My score should be 0
Scenario 2: All once
Given In a game of bowling
When All my 20 rolls are 1
Then My score should be 20
Scenario 3: One spare
Given In a game of bowling
When I role one spare
And The first preceding role is 3
And The rest of my 17 roles are 0
Then My score should be 16
Scenario 4: One strike
Given In a game of bowling
When I role one strike
And The first preceding role is 3
And The second preceding role is 4
And The rest of my 16 roles are 0
Then My score should be 24
Scenario 5: Perfect game
Given In a game of bowling
When All my 12 rolls knoks down 10 pins
Then My score should be 300
