SlideShare a Scribd company logo
1 of 49
Adapted for C# 4.0 (With Visual Studio 2010) By Dan Stewart dan@stewshack.com
Scoring Bowling. The game consists of 10 frames as shown above.  In each frame the player has two opportunities to knock down 10 pins.  The score for the frame is the total number of pins knocked down, plus bonuses for strikes and spares. A spare is when the player knocks down all 10 pins in two tries.  The bonus for that frame is the number of pins knocked down by the next roll.  So in frame 3 above, the score is 10 (the total number knocked down) plus a bonus of 5 (the number of pins knocked down on the next roll.) A strike is when the player knocks down all 10 pins on his first try.  The bonus for that frame is the value of the next two balls rolled. In the tenth frame a player who rolls a spare or strike is allowed to roll the extra balls to complete the frame.  However no more than three balls can be rolled in tenth frame.
A quick design session Clearly we need the Game class.
A quick design session A game has 10 frames.
A quick design session A frame has 1 or two rolls.
A quick design session The tenth frame has two or three rolls. It is different from all the other frames.
A quick design session The score function must include all the frames,  and calculate all their scores.
A quick design session The score for a spare or a strike depends on the frame’s successor
Begin. Create a console application named BowlingGame Add a MSTest project named BowlingGameTest to the solution
Begin. Add a unit test named GameTest to the project using Microsoft.VisualStudio.TestTools.UnitTesting; namespace BowlingGameTest { [TestClass] publicclassGameTest     { privateTestContext testContextInstance; publicTestContext TestContext         { get { return testContextInstance; } set { testContextInstance = value; }         }         [TestMethod] publicvoid TestMethod1()         {         }     } }
The first test. [TestMethod] publicvoidTestGutterGame()  {      Game g = new Game(); }
The first test. namespaceBowlingGame { publicclassGame     {     } } [TestMethod] publicvoidTestGutterGame() {      Game g = new Game(); }
The first test. [TestMethod] publicvoidTestGutterGame() {      Game g = new Game(); } publicclassGame { }
The first test. [TestMethod] publicvoidTestGutterGame() {     Gameg = newGame(); for(int i = 0; i < 20; i++)  {     g.Roll(0);  } } publicclassGame { }
The first test. public class Game {    publicvoid Roll(int p) {    thrownewSystem.NotImplementedException(); } } [TestMethod] publicvoidTestGutterGame() {     Gameg = newGame(); for(int i = 0; i < 20; i++)  {     g.Roll(0);  } }
The first test. [TestMethod] publicvoidTestGutterGame() {    Gameg = newGame(); for(int i = 0; i < 20; i++) { g.Roll(0); } Assert.AreEqual(0, g.Score()); } public class Game {    publicvoid Roll(int p) {    thrownewSystem.NotImplementedException();    } }
The first test. [TestMethod] publicvoid TestGutterGame() {    Gameg = newGame(); for(int i = 0; i < 20; i++) {    g.Roll(0); } Assert.AreEqual(0, g.Score()); } publicclassGame {    publicvoid Roll(int p)    { thrownew System.NotImplementedException();    } publicobject Score() { thrownew System.NotImplementedException();    } } Failed TestGutterGame threw exception
The first test. [TestMethod] publicvoid TestGutterGame() {     Gameg = newGame(); for(int i = 0; i < 20; i++)  {        g.Roll(0);    } Assert.AreEqual(0, g.Score); } publicclassGame { privateint score; publicvoid Roll(int pins)  {  } publicintScore()  { returnscore;  } }
The Second test. [TestMethod] publicvoid TestAllOnes() {     Gameg = newGame();     for(int i = 0; i < 20; i++)  {     g.Roll(1);  } Assert.AreEqual(20, g.Score()); } publicclassGame { privateint score; publicvoid Roll(int pins)  {  } publicintScore()  { returnscore;  } }
The Second test. - Game creation is duplicated - roll loop is duplicated [TestMethod] publicvoid TestAllOnes() {     Gameg = newGame();     for(int i = 0; i < 20; i++)  {     g.Roll(1);  } Assert.AreEqual(20, g.Score()); } publicclassGame { privateint score; publicvoid Roll(int pins)  {  } publicintScore()  { returnscore;  } }
The Second test. - Game creation is duplicated - roll loop is duplicated [TestMethod] publicvoid TestAllOnes() {     Gameg = newGame();     for(int i = 0; i < 20; i++)  {     g.Roll(1);  } Assert.AreEqual(20, g.Score()); } publicclassGame { privateint score; publicvoid Roll(int pins) { } publicintScore() { return score;    } } Assert.AreEqual failed. Expected:<20>. Actual:<0>.
The Second test. - roll loop is duplicated privateGame g; [TestInitialize] publicvoid Initialize()  {     g = newGame(); } [TestCleanup] publicvoid Cleanup() {     g = null; } [TestMethod] publicvoid TestGutterGame() { for(int i = 0; i < 20; i++)  {     g.Roll(0);  } Assert.AreEqual(0, g.Score()); } [TestMethod] publicvoid TestAllOnes() { for(int i = 0; i < 20; i++)  {     g.Roll(1);  } Assert.AreEqual(20, g.Score()); } publicclassGame { privateint score; publicvoid Roll(int pins) { score += pins; } publicint Score() { return score;     } }
The Second test. - roll loop is duplicated [TestMethod] publicvoid TestGutterGame() {    int rolls = 20; intpins = 0; for(int i = 0; i < rolls; i++) {    g.Roll(pins); } Assert.AreEqual(0, g.Score()); } publicclassGame { privateint score; publicvoid Roll(int pins) { score += pins; } publicint Score() { return score;     } }
The Second test. - roll loop is duplicated [TestMethod] publicvoid TestGutterGame() {     int rolls = 20; intpins = 0;    RollMany(rolls, pins); for(int i = 0; i < rolls; i++)   {     g.Roll(pins);  } Assert.AreEqual(0, g.Score()); } publicclassGame { privateint score; publicvoid Roll(int pins) { score += pins; } publicint Score() { return score;     } }
The Second test. publicclassGame { privateint score; publicvoid Roll(int pins) { score += pins; } publicint Score() { return score;     } } [TestMethod] publicvoid TestGutterGame() {     RollMany(20, 0); Assert.AreEqual(0, g.Score()); } privatevoid RollMany(introlls, int pins) {     for(int i = 0; i < rolls; i++)  {     g.Roll(pins);  } }
The Second test. [TestMethod] publicvoid TestGutterGame() {     RollMany(20, 0); Assert.AreEqual(0, g.Score()); }         [TestMethod] publicvoid TestAllOnes() {     RollMany(20, 1); Assert.AreEqual(20, g.Score()); } privatevoid RollMany(int rolls, int pins) {     for(int i = 0; i < rolls; i++)  {     g.Roll(pins);  } } publicclassGame { privateint score; publicvoid Roll(int pins) { score += pins; } publicint Score() { return score;     } }
The Third test. - ugly comment in test. [TestMethod] publicvoid TestOneSpare() {     g.Roll(5);  g.Roll(5); // spare  g.Roll(3);  RollMany(17, 0); Assert.AreEqual(16, g.Score()); } publicclassGame { privateint score; publicvoid Roll(int pins) { score += pins; } publicint Score() { return score;     } } Failed Assert.AreEqual Expected:<16>. Actual:<13>
The Third test. - ugly comment in test. publicclassGame { privateint score; publicvoid Roll(int pins) { score += pins; } publicint Score() { return score;     } } [TestMethod] publicvoid TestOneSpare() {     g.Roll(5);  g.Roll(5); // spare  g.Roll(3);  RollMany(17, 0); Assert.AreEqual(16, g.Score()); } tempted to use flag to remember previous roll.  So design must be wrong. Failed Assert.AreEqual Expected:<16>. Actual:<13>
The Third test. - ugly comment in test. Roll() calculates score, but name does not imply that. publicclassGame { privateint score; publicvoid Roll(int pins) { score += pins; } publicint Score() { return score;     } } [TestMethod] publicvoid TestOneSpare() {     g.Roll(5);     g.Roll(5); // spare     g.Roll(3);     RollMany(17, 0); Assert.AreEqual(16, g.Score); } Score() does not calculate score, but name implies that it does. Design is wrong.  Responsibilities are misplaced. Failed Assert.AreEqual Expected:<16>. Actual:<13>
The Third test. - ugly comment in test. [TestMethod] publicvoid TestOneSpare() {     g.Roll(5);     g.Roll(5); // spare     g.Roll(3);     RollMany(17, 0); //Assert.AreEqual(16, g.Score()); Assert.Inconclusive(); } publicclassGame { privateint score; publicvoid Roll(int pins) { score += pins; } publicint Score() { return score;     } }
The Third test. - ugly comment in test. publicclassGame { privateint score; privateint[] rolls = newint[21]; privateint currentRoll; publicvoid Roll(int pins) { rolls[currentRoll++] = pins; score += pins; } publicint Score() { return score;     } } [TestMethod] publicvoid TestOneSpare() {     g.Roll(5);     g.Roll(5); // spare     g.Roll(3);     RollMany(17, 0); //Assert.AreEqual(16, g.Score()); Assert.Inconclusive(); }
The Third test. - ugly comment in test. publicclassGame {         privateint[] rolls = newint[21]; privateint currentRoll; publicvoid Roll(int pins) { rolls[currentRoll++] = pins; } publicint Score() { int score = 0; for (int i = 0; i < rolls.Length; i++) { score += rolls[i]; } return score;     } } [TestMethod] publicvoid TestOneSpare() {     g.Roll(5);  g.Roll(5); // spare  g.Roll(3);  RollMany(17, 0); //Assert.AreEqual(16, g.Score()); Assert.Inconclusive(); }
The Third test. - ugly comment in test. [TestMethod] publicvoid TestOneSpare() {     g.Roll(5);  g.Roll(5); // spare  g.Roll(3);  RollMany(17, 0); Assert.AreEqual(16, g.Score()); } publicclassGame {         privateint[] rolls = newint[21]; privateint currentRoll; publicvoid Roll(int pins) { rolls[currentRoll++] = pins; } publicint Score() { int score = 0; for (int i = 0; i < rolls.Length; i++) { score += rolls[i]; } return score;     } } Failed Assert.AreEqual Expected:<16>. Actual:<13>
The Third test. - ugly comment in test. publicint Score() { int score = 0; for (int i = 0; i < rolls.Length; i++)     {         // spare         if(rolls[i] + rolls[i+1] == 10) { score += ... } score += rolls[i]; } return score; } [TestMethod] publicvoid TestOneSpare() {     g.Roll(5);  g.Roll(5); // spare  g.Roll(3);  RollMany(17, 0); Assert.AreEqual(16, g.Score()); } This isn’t going to work because i might not refer to the first ball of the frame. Design is still wrong. Need to walk through array two balls (one frame) at a time. Failed Assert.AreEqual Expected:<16>. Actual:<13>
The Third test. - ugly comment in test. publicclassGame {         privateint[] rolls = newint[21]; privateint currentRoll; publicvoid Roll(int pins) { rolls[currentRoll++] = pins; } publicint Score() { int score = 0; for (int i = 0; i < rolls.Length; i++) { score += rolls[i]; } return score;     } } [TestMethod] publicvoid TestOneSpare() {     g.Roll(5);  g.Roll(5); // spare  g.Roll(3);  RollMany(17, 0); //Assert.AreEqual(16, g.Score()); Assert.Inconclusive(); }
The Third test. - ugly comment in test. publicint Score() { int score = 0; int roll = 0; for (int frame = 0; frame < 10; frame++) {         score += rolls[roll] + rolls[roll + 1]; roll += 2; } returnscore; } [TestMethod] publicvoid TestOneSpare() {     g.Roll(5);  g.Roll(5); // spare  g.Roll(3);  RollMany(17, 0); //Assert.AreEqual(16, g.Score()); Assert.Inconclusive(); }
The Third test. - ugly comment in test. [TestMethod] publicvoid TestOneSpare() {     g.Roll(5);  g.Roll(5); // spare  g.Roll(3);  RollMany(17, 0); Assert.AreEqual(16, g.Score()); } publicint Score() { int score = 0; int roll = 0; for (int frame = 0; frame < 10; frame++) {         score += rolls[roll] + rolls[roll + 1]; roll += 2; } returnscore; } Failed Assert.AreEqual Expected:<16>. Actual:<13>
The Third test. - ugly comment in test. publicint Score() { int score = 0; int roll = 0; for (int frame = 0; frame < 10; frame++) { // spare if (rolls[roll] + rolls[roll + 1] == 10) { score += 10 + rolls[roll + 2]; } else {             score += rolls[roll] + rolls[roll + 1];               } roll += 2; } return score; } [TestMethod] publicvoid TestOneSpare() {     g.Roll(5);  g.Roll(5); // spare  g.Roll(3);  RollMany(17, 0); Assert.AreEqual(16, g.Score()); }
The Third test. ,[object Object]
ugly comment in conditional.publicint Score() { int score = 0; int roll = 0; for (int frame = 0; frame < 10; frame++) { // spare if (rolls[roll] + rolls[roll + 1] == 10) { score += 10 + rolls[roll + 2]; } else {             score += rolls[roll] + rolls[roll + 1];               } roll += 2; } return score; } [TestMethod] publicvoid TestOneSpare() {     g.Roll(5);  g.Roll(5); // spare  g.Roll(3);  RollMany(17, 0); Assert.AreEqual(16, g.Score()); }
The Third test. - ugly comment in test. publicint Score() { int score = 0; int roll = 0; for (int frame = 0; frame < 10; frame++) {         if(IsSpare(roll)) {     score += 10 + rolls[roll + 2]; } else {             score += rolls[roll] + rolls[roll + 1]; } roll += 2; } returnscore; } privatebool IsSpare(int roll) {     returnrolls[roll] +     rolls[roll + 1] == 10; } [TestMethod] publicvoid TestOneSpare() {     g.Roll(5);  g.Roll(5); // spare  g.Roll(3);  RollMany(17, 0); Assert.AreEqual(16, g.Score()); }
The Third test. [TestMethod] publicvoid TestOneSpare() {     RollSpare(); g.Roll(3); RollMany(17, 0); Assert.AreEqual(16, g.Score()); } privatevoid RollSpare() {     g.Roll(5); g.Roll(5); } publicint Score() { int score = 0; int roll = 0; for (int frame = 0; frame < 10; frame++) {         if(IsSpare(roll)) {     score += 10 + rolls[roll + 2]; } else {             score += rolls[roll] + rolls[roll + 1]; } roll += 2; } returnscore; } privatebool IsSpare(int roll) {     returnrolls[roll] +     rolls[roll + 1] == 10; }
The Fourth test. - ugly comment in testOneStrike. [TestMethod] publicvoid TestOneStrike() {     g.Roll(10); // strike g.Roll(3); g.Roll(4); RollMany(16, 0); Assert.AreEqual(24, g.Score()); } publicint Score() { int score = 0; int roll = 0; for (int frame = 0; frame < 10; frame++) {         if(IsSpare(roll)) {     score += 10 + rolls[roll + 2]; } else {             score += rolls[roll] + rolls[roll + 1]; } roll += 2; } returnscore; } privatebool IsSpare(int roll) {     returnrolls[roll] +     rolls[roll + 1] == 10; } Failed Assert.AreEqual Expected:<24>. Actual:<17>
The Fourth test. ,[object Object]
ugly comment in conditional.
ugly expressions.publicint Score() {     intscore = 0; introll = 0; for(int frame = 0; frame < 10; frame++) { if(rolls[roll] == 10) // strike {     score += 10 + rolls[roll + 1]     + rolls[roll + 2]; roll++; } elseif (IsSpare(roll)) {     score += 10 + rolls[roll + 2]; roll += 2; } else {     score += rolls[roll] + rolls[roll + 1]; roll += 2; }     }     returnscore; } [TestMethod] publicvoid TestOneStrike() {     g.Roll(10); // strike g.Roll(3); g.Roll(4); RollMany(16, 0); Assert.AreEqual(24, g.Score()); }
The Fourth test. ,[object Object]
ugly comment in conditional.publicint Score() {     intscore = 0; introll = 0; for(int frame = 0; frame < 10; frame++) { if(rolls[roll] == 10) // strike {     score += 10 + StrikeBonus(roll); roll++; } elseif (IsSpare(roll)) {     score += 10 + SpareBonus(roll); roll += 2; } else {            score += SumOfBallsInFrame(roll); roll += 2; } } returnscore; } privateint SumOfBallsInFrame(int roll) {     returnrolls[roll] + rolls[roll + 1]; } privateint SpareBonus(int roll) {     returnrolls[roll + 2]; } privateint StrikeBonus(int roll) {     returnrolls[roll + 1] + rolls[roll + 2]; } [TestMethod] publicvoid TestOneStrike() {     g.Roll(10); // strike g.Roll(3); g.Roll(4); RollMany(16, 0); Assert.AreEqual(24, g.Score()); }

More Related Content

What's hot

JavaScript
JavaScriptJavaScript
JavaScriptSunil OS
 
Understanding java streams
Understanding java streamsUnderstanding java streams
Understanding java streamsShahjahan Samoon
 
16. Java stacks and queues
16. Java stacks and queues16. Java stacks and queues
16. Java stacks and queuesIntro C# Book
 
Chapter 1 Basic Programming (Python Programming Lecture)
Chapter 1 Basic Programming (Python Programming Lecture)Chapter 1 Basic Programming (Python Programming Lecture)
Chapter 1 Basic Programming (Python Programming Lecture)IoT Code Lab
 
Towards Functional Programming through Hexagonal Architecture
Towards Functional Programming through Hexagonal ArchitectureTowards Functional Programming through Hexagonal Architecture
Towards Functional Programming through Hexagonal ArchitectureCodelyTV
 
Regular Expressions in Java
Regular Expressions in JavaRegular Expressions in Java
Regular Expressions in JavaOblivionWalker
 
Class and Objects in PHP
Class and Objects in PHPClass and Objects in PHP
Class and Objects in PHPRamasubbu .P
 
11. Java Objects and classes
11. Java  Objects and classes11. Java  Objects and classes
11. Java Objects and classesIntro C# Book
 
Polymorphism in Java by Animesh Sarkar
Polymorphism in Java by Animesh SarkarPolymorphism in Java by Animesh Sarkar
Polymorphism in Java by Animesh SarkarAnimesh Sarkar
 
Java Foundations: Lists, ArrayList<T>
Java Foundations: Lists, ArrayList<T>Java Foundations: Lists, ArrayList<T>
Java Foundations: Lists, ArrayList<T>Svetlin Nakov
 
Tableau objetjava
Tableau objetjavaTableau objetjava
Tableau objetjavaMoez Moezm
 

What's hot (20)

JavaScript
JavaScriptJavaScript
JavaScript
 
Gof design patterns
Gof design patternsGof design patterns
Gof design patterns
 
JUnit 4
JUnit 4JUnit 4
JUnit 4
 
Understanding java streams
Understanding java streamsUnderstanding java streams
Understanding java streams
 
16. Java stacks and queues
16. Java stacks and queues16. Java stacks and queues
16. Java stacks and queues
 
Chapter 1 Basic Programming (Python Programming Lecture)
Chapter 1 Basic Programming (Python Programming Lecture)Chapter 1 Basic Programming (Python Programming Lecture)
Chapter 1 Basic Programming (Python Programming Lecture)
 
Towards Functional Programming through Hexagonal Architecture
Towards Functional Programming through Hexagonal ArchitectureTowards Functional Programming through Hexagonal Architecture
Towards Functional Programming through Hexagonal Architecture
 
09. Java Methods
09. Java Methods09. Java Methods
09. Java Methods
 
Java Generics - by Example
Java Generics - by ExampleJava Generics - by Example
Java Generics - by Example
 
Regular Expressions in Java
Regular Expressions in JavaRegular Expressions in Java
Regular Expressions in Java
 
Database connectivity in python
Database connectivity in pythonDatabase connectivity in python
Database connectivity in python
 
Class and Objects in PHP
Class and Objects in PHPClass and Objects in PHP
Class and Objects in PHP
 
Wrapper class
Wrapper classWrapper class
Wrapper class
 
11. Java Objects and classes
11. Java  Objects and classes11. Java  Objects and classes
11. Java Objects and classes
 
Classes e Objectos JAVA
Classes e Objectos JAVAClasses e Objectos JAVA
Classes e Objectos JAVA
 
Constructor
ConstructorConstructor
Constructor
 
Polymorphism in Java by Animesh Sarkar
Polymorphism in Java by Animesh SarkarPolymorphism in Java by Animesh Sarkar
Polymorphism in Java by Animesh Sarkar
 
Java Foundations: Lists, ArrayList<T>
Java Foundations: Lists, ArrayList<T>Java Foundations: Lists, ArrayList<T>
Java Foundations: Lists, ArrayList<T>
 
Java Coleções
Java ColeçõesJava Coleções
Java Coleções
 
Tableau objetjava
Tableau objetjavaTableau objetjava
Tableau objetjava
 

Viewers also liked

Viewers also liked (6)

Test driven development
Test driven developmentTest driven development
Test driven development
 
Fast Bowling
Fast Bowling Fast Bowling
Fast Bowling
 
Bowling
BowlingBowling
Bowling
 
Bowling
BowlingBowling
Bowling
 
Test and Behaviour Driven Development (TDD/BDD)
Test and Behaviour Driven Development (TDD/BDD)Test and Behaviour Driven Development (TDD/BDD)
Test and Behaviour Driven Development (TDD/BDD)
 
Test driven development in C
Test driven development in CTest driven development in C
Test driven development in C
 

Similar to Bowling Game Kata C#

Bowling Game Kata in C# Adapted
Bowling Game Kata in C# AdaptedBowling Game Kata in C# Adapted
Bowling Game Kata in C# AdaptedMike Clement
 
Bowling Game Kata
Bowling Game KataBowling Game Kata
Bowling Game Kataguest958d7
 
Bowling game kata
Bowling game kataBowling game kata
Bowling game kataCarol Bruno
 
Bowling game kata
Bowling game kataBowling game kata
Bowling game kataJoe McCall
 
Bowling game kata
Bowling game kataBowling game kata
Bowling game kataRahman Ash
 
Test-Driven Development Fundamentals on Force.com
Test-Driven Development Fundamentals on Force.comTest-Driven Development Fundamentals on Force.com
Test-Driven Development Fundamentals on Force.comSalesforce Developers
 
I dont know what is wrong with this roulette program I cant seem.pdf
I dont know what is wrong with this roulette program I cant seem.pdfI dont know what is wrong with this roulette program I cant seem.pdf
I dont know what is wrong with this roulette program I cant seem.pdfarchanaemporium
 
You will write a multi-interface version of the well-known concentra.pdf
You will write a multi-interface version of the well-known concentra.pdfYou will write a multi-interface version of the well-known concentra.pdf
You will write a multi-interface version of the well-known concentra.pdfFashionColZone
 
Working with Layout Managers. Notes 1. In part 2, note that the Gam.pdf
Working with Layout Managers. Notes 1. In part 2, note that the Gam.pdfWorking with Layout Managers. Notes 1. In part 2, note that the Gam.pdf
Working with Layout Managers. Notes 1. In part 2, note that the Gam.pdfudit652068
 
The main class of the tictoe game looks like.public class Main {.pdf
The main class of the tictoe game looks like.public class Main {.pdfThe main class of the tictoe game looks like.public class Main {.pdf
The main class of the tictoe game looks like.public class Main {.pdfasif1401
 
Team public class Team {    private String teamId;    priva.pdf
Team public class Team {    private String teamId;    priva.pdfTeam public class Team {    private String teamId;    priva.pdf
Team public class Team {    private String teamId;    priva.pdfDEEPAKSONI562
 
The Ring programming language version 1.6 book - Part 55 of 189
The Ring programming language version 1.6 book - Part 55 of 189The Ring programming language version 1.6 book - Part 55 of 189
The Ring programming language version 1.6 book - Part 55 of 189Mahmoud Samir Fayed
 
This is Java,I am currently stumped on how to add a scoreboard for.pdf
This is Java,I am currently stumped on how to add a scoreboard for.pdfThis is Java,I am currently stumped on how to add a scoreboard for.pdf
This is Java,I am currently stumped on how to add a scoreboard for.pdfanjandavid
 
New Tools for a More Functional C++
New Tools for a More Functional C++New Tools for a More Functional C++
New Tools for a More Functional C++Sumant Tambe
 
Here are the instructions and then the code in a sec. Please R.pdf
Here are the instructions and then the code in a sec. Please R.pdfHere are the instructions and then the code in a sec. Please R.pdf
Here are the instructions and then the code in a sec. Please R.pdfaggarwalshoppe14
 
package com.tictactoe; public class Main {public void play() {.pdf
package com.tictactoe; public class Main {public void play() {.pdfpackage com.tictactoe; public class Main {public void play() {.pdf
package com.tictactoe; public class Main {public void play() {.pdfinfo430661
 
The Ring programming language version 1.3 book - Part 43 of 88
The Ring programming language version 1.3 book - Part 43 of 88The Ring programming language version 1.3 book - Part 43 of 88
The Ring programming language version 1.3 book - Part 43 of 88Mahmoud Samir Fayed
 

Similar to Bowling Game Kata C# (20)

Bowling Game Kata in C# Adapted
Bowling Game Kata in C# AdaptedBowling Game Kata in C# Adapted
Bowling Game Kata in C# Adapted
 
Bowling Game Kata
Bowling Game KataBowling Game Kata
Bowling Game Kata
 
Bowling game kata
Bowling game kataBowling game kata
Bowling game kata
 
Bowling game kata
Bowling game kataBowling game kata
Bowling game kata
 
Bowling game kata
Bowling game kataBowling game kata
Bowling game kata
 
Test-Driven Development Fundamentals on Force.com
Test-Driven Development Fundamentals on Force.comTest-Driven Development Fundamentals on Force.com
Test-Driven Development Fundamentals on Force.com
 
I dont know what is wrong with this roulette program I cant seem.pdf
I dont know what is wrong with this roulette program I cant seem.pdfI dont know what is wrong with this roulette program I cant seem.pdf
I dont know what is wrong with this roulette program I cant seem.pdf
 
You will write a multi-interface version of the well-known concentra.pdf
You will write a multi-interface version of the well-known concentra.pdfYou will write a multi-interface version of the well-known concentra.pdf
You will write a multi-interface version of the well-known concentra.pdf
 
Working with Layout Managers. Notes 1. In part 2, note that the Gam.pdf
Working with Layout Managers. Notes 1. In part 2, note that the Gam.pdfWorking with Layout Managers. Notes 1. In part 2, note that the Gam.pdf
Working with Layout Managers. Notes 1. In part 2, note that the Gam.pdf
 
The main class of the tictoe game looks like.public class Main {.pdf
The main class of the tictoe game looks like.public class Main {.pdfThe main class of the tictoe game looks like.public class Main {.pdf
The main class of the tictoe game looks like.public class Main {.pdf
 
Driver class
Driver classDriver class
Driver class
 
Team public class Team {    private String teamId;    priva.pdf
Team public class Team {    private String teamId;    priva.pdfTeam public class Team {    private String teamId;    priva.pdf
Team public class Team {    private String teamId;    priva.pdf
 
The Ring programming language version 1.6 book - Part 55 of 189
The Ring programming language version 1.6 book - Part 55 of 189The Ring programming language version 1.6 book - Part 55 of 189
The Ring programming language version 1.6 book - Part 55 of 189
 
This is Java,I am currently stumped on how to add a scoreboard for.pdf
This is Java,I am currently stumped on how to add a scoreboard for.pdfThis is Java,I am currently stumped on how to add a scoreboard for.pdf
This is Java,I am currently stumped on how to add a scoreboard for.pdf
 
New Tools for a More Functional C++
New Tools for a More Functional C++New Tools for a More Functional C++
New Tools for a More Functional C++
 
Here are the instructions and then the code in a sec. Please R.pdf
Here are the instructions and then the code in a sec. Please R.pdfHere are the instructions and then the code in a sec. Please R.pdf
Here are the instructions and then the code in a sec. Please R.pdf
 
Oop objects_classes
Oop objects_classesOop objects_classes
Oop objects_classes
 
Parameters
ParametersParameters
Parameters
 
package com.tictactoe; public class Main {public void play() {.pdf
package com.tictactoe; public class Main {public void play() {.pdfpackage com.tictactoe; public class Main {public void play() {.pdf
package com.tictactoe; public class Main {public void play() {.pdf
 
The Ring programming language version 1.3 book - Part 43 of 88
The Ring programming language version 1.3 book - Part 43 of 88The Ring programming language version 1.3 book - Part 43 of 88
The Ring programming language version 1.3 book - Part 43 of 88
 

Recently uploaded

Moving Beyond Passwords: FIDO Paris Seminar.pdf
Moving Beyond Passwords: FIDO Paris Seminar.pdfMoving Beyond Passwords: FIDO Paris Seminar.pdf
Moving Beyond Passwords: FIDO Paris Seminar.pdfLoriGlavin3
 
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024BookNet Canada
 
The Ultimate Guide to Choosing WordPress Pros and Cons
The Ultimate Guide to Choosing WordPress Pros and ConsThe Ultimate Guide to Choosing WordPress Pros and Cons
The Ultimate Guide to Choosing WordPress Pros and ConsPixlogix Infotech
 
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptx
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptxPasskey Providers and Enabling Portability: FIDO Paris Seminar.pptx
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptxLoriGlavin3
 
A Deep Dive on Passkeys: FIDO Paris Seminar.pptx
A Deep Dive on Passkeys: FIDO Paris Seminar.pptxA Deep Dive on Passkeys: FIDO Paris Seminar.pptx
A Deep Dive on Passkeys: FIDO Paris Seminar.pptxLoriGlavin3
 
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024BookNet Canada
 
How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.Curtis Poe
 
TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024Lonnie McRorey
 
Ensuring Technical Readiness For Copilot in Microsoft 365
Ensuring Technical Readiness For Copilot in Microsoft 365Ensuring Technical Readiness For Copilot in Microsoft 365
Ensuring Technical Readiness For Copilot in Microsoft 3652toLead Limited
 
Time Series Foundation Models - current state and future directions
Time Series Foundation Models - current state and future directionsTime Series Foundation Models - current state and future directions
Time Series Foundation Models - current state and future directionsNathaniel Shimoni
 
SALESFORCE EDUCATION CLOUD | FEXLE SERVICES
SALESFORCE EDUCATION CLOUD | FEXLE SERVICESSALESFORCE EDUCATION CLOUD | FEXLE SERVICES
SALESFORCE EDUCATION CLOUD | FEXLE SERVICESmohitsingh558521
 
Take control of your SAP testing with UiPath Test Suite
Take control of your SAP testing with UiPath Test SuiteTake control of your SAP testing with UiPath Test Suite
Take control of your SAP testing with UiPath Test SuiteDianaGray10
 
WordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your BrandWordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your Brandgvaughan
 
Training state-of-the-art general text embedding
Training state-of-the-art general text embeddingTraining state-of-the-art general text embedding
Training state-of-the-art general text embeddingZilliz
 
Gen AI in Business - Global Trends Report 2024.pdf
Gen AI in Business - Global Trends Report 2024.pdfGen AI in Business - Global Trends Report 2024.pdf
Gen AI in Business - Global Trends Report 2024.pdfAddepto
 
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptxUse of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptxLoriGlavin3
 
DSPy a system for AI to Write Prompts and Do Fine Tuning
DSPy a system for AI to Write Prompts and Do Fine TuningDSPy a system for AI to Write Prompts and Do Fine Tuning
DSPy a system for AI to Write Prompts and Do Fine TuningLars Bell
 
What is DBT - The Ultimate Data Build Tool.pdf
What is DBT - The Ultimate Data Build Tool.pdfWhat is DBT - The Ultimate Data Build Tool.pdf
What is DBT - The Ultimate Data Build Tool.pdfMounikaPolabathina
 
TrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data PrivacyTrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data PrivacyTrustArc
 
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024BookNet Canada
 

Recently uploaded (20)

Moving Beyond Passwords: FIDO Paris Seminar.pdf
Moving Beyond Passwords: FIDO Paris Seminar.pdfMoving Beyond Passwords: FIDO Paris Seminar.pdf
Moving Beyond Passwords: FIDO Paris Seminar.pdf
 
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
 
The Ultimate Guide to Choosing WordPress Pros and Cons
The Ultimate Guide to Choosing WordPress Pros and ConsThe Ultimate Guide to Choosing WordPress Pros and Cons
The Ultimate Guide to Choosing WordPress Pros and Cons
 
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptx
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptxPasskey Providers and Enabling Portability: FIDO Paris Seminar.pptx
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptx
 
A Deep Dive on Passkeys: FIDO Paris Seminar.pptx
A Deep Dive on Passkeys: FIDO Paris Seminar.pptxA Deep Dive on Passkeys: FIDO Paris Seminar.pptx
A Deep Dive on Passkeys: FIDO Paris Seminar.pptx
 
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
 
How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.
 
TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024
 
Ensuring Technical Readiness For Copilot in Microsoft 365
Ensuring Technical Readiness For Copilot in Microsoft 365Ensuring Technical Readiness For Copilot in Microsoft 365
Ensuring Technical Readiness For Copilot in Microsoft 365
 
Time Series Foundation Models - current state and future directions
Time Series Foundation Models - current state and future directionsTime Series Foundation Models - current state and future directions
Time Series Foundation Models - current state and future directions
 
SALESFORCE EDUCATION CLOUD | FEXLE SERVICES
SALESFORCE EDUCATION CLOUD | FEXLE SERVICESSALESFORCE EDUCATION CLOUD | FEXLE SERVICES
SALESFORCE EDUCATION CLOUD | FEXLE SERVICES
 
Take control of your SAP testing with UiPath Test Suite
Take control of your SAP testing with UiPath Test SuiteTake control of your SAP testing with UiPath Test Suite
Take control of your SAP testing with UiPath Test Suite
 
WordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your BrandWordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your Brand
 
Training state-of-the-art general text embedding
Training state-of-the-art general text embeddingTraining state-of-the-art general text embedding
Training state-of-the-art general text embedding
 
Gen AI in Business - Global Trends Report 2024.pdf
Gen AI in Business - Global Trends Report 2024.pdfGen AI in Business - Global Trends Report 2024.pdf
Gen AI in Business - Global Trends Report 2024.pdf
 
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptxUse of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
 
DSPy a system for AI to Write Prompts and Do Fine Tuning
DSPy a system for AI to Write Prompts and Do Fine TuningDSPy a system for AI to Write Prompts and Do Fine Tuning
DSPy a system for AI to Write Prompts and Do Fine Tuning
 
What is DBT - The Ultimate Data Build Tool.pdf
What is DBT - The Ultimate Data Build Tool.pdfWhat is DBT - The Ultimate Data Build Tool.pdf
What is DBT - The Ultimate Data Build Tool.pdf
 
TrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data PrivacyTrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data Privacy
 
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
 

Bowling Game Kata C#

  • 1.
  • 2. Adapted for C# 4.0 (With Visual Studio 2010) By Dan Stewart dan@stewshack.com
  • 3. Scoring Bowling. The game consists of 10 frames as shown above. In each frame the player has two opportunities to knock down 10 pins. The score for the frame is the total number of pins knocked down, plus bonuses for strikes and spares. A spare is when the player knocks down all 10 pins in two tries. The bonus for that frame is the number of pins knocked down by the next roll. So in frame 3 above, the score is 10 (the total number knocked down) plus a bonus of 5 (the number of pins knocked down on the next roll.) A strike is when the player knocks down all 10 pins on his first try. The bonus for that frame is the value of the next two balls rolled. In the tenth frame a player who rolls a spare or strike is allowed to roll the extra balls to complete the frame. However no more than three balls can be rolled in tenth frame.
  • 4. A quick design session Clearly we need the Game class.
  • 5. A quick design session A game has 10 frames.
  • 6. A quick design session A frame has 1 or two rolls.
  • 7. A quick design session The tenth frame has two or three rolls. It is different from all the other frames.
  • 8. A quick design session The score function must include all the frames, and calculate all their scores.
  • 9. A quick design session The score for a spare or a strike depends on the frame’s successor
  • 10. Begin. Create a console application named BowlingGame Add a MSTest project named BowlingGameTest to the solution
  • 11. Begin. Add a unit test named GameTest to the project using Microsoft.VisualStudio.TestTools.UnitTesting; namespace BowlingGameTest { [TestClass] publicclassGameTest { privateTestContext testContextInstance; publicTestContext TestContext { get { return testContextInstance; } set { testContextInstance = value; } } [TestMethod] publicvoid TestMethod1() { } } }
  • 12. The first test. [TestMethod] publicvoidTestGutterGame() { Game g = new Game(); }
  • 13. The first test. namespaceBowlingGame { publicclassGame { } } [TestMethod] publicvoidTestGutterGame() { Game g = new Game(); }
  • 14. The first test. [TestMethod] publicvoidTestGutterGame() { Game g = new Game(); } publicclassGame { }
  • 15. The first test. [TestMethod] publicvoidTestGutterGame() { Gameg = newGame(); for(int i = 0; i < 20; i++) { g.Roll(0); } } publicclassGame { }
  • 16. The first test. public class Game { publicvoid Roll(int p) { thrownewSystem.NotImplementedException(); } } [TestMethod] publicvoidTestGutterGame() { Gameg = newGame(); for(int i = 0; i < 20; i++) { g.Roll(0); } }
  • 17. The first test. [TestMethod] publicvoidTestGutterGame() { Gameg = newGame(); for(int i = 0; i < 20; i++) { g.Roll(0); } Assert.AreEqual(0, g.Score()); } public class Game { publicvoid Roll(int p) { thrownewSystem.NotImplementedException(); } }
  • 18. The first test. [TestMethod] publicvoid TestGutterGame() { Gameg = newGame(); for(int i = 0; i < 20; i++) { g.Roll(0); } Assert.AreEqual(0, g.Score()); } publicclassGame { publicvoid Roll(int p) { thrownew System.NotImplementedException(); } publicobject Score() { thrownew System.NotImplementedException(); } } Failed TestGutterGame threw exception
  • 19. The first test. [TestMethod] publicvoid TestGutterGame() { Gameg = newGame(); for(int i = 0; i < 20; i++) { g.Roll(0); } Assert.AreEqual(0, g.Score); } publicclassGame { privateint score; publicvoid Roll(int pins) { } publicintScore() { returnscore; } }
  • 20. The Second test. [TestMethod] publicvoid TestAllOnes() { Gameg = newGame(); for(int i = 0; i < 20; i++) { g.Roll(1); } Assert.AreEqual(20, g.Score()); } publicclassGame { privateint score; publicvoid Roll(int pins) { } publicintScore() { returnscore; } }
  • 21. The Second test. - Game creation is duplicated - roll loop is duplicated [TestMethod] publicvoid TestAllOnes() { Gameg = newGame(); for(int i = 0; i < 20; i++) { g.Roll(1); } Assert.AreEqual(20, g.Score()); } publicclassGame { privateint score; publicvoid Roll(int pins) { } publicintScore() { returnscore; } }
  • 22. The Second test. - Game creation is duplicated - roll loop is duplicated [TestMethod] publicvoid TestAllOnes() { Gameg = newGame(); for(int i = 0; i < 20; i++) { g.Roll(1); } Assert.AreEqual(20, g.Score()); } publicclassGame { privateint score; publicvoid Roll(int pins) { } publicintScore() { return score; } } Assert.AreEqual failed. Expected:<20>. Actual:<0>.
  • 23. The Second test. - roll loop is duplicated privateGame g; [TestInitialize] publicvoid Initialize() { g = newGame(); } [TestCleanup] publicvoid Cleanup() { g = null; } [TestMethod] publicvoid TestGutterGame() { for(int i = 0; i < 20; i++) { g.Roll(0); } Assert.AreEqual(0, g.Score()); } [TestMethod] publicvoid TestAllOnes() { for(int i = 0; i < 20; i++) { g.Roll(1); } Assert.AreEqual(20, g.Score()); } publicclassGame { privateint score; publicvoid Roll(int pins) { score += pins; } publicint Score() { return score; } }
  • 24. The Second test. - roll loop is duplicated [TestMethod] publicvoid TestGutterGame() { int rolls = 20; intpins = 0; for(int i = 0; i < rolls; i++) { g.Roll(pins); } Assert.AreEqual(0, g.Score()); } publicclassGame { privateint score; publicvoid Roll(int pins) { score += pins; } publicint Score() { return score; } }
  • 25. The Second test. - roll loop is duplicated [TestMethod] publicvoid TestGutterGame() { int rolls = 20; intpins = 0; RollMany(rolls, pins); for(int i = 0; i < rolls; i++) { g.Roll(pins); } Assert.AreEqual(0, g.Score()); } publicclassGame { privateint score; publicvoid Roll(int pins) { score += pins; } publicint Score() { return score; } }
  • 26. The Second test. publicclassGame { privateint score; publicvoid Roll(int pins) { score += pins; } publicint Score() { return score; } } [TestMethod] publicvoid TestGutterGame() { RollMany(20, 0); Assert.AreEqual(0, g.Score()); } privatevoid RollMany(introlls, int pins) { for(int i = 0; i < rolls; i++) { g.Roll(pins); } }
  • 27. The Second test. [TestMethod] publicvoid TestGutterGame() { RollMany(20, 0); Assert.AreEqual(0, g.Score()); } [TestMethod] publicvoid TestAllOnes() { RollMany(20, 1); Assert.AreEqual(20, g.Score()); } privatevoid RollMany(int rolls, int pins) { for(int i = 0; i < rolls; i++) { g.Roll(pins); } } publicclassGame { privateint score; publicvoid Roll(int pins) { score += pins; } publicint Score() { return score; } }
  • 28. The Third test. - ugly comment in test. [TestMethod] publicvoid TestOneSpare() { g.Roll(5); g.Roll(5); // spare g.Roll(3); RollMany(17, 0); Assert.AreEqual(16, g.Score()); } publicclassGame { privateint score; publicvoid Roll(int pins) { score += pins; } publicint Score() { return score; } } Failed Assert.AreEqual Expected:<16>. Actual:<13>
  • 29. The Third test. - ugly comment in test. publicclassGame { privateint score; publicvoid Roll(int pins) { score += pins; } publicint Score() { return score; } } [TestMethod] publicvoid TestOneSpare() { g.Roll(5); g.Roll(5); // spare g.Roll(3); RollMany(17, 0); Assert.AreEqual(16, g.Score()); } tempted to use flag to remember previous roll. So design must be wrong. Failed Assert.AreEqual Expected:<16>. Actual:<13>
  • 30. The Third test. - ugly comment in test. Roll() calculates score, but name does not imply that. publicclassGame { privateint score; publicvoid Roll(int pins) { score += pins; } publicint Score() { return score; } } [TestMethod] publicvoid TestOneSpare() { g.Roll(5); g.Roll(5); // spare g.Roll(3); RollMany(17, 0); Assert.AreEqual(16, g.Score); } Score() does not calculate score, but name implies that it does. Design is wrong. Responsibilities are misplaced. Failed Assert.AreEqual Expected:<16>. Actual:<13>
  • 31. The Third test. - ugly comment in test. [TestMethod] publicvoid TestOneSpare() { g.Roll(5); g.Roll(5); // spare g.Roll(3); RollMany(17, 0); //Assert.AreEqual(16, g.Score()); Assert.Inconclusive(); } publicclassGame { privateint score; publicvoid Roll(int pins) { score += pins; } publicint Score() { return score; } }
  • 32. The Third test. - ugly comment in test. publicclassGame { privateint score; privateint[] rolls = newint[21]; privateint currentRoll; publicvoid Roll(int pins) { rolls[currentRoll++] = pins; score += pins; } publicint Score() { return score; } } [TestMethod] publicvoid TestOneSpare() { g.Roll(5); g.Roll(5); // spare g.Roll(3); RollMany(17, 0); //Assert.AreEqual(16, g.Score()); Assert.Inconclusive(); }
  • 33. The Third test. - ugly comment in test. publicclassGame { privateint[] rolls = newint[21]; privateint currentRoll; publicvoid Roll(int pins) { rolls[currentRoll++] = pins; } publicint Score() { int score = 0; for (int i = 0; i < rolls.Length; i++) { score += rolls[i]; } return score; } } [TestMethod] publicvoid TestOneSpare() { g.Roll(5); g.Roll(5); // spare g.Roll(3); RollMany(17, 0); //Assert.AreEqual(16, g.Score()); Assert.Inconclusive(); }
  • 34. The Third test. - ugly comment in test. [TestMethod] publicvoid TestOneSpare() { g.Roll(5); g.Roll(5); // spare g.Roll(3); RollMany(17, 0); Assert.AreEqual(16, g.Score()); } publicclassGame { privateint[] rolls = newint[21]; privateint currentRoll; publicvoid Roll(int pins) { rolls[currentRoll++] = pins; } publicint Score() { int score = 0; for (int i = 0; i < rolls.Length; i++) { score += rolls[i]; } return score; } } Failed Assert.AreEqual Expected:<16>. Actual:<13>
  • 35. The Third test. - ugly comment in test. publicint Score() { int score = 0; for (int i = 0; i < rolls.Length; i++) { // spare if(rolls[i] + rolls[i+1] == 10) { score += ... } score += rolls[i]; } return score; } [TestMethod] publicvoid TestOneSpare() { g.Roll(5); g.Roll(5); // spare g.Roll(3); RollMany(17, 0); Assert.AreEqual(16, g.Score()); } This isn’t going to work because i might not refer to the first ball of the frame. Design is still wrong. Need to walk through array two balls (one frame) at a time. Failed Assert.AreEqual Expected:<16>. Actual:<13>
  • 36. The Third test. - ugly comment in test. publicclassGame { privateint[] rolls = newint[21]; privateint currentRoll; publicvoid Roll(int pins) { rolls[currentRoll++] = pins; } publicint Score() { int score = 0; for (int i = 0; i < rolls.Length; i++) { score += rolls[i]; } return score; } } [TestMethod] publicvoid TestOneSpare() { g.Roll(5); g.Roll(5); // spare g.Roll(3); RollMany(17, 0); //Assert.AreEqual(16, g.Score()); Assert.Inconclusive(); }
  • 37. The Third test. - ugly comment in test. publicint Score() { int score = 0; int roll = 0; for (int frame = 0; frame < 10; frame++) { score += rolls[roll] + rolls[roll + 1]; roll += 2; } returnscore; } [TestMethod] publicvoid TestOneSpare() { g.Roll(5); g.Roll(5); // spare g.Roll(3); RollMany(17, 0); //Assert.AreEqual(16, g.Score()); Assert.Inconclusive(); }
  • 38. The Third test. - ugly comment in test. [TestMethod] publicvoid TestOneSpare() { g.Roll(5); g.Roll(5); // spare g.Roll(3); RollMany(17, 0); Assert.AreEqual(16, g.Score()); } publicint Score() { int score = 0; int roll = 0; for (int frame = 0; frame < 10; frame++) { score += rolls[roll] + rolls[roll + 1]; roll += 2; } returnscore; } Failed Assert.AreEqual Expected:<16>. Actual:<13>
  • 39. The Third test. - ugly comment in test. publicint Score() { int score = 0; int roll = 0; for (int frame = 0; frame < 10; frame++) { // spare if (rolls[roll] + rolls[roll + 1] == 10) { score += 10 + rolls[roll + 2]; } else { score += rolls[roll] + rolls[roll + 1]; } roll += 2; } return score; } [TestMethod] publicvoid TestOneSpare() { g.Roll(5); g.Roll(5); // spare g.Roll(3); RollMany(17, 0); Assert.AreEqual(16, g.Score()); }
  • 40.
  • 41. ugly comment in conditional.publicint Score() { int score = 0; int roll = 0; for (int frame = 0; frame < 10; frame++) { // spare if (rolls[roll] + rolls[roll + 1] == 10) { score += 10 + rolls[roll + 2]; } else { score += rolls[roll] + rolls[roll + 1]; } roll += 2; } return score; } [TestMethod] publicvoid TestOneSpare() { g.Roll(5); g.Roll(5); // spare g.Roll(3); RollMany(17, 0); Assert.AreEqual(16, g.Score()); }
  • 42. The Third test. - ugly comment in test. publicint Score() { int score = 0; int roll = 0; for (int frame = 0; frame < 10; frame++) { if(IsSpare(roll)) { score += 10 + rolls[roll + 2]; } else { score += rolls[roll] + rolls[roll + 1]; } roll += 2; } returnscore; } privatebool IsSpare(int roll) { returnrolls[roll] + rolls[roll + 1] == 10; } [TestMethod] publicvoid TestOneSpare() { g.Roll(5); g.Roll(5); // spare g.Roll(3); RollMany(17, 0); Assert.AreEqual(16, g.Score()); }
  • 43. The Third test. [TestMethod] publicvoid TestOneSpare() { RollSpare(); g.Roll(3); RollMany(17, 0); Assert.AreEqual(16, g.Score()); } privatevoid RollSpare() { g.Roll(5); g.Roll(5); } publicint Score() { int score = 0; int roll = 0; for (int frame = 0; frame < 10; frame++) { if(IsSpare(roll)) { score += 10 + rolls[roll + 2]; } else { score += rolls[roll] + rolls[roll + 1]; } roll += 2; } returnscore; } privatebool IsSpare(int roll) { returnrolls[roll] + rolls[roll + 1] == 10; }
  • 44. The Fourth test. - ugly comment in testOneStrike. [TestMethod] publicvoid TestOneStrike() { g.Roll(10); // strike g.Roll(3); g.Roll(4); RollMany(16, 0); Assert.AreEqual(24, g.Score()); } publicint Score() { int score = 0; int roll = 0; for (int frame = 0; frame < 10; frame++) { if(IsSpare(roll)) { score += 10 + rolls[roll + 2]; } else { score += rolls[roll] + rolls[roll + 1]; } roll += 2; } returnscore; } privatebool IsSpare(int roll) { returnrolls[roll] + rolls[roll + 1] == 10; } Failed Assert.AreEqual Expected:<24>. Actual:<17>
  • 45.
  • 46. ugly comment in conditional.
  • 47. ugly expressions.publicint Score() { intscore = 0; introll = 0; for(int frame = 0; frame < 10; frame++) { if(rolls[roll] == 10) // strike { score += 10 + rolls[roll + 1] + rolls[roll + 2]; roll++; } elseif (IsSpare(roll)) { score += 10 + rolls[roll + 2]; roll += 2; } else { score += rolls[roll] + rolls[roll + 1]; roll += 2; } } returnscore; } [TestMethod] publicvoid TestOneStrike() { g.Roll(10); // strike g.Roll(3); g.Roll(4); RollMany(16, 0); Assert.AreEqual(24, g.Score()); }
  • 48.
  • 49. ugly comment in conditional.publicint Score() { intscore = 0; introll = 0; for(int frame = 0; frame < 10; frame++) { if(rolls[roll] == 10) // strike { score += 10 + StrikeBonus(roll); roll++; } elseif (IsSpare(roll)) { score += 10 + SpareBonus(roll); roll += 2; } else { score += SumOfBallsInFrame(roll); roll += 2; } } returnscore; } privateint SumOfBallsInFrame(int roll) { returnrolls[roll] + rolls[roll + 1]; } privateint SpareBonus(int roll) { returnrolls[roll + 2]; } privateint StrikeBonus(int roll) { returnrolls[roll + 1] + rolls[roll + 2]; } [TestMethod] publicvoid TestOneStrike() { g.Roll(10); // strike g.Roll(3); g.Roll(4); RollMany(16, 0); Assert.AreEqual(24, g.Score()); }
  • 50. The Fourth test. - ugly comment in testOneStrike. publicint Score() { int score = 0; int roll = 0; for (int frame = 0; frame < 10; frame++) { if(IsStrike(roll)) { score += 10 + StrikeBonus(roll); roll++; } elseif (IsSpare(roll)) { score += 10 + SpareBonus(roll); roll += 2; } else { score += SumOfBallsInFrame(roll); roll += 2; } } returnscore; } privatebool IsStrike(int roll) { returnrolls[roll] == 10; } [TestMethod] publicvoid TestOneStrike() { g.Roll(10); // strike g.Roll(3); g.Roll(4); RollMany(16, 0); Assert.AreEqual(24, g.Score()); }
  • 51. The Fourth test. [TestMethod] publicvoid TestOneStrike() { RollStrike(); g.Roll(3); g.Roll(4); RollMany(16, 0); Assert.AreEqual(24, g.Score()); } privatevoid RollStrike() { g.Roll(10); } publicint Score() { int score = 0; int roll = 0; for (int frame = 0; frame < 10; frame++) { if(IsStrike(roll)) { score += 10 + StrikeBonus(roll); roll++; } elseif (IsSpare(roll)) { score += 10 + SpareBonus(roll); roll += 2; } else { score += SumOfBallsInFrame(roll); roll += 2; } } returnscore; }
  • 52. The Fifth test. [TestMethod] publicvoid TestPerfectGame() { RollMany(12, 10); Assert.AreEqual(300, g.Score()); } publicint Score() { int score = 0; int roll = 0; for (int frame = 0; frame < 10; frame++) { if(IsStrike(roll)) { score += 10 + StrikeBonus(roll); roll++; } elseif (IsSpare(roll)) { score += 10 + SpareBonus(roll); roll += 2; } else { score += SumOfBallsInFrame(roll); roll += 2; } } returnscore; }

Editor's Notes

  1. First, I would like to thank Uncle Bob Martin and Object Mentor for the bowling game kata.
  2. My name is Dan Stewart. My e-mail is dan@stewshack.com. I welcome your feedback on my version of the Bowling Game.