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

Clean code and Code Smells
Clean code and Code SmellsClean code and Code Smells
Clean code and Code SmellsMario Sangiorgio
 
Kotlin Basics & Introduction to Jetpack Compose.pptx
Kotlin Basics & Introduction to Jetpack Compose.pptxKotlin Basics & Introduction to Jetpack Compose.pptx
Kotlin Basics & Introduction to Jetpack Compose.pptxtakshilkunadia
 
12 tips on Django Best Practices
12 tips on Django Best Practices12 tips on Django Best Practices
12 tips on Django Best PracticesDavid Arcos
 
Go Programming language, golang
Go Programming language, golangGo Programming language, golang
Go Programming language, golangBasil N G
 
Compose Camp - Jetpack Compose for Android Developers Introduction Session De...
Compose Camp - Jetpack Compose for Android Developers Introduction Session De...Compose Camp - Jetpack Compose for Android Developers Introduction Session De...
Compose Camp - Jetpack Compose for Android Developers Introduction Session De...JassGroup TICS
 
Nestjs MasterClass Slides
Nestjs MasterClass SlidesNestjs MasterClass Slides
Nestjs MasterClass SlidesNir Kaufman
 
닷넷프레임워크에서 Redis 사용하기
닷넷프레임워크에서 Redis 사용하기닷넷프레임워크에서 Redis 사용하기
닷넷프레임워크에서 Redis 사용하기흥배 최
 
Introdução a programação Orientada a Objeto
Introdução a programação Orientada a ObjetoIntrodução a programação Orientada a Objeto
Introdução a programação Orientada a ObjetoMarconi Rodrigues
 
Presentation of framework Angular
Presentation of framework AngularPresentation of framework Angular
Presentation of framework AngularLhouceine OUHAMZA
 
Introduction to Coroutines @ KotlinConf 2017
Introduction to Coroutines @ KotlinConf 2017Introduction to Coroutines @ KotlinConf 2017
Introduction to Coroutines @ KotlinConf 2017Roman Elizarov
 
Android kotlin coroutines
Android kotlin coroutinesAndroid kotlin coroutines
Android kotlin coroutinesBipin Vayalu
 
Intégration continue et déploiement continue avec Jenkins
Intégration continue et déploiement continue avec JenkinsIntégration continue et déploiement continue avec Jenkins
Intégration continue et déploiement continue avec JenkinsKokou Gaglo
 
Intégration et livraison continues des bonnes pratiques de conception d'appli...
Intégration et livraison continues des bonnes pratiques de conception d'appli...Intégration et livraison continues des bonnes pratiques de conception d'appli...
Intégration et livraison continues des bonnes pratiques de conception d'appli...Amazon Web Services
 
Formation autour de git et git lab
Formation autour de git et git labFormation autour de git et git lab
Formation autour de git et git labAbdelghani Azri
 
Git이란 (Git 소개 및 기초 이론)
Git이란 (Git 소개 및 기초 이론)Git이란 (Git 소개 및 기초 이론)
Git이란 (Git 소개 및 기초 이론)승용 윤
 
RESTful API In Node Js using Express
RESTful API In Node Js using Express RESTful API In Node Js using Express
RESTful API In Node Js using Express Jeetendra singh
 
Build RESTful API Using Express JS
Build RESTful API Using Express JSBuild RESTful API Using Express JS
Build RESTful API Using Express JSCakra Danu Sedayu
 

What's hot (20)

Clean code and Code Smells
Clean code and Code SmellsClean code and Code Smells
Clean code and Code Smells
 
Kotlin Basics & Introduction to Jetpack Compose.pptx
Kotlin Basics & Introduction to Jetpack Compose.pptxKotlin Basics & Introduction to Jetpack Compose.pptx
Kotlin Basics & Introduction to Jetpack Compose.pptx
 
12 tips on Django Best Practices
12 tips on Django Best Practices12 tips on Django Best Practices
12 tips on Django Best Practices
 
Go Programming language, golang
Go Programming language, golangGo Programming language, golang
Go Programming language, golang
 
Clean code
Clean code Clean code
Clean code
 
Compose Camp - Jetpack Compose for Android Developers Introduction Session De...
Compose Camp - Jetpack Compose for Android Developers Introduction Session De...Compose Camp - Jetpack Compose for Android Developers Introduction Session De...
Compose Camp - Jetpack Compose for Android Developers Introduction Session De...
 
Nestjs MasterClass Slides
Nestjs MasterClass SlidesNestjs MasterClass Slides
Nestjs MasterClass Slides
 
닷넷프레임워크에서 Redis 사용하기
닷넷프레임워크에서 Redis 사용하기닷넷프레임워크에서 Redis 사용하기
닷넷프레임워크에서 Redis 사용하기
 
Gradle Introduction
Gradle IntroductionGradle Introduction
Gradle Introduction
 
Introdução a programação Orientada a Objeto
Introdução a programação Orientada a ObjetoIntrodução a programação Orientada a Objeto
Introdução a programação Orientada a Objeto
 
Presentation of framework Angular
Presentation of framework AngularPresentation of framework Angular
Presentation of framework Angular
 
Introduction to Coroutines @ KotlinConf 2017
Introduction to Coroutines @ KotlinConf 2017Introduction to Coroutines @ KotlinConf 2017
Introduction to Coroutines @ KotlinConf 2017
 
Android kotlin coroutines
Android kotlin coroutinesAndroid kotlin coroutines
Android kotlin coroutines
 
Intégration continue et déploiement continue avec Jenkins
Intégration continue et déploiement continue avec JenkinsIntégration continue et déploiement continue avec Jenkins
Intégration continue et déploiement continue avec Jenkins
 
Introduction Node.js
Introduction Node.jsIntroduction Node.js
Introduction Node.js
 
Intégration et livraison continues des bonnes pratiques de conception d'appli...
Intégration et livraison continues des bonnes pratiques de conception d'appli...Intégration et livraison continues des bonnes pratiques de conception d'appli...
Intégration et livraison continues des bonnes pratiques de conception d'appli...
 
Formation autour de git et git lab
Formation autour de git et git labFormation autour de git et git lab
Formation autour de git et git lab
 
Git이란 (Git 소개 및 기초 이론)
Git이란 (Git 소개 및 기초 이론)Git이란 (Git 소개 및 기초 이론)
Git이란 (Git 소개 및 기초 이론)
 
RESTful API In Node Js using Express
RESTful API In Node Js using Express RESTful API In Node Js using Express
RESTful API In Node Js using Express
 
Build RESTful API Using Express JS
Build RESTful API Using Express JSBuild RESTful API Using Express JS
Build RESTful API Using Express JS
 

Viewers also liked

Viewers also liked (7)

Bowling Game Kata by Robert C. Martin
Bowling Game Kata by Robert C. MartinBowling Game Kata by Robert C. Martin
Bowling Game Kata by Robert C. Martin
 
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 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
 
In Java using Eclipse, Im suppose to write a class that encapsulat.pdf
In Java using Eclipse, Im suppose to write a class that encapsulat.pdfIn Java using Eclipse, Im suppose to write a class that encapsulat.pdf
In Java using Eclipse, Im suppose to write a class that encapsulat.pdfanjandavid
 

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
 
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
 
In Java using Eclipse, Im suppose to write a class that encapsulat.pdf
In Java using Eclipse, Im suppose to write a class that encapsulat.pdfIn Java using Eclipse, Im suppose to write a class that encapsulat.pdf
In Java using Eclipse, Im suppose to write a class that encapsulat.pdf
 

Recently uploaded

Unblocking The Main Thread Solving ANRs and Frozen Frames
Unblocking The Main Thread Solving ANRs and Frozen FramesUnblocking The Main Thread Solving ANRs and Frozen Frames
Unblocking The Main Thread Solving ANRs and Frozen FramesSinan KOZAK
 
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmaticsKotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmaticscarlostorres15106
 
Enhancing Worker Digital Experience: A Hands-on Workshop for Partners
Enhancing Worker Digital Experience: A Hands-on Workshop for PartnersEnhancing Worker Digital Experience: A Hands-on Workshop for Partners
Enhancing Worker Digital Experience: A Hands-on Workshop for PartnersThousandEyes
 
Presentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreterPresentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreternaman860154
 
CloudStudio User manual (basic edition):
CloudStudio User manual (basic edition):CloudStudio User manual (basic edition):
CloudStudio User manual (basic edition):comworks
 
Azure Monitor & Application Insight to monitor Infrastructure & Application
Azure Monitor & Application Insight to monitor Infrastructure & ApplicationAzure Monitor & Application Insight to monitor Infrastructure & Application
Azure Monitor & Application Insight to monitor Infrastructure & ApplicationAndikSusilo4
 
08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking Men08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking MenDelhi Call girls
 
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure serviceWhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure servicePooja Nehwal
 
Beyond Boundaries: Leveraging No-Code Solutions for Industry Innovation
Beyond Boundaries: Leveraging No-Code Solutions for Industry InnovationBeyond Boundaries: Leveraging No-Code Solutions for Industry Innovation
Beyond Boundaries: Leveraging No-Code Solutions for Industry InnovationSafe Software
 
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...shyamraj55
 
My Hashitalk Indonesia April 2024 Presentation
My Hashitalk Indonesia April 2024 PresentationMy Hashitalk Indonesia April 2024 Presentation
My Hashitalk Indonesia April 2024 PresentationRidwan Fadjar
 
Hyderabad Call Girls Khairatabad ✨ 7001305949 ✨ Cheap Price Your Budget
Hyderabad Call Girls Khairatabad ✨ 7001305949 ✨ Cheap Price Your BudgetHyderabad Call Girls Khairatabad ✨ 7001305949 ✨ Cheap Price Your Budget
Hyderabad Call Girls Khairatabad ✨ 7001305949 ✨ Cheap Price Your BudgetEnjoy Anytime
 
Making_way_through_DLL_hollowing_inspite_of_CFG_by_Debjeet Banerjee.pptx
Making_way_through_DLL_hollowing_inspite_of_CFG_by_Debjeet Banerjee.pptxMaking_way_through_DLL_hollowing_inspite_of_CFG_by_Debjeet Banerjee.pptx
Making_way_through_DLL_hollowing_inspite_of_CFG_by_Debjeet Banerjee.pptxnull - The Open Security Community
 
The Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptxThe Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptxMalak Abu Hammad
 
Artificial intelligence in the post-deep learning era
Artificial intelligence in the post-deep learning eraArtificial intelligence in the post-deep learning era
Artificial intelligence in the post-deep learning eraDeakin University
 
Transcript: #StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
Transcript: #StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024Transcript: #StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
Transcript: #StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024BookNet Canada
 
IAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI SolutionsIAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI SolutionsEnterprise Knowledge
 
Understanding the Laravel MVC Architecture
Understanding the Laravel MVC ArchitectureUnderstanding the Laravel MVC Architecture
Understanding the Laravel MVC ArchitecturePixlogix Infotech
 

Recently uploaded (20)

Unblocking The Main Thread Solving ANRs and Frozen Frames
Unblocking The Main Thread Solving ANRs and Frozen FramesUnblocking The Main Thread Solving ANRs and Frozen Frames
Unblocking The Main Thread Solving ANRs and Frozen Frames
 
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmaticsKotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
 
Enhancing Worker Digital Experience: A Hands-on Workshop for Partners
Enhancing Worker Digital Experience: A Hands-on Workshop for PartnersEnhancing Worker Digital Experience: A Hands-on Workshop for Partners
Enhancing Worker Digital Experience: A Hands-on Workshop for Partners
 
Presentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreterPresentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreter
 
CloudStudio User manual (basic edition):
CloudStudio User manual (basic edition):CloudStudio User manual (basic edition):
CloudStudio User manual (basic edition):
 
Azure Monitor & Application Insight to monitor Infrastructure & Application
Azure Monitor & Application Insight to monitor Infrastructure & ApplicationAzure Monitor & Application Insight to monitor Infrastructure & Application
Azure Monitor & Application Insight to monitor Infrastructure & Application
 
08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking Men08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking Men
 
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure serviceWhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
 
Beyond Boundaries: Leveraging No-Code Solutions for Industry Innovation
Beyond Boundaries: Leveraging No-Code Solutions for Industry InnovationBeyond Boundaries: Leveraging No-Code Solutions for Industry Innovation
Beyond Boundaries: Leveraging No-Code Solutions for Industry Innovation
 
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...
 
My Hashitalk Indonesia April 2024 Presentation
My Hashitalk Indonesia April 2024 PresentationMy Hashitalk Indonesia April 2024 Presentation
My Hashitalk Indonesia April 2024 Presentation
 
Hyderabad Call Girls Khairatabad ✨ 7001305949 ✨ Cheap Price Your Budget
Hyderabad Call Girls Khairatabad ✨ 7001305949 ✨ Cheap Price Your BudgetHyderabad Call Girls Khairatabad ✨ 7001305949 ✨ Cheap Price Your Budget
Hyderabad Call Girls Khairatabad ✨ 7001305949 ✨ Cheap Price Your Budget
 
E-Vehicle_Hacking_by_Parul Sharma_null_owasp.pptx
E-Vehicle_Hacking_by_Parul Sharma_null_owasp.pptxE-Vehicle_Hacking_by_Parul Sharma_null_owasp.pptx
E-Vehicle_Hacking_by_Parul Sharma_null_owasp.pptx
 
Making_way_through_DLL_hollowing_inspite_of_CFG_by_Debjeet Banerjee.pptx
Making_way_through_DLL_hollowing_inspite_of_CFG_by_Debjeet Banerjee.pptxMaking_way_through_DLL_hollowing_inspite_of_CFG_by_Debjeet Banerjee.pptx
Making_way_through_DLL_hollowing_inspite_of_CFG_by_Debjeet Banerjee.pptx
 
The Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptxThe Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptx
 
Artificial intelligence in the post-deep learning era
Artificial intelligence in the post-deep learning eraArtificial intelligence in the post-deep learning era
Artificial intelligence in the post-deep learning era
 
Transcript: #StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
Transcript: #StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024Transcript: #StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
Transcript: #StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
 
IAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI SolutionsIAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI Solutions
 
The transition to renewables in India.pdf
The transition to renewables in India.pdfThe transition to renewables in India.pdf
The transition to renewables in India.pdf
 
Understanding the Laravel MVC Architecture
Understanding the Laravel MVC ArchitectureUnderstanding the Laravel MVC Architecture
Understanding the Laravel MVC Architecture
 

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.