SlideShare uma empresa Scribd logo
1 de 49
Bowling Game KataAdapted for C# and nUnit By Dan Stewart (with modifications by Mike Clement) dan@stewshack.com mike@softwareontheside.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 class library named BowlingGameKata
Begin. Add a test fixture named BowlingGameTests to the project usingNUnit.Framework; namespaceBowlingGameKata { [TestFixture] publicclassBowlingGameTests {         [Test] publicvoidGutterGameTest()         {         }     } }
The first test. [Test] publicvoidGutterGameTest()  {      Game g = new Game(); }
The first test. namespaceBowlingGameKata { publicclassGame     {     } } [Test] publicvoidGutterGameTest() {      Game g = new Game(); }
The first test. [Test] publicvoidGutterGameTest() {      Game g = new Game(); } publicclassGame { }
The first test. [Test] publicvoidGutterGameTest() {     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(); } } [Test] publicvoidGutterGameTest() {     Gameg = newGame(); for(int i = 0; i < 20; i++)  { g.Roll(0);  } }
The first test. [Test] publicvoidGutterGameTest() {    Gameg = newGame(); for(int i = 0; i < 20; i++) { g.Roll(0); } Assert.That(g.Score(), Is.EqualTo(0)); } public class Game {    publicvoid Roll(int p) {    thrownewSystem.NotImplementedException();    } }
The first test. [Test] publicvoidGutterGameTest() {    Gameg = newGame(); for(int i = 0; i < 20; i++) { g.Roll(0); } Assert.That(g.Score(), Is.EqualTo(0)); } publicclassGame {    publicvoid Roll(int p)    { thrownew System.NotImplementedException();    } publicobject Score() { thrownew System.NotImplementedException();    } } Failed GutterGameTestthrew exception
The first test. [Test] publicvoidGutterGameTest() {     Gameg = newGame(); for(int i = 0; i < 20; i++)  { g.Roll(0);    } Assert.That(g.Score(), Is.EqualTo(0)); } publicclassGame { privateint score; publicvoid Roll(int pins)  {  } publicintScore()  { returnscore;  } }
The Second test. [Test] publicvoidAllOnesTest() {     Gameg = newGame();     for(int i = 0; i < 20; i++)  { g.Roll(1);  } Assert.That(g.Score(), Is.EqualTo(20)); } publicclassGame { privateint score; publicvoid Roll(int pins)  {  } publicintScore()  { returnscore;  } }
The Second test. - Game creation is duplicated - roll loop is duplicated [Test] publicvoidAllOnesTest() {     Gameg = newGame();     for(int i = 0; i < 20; i++)  { g.Roll(1);  } Assert.That(g.Score(), Is.EqualTo(20)); } publicclassGame { privateint score; publicvoid Roll(int pins)  {  } publicintScore()  { returnscore;  } }
The Second test. - Game creation is duplicated - roll loop is duplicated [Test] publicvoidAllOnesTest() {     Gameg = newGame();     for(int i = 0; i < 20; i++)  { g.Roll(1);  } Assert.That(g.Score(), Is.EqualTo(20)); } 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; [SetUp] publicvoidSetup()  {     g = newGame(); } [Test] publicvoidGutterGameTest() { for(int i = 0; i < 20; i++)  { g.Roll(0);  } Assert.That(g.Score(), Is.EqualTo(0)); } [Test] publicvoidAllOnesTest() { for(int i = 0; i < 20; i++)  { g.Roll(1);  } Assert.That(g.Score(), Is.EqualTo(20)); } publicclassGame { privateint score; publicvoid Roll(int pins) { score += pins; } publicint Score() { return score;     } }
The Second test. - roll loop is duplicated [Test] publicvoidGutterGameTest() { int rolls = 20; intpins = 0; for(int i = 0; i < rolls; i++) { g.Roll(pins); } Assert.That(g.Score(), Is.EqualTo(0)); } publicclassGame { privateint score; publicvoid Roll(int pins) { score += pins; } publicint Score() { return score;     } }
The Second test. - roll loop is duplicated [Test] publicvoidGutterGameTest() { int rolls = 20; intpins = 0; RollMany(rolls, pins); for(int i = 0; i < rolls; i++)   { g.Roll(pins);  } Assert.That(g.Score(), Is.EqualTo(0)); } 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;     } } [Test] publicvoidGutterGameTest() { RollMany(20, 0); Assert.That(g.Score(), Is.EqualTo(0)); } privatevoidRollMany(introlls, int pins) {     for(int i = 0; i < rolls; i++)  { g.Roll(pins);  } }
The Second test. [Test] publicvoidGutterGameTest() { RollMany(20, 0); Assert.That(g.Score(), Is.EqualTo(0)); } [Test] publicvoidAllOnesTest() { RollMany(20, 1); Assert.That(g.Score(), Is.EqualTo(20)); } privatevoidRollMany(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. [Test] publicvoidOneSpareTest() { g.Roll(5); g.Roll(5); // spare g.Roll(3); RollMany(17, 0); Assert.That(g.Score(), Is.EqualTo(16)); } 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;     } } [Test] publicvoidOneSpareTest() { g.Roll(5); g.Roll(5); // spare g.Roll(3); RollMany(17, 0); Assert.That(g.Score(), Is.EqualTo(16)); } 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;     } } [Test] publicvoidOneSpareTest() { 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. [Test] publicvoidOneSpareTest() { g.Roll(5); g.Roll(5); // spare g.Roll(3); RollMany(17, 0); //Assert.That(g.Score(), Is.EqualTo(16)); } 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;     } } [Test] publicvoidOneSpareTest() { g.Roll(5); g.Roll(5); // spare g.Roll(3); RollMany(17, 0); //Assert.That(g.Score(), Is.EqualTo(16)); }
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;     } } [Test] publicvoidOneSpareTest() { g.Roll(5); g.Roll(5); // spare g.Roll(3); RollMany(17, 0); //Assert.That(g.Score(), Is.EqualTo(16)); }
The Third test. - ugly comment in test. [Test] publicvoidOneSpareTest() { g.Roll(5); g.Roll(5); // spare g.Roll(3); RollMany(17, 0); Assert.That(g.Score(), Is.EqualTo(16)); } 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; } [Test] publicvoidOneSpareTest() { g.Roll(5); g.Roll(5); // spare g.Roll(3); RollMany(17, 0); Assert.That(g.Score(), Is.EqualTo(16)); } 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;     } } [Test] publicvoidOneSpareTest() { g.Roll(5); g.Roll(5); // spare g.Roll(3); RollMany(17, 0); //Assert.That(g.Score(), Is.EqualTo(16)); Assert.Inconclusive(); }
The Third test. - ugly comment in test. publicint Score() { int score = 0; inti = 0; for (int frame = 0; frame < 10; frame++) {         score += rolls[i] + rolls[i + 1];         i+= 2; } returnscore; } [Test] publicvoidOneSpareTest() { g.Roll(5); g.Roll(5); // spare g.Roll(3); RollMany(17, 0); //Assert.That(g.Score(), Is.EqualTo(16)); Assert.Inconclusive(); }
The Third test. - ugly comment in test. [Test] publicvoidOneSpareTest() { g.Roll(5); g.Roll(5); // spare g.Roll(3); RollMany(17, 0); Assert.That(g.Score(), Is.EqualTo(16)); } publicint Score() { int score = 0; int i = 0; for (int frame = 0; frame < 10; frame++)     {         score += rolls[i] + rolls[i + 1];         i += 2;     } return score; } Failed Assert.AreEqual Expected:<16>. Actual:<13>
The Third test. - ugly comment in test. publicint Score() { int score = 0; inti = 0; for (int frame = 0; frame < 10; frame++) { // spare if (rolls[i] + rolls[i + 1] == 10) { score += 10 + rolls[i + 2]; i += 2; } else {             score += rolls[i] + rolls[i + 1];       i += 2;        }     } return score; } [Test] publicvoidOneSpareTest() { g.Roll(5); g.Roll(5); // spare g.Roll(3); RollMany(17, 0); Assert.That(g.Score(), Is.EqualTo(16)); }
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]; roll += 2; } else {             score += rolls[roll] + rolls[roll + 1];                   roll += 2;         }    } return score; } [Test] publicvoidOneSpareTest() { g.Roll(5); g.Roll(5); // spare g.Roll(3); RollMany(17, 0); Assert.That(g.Score(), Is.EqualTo(16)); }
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];             roll += 2;         } else         {             score += rolls[roll] + rolls[roll + 1];                   roll += 2; }    } returnscore; } privateboolIsSpare(int roll) {     returnrolls[roll] +     rolls[roll + 1] == 10; } [Test] publicvoidOneSpareTest() { g.Roll(5); g.Roll(5); // spare g.Roll(3); RollMany(17, 0); Assert.That(g.Score(), Is.EqualTo(16)); }
The Third test. [Test] publicvoidOneSpareTest() { RollSpare(); g.Roll(3); RollMany(17, 0); Assert.That(g.Score(), Is.EqualTo(16)); } privatevoidRollSpare() { 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];             roll += 2;         } else         {             score += rolls[roll] + rolls[roll + 1];                   roll += 2;         } } returnscore; } privateboolIsSpare(int roll) {     returnrolls[roll] +     rolls[roll + 1] == 10; }
The Fourth test. - ugly comment in OneStrikeTest. [Test] publicvoidOneStrikeTest() { g.Roll(10); // strike g.Roll(3); g.Roll(4); RollMany(16, 0); Assert.That(g.Score(), Is.EqualTo(24)); } 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; } [Test] publicvoidOneStrikeTest() { g.Roll(10); // strike g.Roll(3); g.Roll(4); RollMany(16, 0); Assert.That(g.Score(), Is.EqualTo(24)); }
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]; } [Test] publicvoidOneStrikeTest() { g.Roll(10); // strike g.Roll(3); g.Roll(4); RollMany(16, 0); Assert.That(g.Score(), Is.EqualTo(24)); }
The Fourth test. - ugly comment in OneStrikeTest. 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; } [Test] publicvoidOneStrikeTest() { g.Roll(10); // strike g.Roll(3); g.Roll(4); RollMany(16, 0); Assert.That(g.Score(), Is.EqualTo(24)); }

Mais conteúdo relacionado

Mais procurados (20)

[OKKY 세미나] 정진욱 - 테스트하기 쉬운 코드로 개발하기
[OKKY 세미나] 정진욱 - 테스트하기 쉬운 코드로 개발하기[OKKY 세미나] 정진욱 - 테스트하기 쉬운 코드로 개발하기
[OKKY 세미나] 정진욱 - 테스트하기 쉬운 코드로 개발하기
 
Java platform
Java platformJava platform
Java platform
 
Java Collections
Java  Collections Java  Collections
Java Collections
 
Java Fundamentals
Java FundamentalsJava Fundamentals
Java Fundamentals
 
Access Modifier.pptx
Access Modifier.pptxAccess Modifier.pptx
Access Modifier.pptx
 
Clean code slide
Clean code slideClean code slide
Clean code slide
 
6-Python-Recursion PPT.pptx
6-Python-Recursion PPT.pptx6-Python-Recursion PPT.pptx
6-Python-Recursion PPT.pptx
 
L14 exception handling
L14 exception handlingL14 exception handling
L14 exception handling
 
Clean code
Clean codeClean code
Clean code
 
Java practical
Java practicalJava practical
Java practical
 
This pointer
This pointerThis pointer
This pointer
 
Presentation on class and object in Object Oriented programming.
Presentation on class and object in Object Oriented programming.Presentation on class and object in Object Oriented programming.
Presentation on class and object in Object Oriented programming.
 
Java: Java Applets
Java: Java AppletsJava: Java Applets
Java: Java Applets
 
Inheritance
InheritanceInheritance
Inheritance
 
Access modifiers in java
Access modifiers in javaAccess modifiers in java
Access modifiers in java
 
Java script arrays
Java script arraysJava script arrays
Java script arrays
 
Packages
PackagesPackages
Packages
 
Clean coding-practices
Clean coding-practicesClean coding-practices
Clean coding-practices
 
Java operators
Java operatorsJava operators
Java operators
 
Set methods in python
Set methods in pythonSet methods in python
Set methods in python
 

Semelhante a Bowling Game Kata in C# Adapted

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
 
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. MartinLalit Kale
 
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
 
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
 
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
 
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
 
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
 
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
 
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 Ring programming language version 1.5 book - Part 9 of 31
The Ring programming language version 1.5 book - Part 9 of 31The Ring programming language version 1.5 book - Part 9 of 31
The Ring programming language version 1.5 book - Part 9 of 31Mahmoud Samir Fayed
 
Tic tac toe on c++ project
Tic tac toe on c++ projectTic tac toe on c++ project
Tic tac toe on c++ projectUtkarsh Aggarwal
 
Ifgqueue.h#ifndef LFGQUEUE_H #define LFGQUEUE_H#include pl.pdf
Ifgqueue.h#ifndef LFGQUEUE_H #define LFGQUEUE_H#include pl.pdfIfgqueue.h#ifndef LFGQUEUE_H #define LFGQUEUE_H#include pl.pdf
Ifgqueue.h#ifndef LFGQUEUE_H #define LFGQUEUE_H#include pl.pdffazilfootsteps
 
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
 
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
 
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
 

Semelhante a Bowling Game Kata in C# Adapted (20)

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 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 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
 
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
 
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++
 
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
 
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
 
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
 
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
 
Driver class
Driver classDriver class
Driver class
 
The Ring programming language version 1.5 book - Part 9 of 31
The Ring programming language version 1.5 book - Part 9 of 31The Ring programming language version 1.5 book - Part 9 of 31
The Ring programming language version 1.5 book - Part 9 of 31
 
Tic tac toe on c++ project
Tic tac toe on c++ projectTic tac toe on c++ project
Tic tac toe on c++ project
 
Ifgqueue.h#ifndef LFGQUEUE_H #define LFGQUEUE_H#include pl.pdf
Ifgqueue.h#ifndef LFGQUEUE_H #define LFGQUEUE_H#include pl.pdfIfgqueue.h#ifndef LFGQUEUE_H #define LFGQUEUE_H#include pl.pdf
Ifgqueue.h#ifndef LFGQUEUE_H #define LFGQUEUE_H#include pl.pdf
 
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
 
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
 
Oop objects_classes
Oop objects_classesOop objects_classes
Oop objects_classes
 
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
 

Mais de Mike Clement

Collaboration Principles from Mob Programming
Collaboration Principles from Mob ProgrammingCollaboration Principles from Mob Programming
Collaboration Principles from Mob ProgrammingMike Clement
 
Focus on Flow: Lean Principles in Action
Focus on Flow: Lean Principles in ActionFocus on Flow: Lean Principles in Action
Focus on Flow: Lean Principles in ActionMike Clement
 
Taming scary production code that nobody wants to touch
Taming scary production code that nobody wants to touchTaming scary production code that nobody wants to touch
Taming scary production code that nobody wants to touchMike Clement
 
Develop your sense of code smell
Develop your sense of code smellDevelop your sense of code smell
Develop your sense of code smellMike Clement
 
Maps over Backlogs: User Story Mapping to Share the Big Picture
Maps over Backlogs: User Story Mapping to Share the Big PictureMaps over Backlogs: User Story Mapping to Share the Big Picture
Maps over Backlogs: User Story Mapping to Share the Big PictureMike Clement
 
Escaping the Pitfalls of Software Product Development
Escaping the Pitfalls of Software Product DevelopmentEscaping the Pitfalls of Software Product Development
Escaping the Pitfalls of Software Product DevelopmentMike Clement
 
Put the Tests Before the Code
Put the Tests Before the CodePut the Tests Before the Code
Put the Tests Before the CodeMike Clement
 
Mob Programming for Continuous Learning
Mob Programming for Continuous LearningMob Programming for Continuous Learning
Mob Programming for Continuous LearningMike Clement
 
Play to Learn: Agile Games with Cards and Dice
Play to Learn: Agile Games with Cards and DicePlay to Learn: Agile Games with Cards and Dice
Play to Learn: Agile Games with Cards and DiceMike Clement
 
The Quest for Continuous Delivery at Pluralsight
The Quest for Continuous Delivery at PluralsightThe Quest for Continuous Delivery at Pluralsight
The Quest for Continuous Delivery at PluralsightMike Clement
 
Software Craftsmanship and Agile Code Games
Software Craftsmanship and Agile Code GamesSoftware Craftsmanship and Agile Code Games
Software Craftsmanship and Agile Code GamesMike Clement
 
Transformation Priority Premise: TDD Test Order Matters
Transformation Priority Premise: TDD Test Order MattersTransformation Priority Premise: TDD Test Order Matters
Transformation Priority Premise: TDD Test Order MattersMike Clement
 
Power of Patterns: Refactoring to (or away from) Patterns
Power of Patterns: Refactoring to (or away from) PatternsPower of Patterns: Refactoring to (or away from) Patterns
Power of Patterns: Refactoring to (or away from) PatternsMike Clement
 
Code Katas Spring 2012
Code Katas Spring 2012Code Katas Spring 2012
Code Katas Spring 2012Mike Clement
 
FizzBuzz Guided Kata
FizzBuzz Guided KataFizzBuzz Guided Kata
FizzBuzz Guided KataMike Clement
 
Linq (from the inside)
Linq (from the inside)Linq (from the inside)
Linq (from the inside)Mike Clement
 
Code Katas: Practicing Your Craft
Code Katas: Practicing Your CraftCode Katas: Practicing Your Craft
Code Katas: Practicing Your CraftMike Clement
 
Software Craftsmanship
Software CraftsmanshipSoftware Craftsmanship
Software CraftsmanshipMike Clement
 
Using Rhino Mocks for Effective Unit Testing
Using Rhino Mocks for Effective Unit TestingUsing Rhino Mocks for Effective Unit Testing
Using Rhino Mocks for Effective Unit TestingMike Clement
 

Mais de Mike Clement (20)

Collaboration Principles from Mob Programming
Collaboration Principles from Mob ProgrammingCollaboration Principles from Mob Programming
Collaboration Principles from Mob Programming
 
Focus on Flow: Lean Principles in Action
Focus on Flow: Lean Principles in ActionFocus on Flow: Lean Principles in Action
Focus on Flow: Lean Principles in Action
 
Taming scary production code that nobody wants to touch
Taming scary production code that nobody wants to touchTaming scary production code that nobody wants to touch
Taming scary production code that nobody wants to touch
 
Develop your sense of code smell
Develop your sense of code smellDevelop your sense of code smell
Develop your sense of code smell
 
Maps over Backlogs: User Story Mapping to Share the Big Picture
Maps over Backlogs: User Story Mapping to Share the Big PictureMaps over Backlogs: User Story Mapping to Share the Big Picture
Maps over Backlogs: User Story Mapping to Share the Big Picture
 
Escaping the Pitfalls of Software Product Development
Escaping the Pitfalls of Software Product DevelopmentEscaping the Pitfalls of Software Product Development
Escaping the Pitfalls of Software Product Development
 
Put the Tests Before the Code
Put the Tests Before the CodePut the Tests Before the Code
Put the Tests Before the Code
 
Mob Programming for Continuous Learning
Mob Programming for Continuous LearningMob Programming for Continuous Learning
Mob Programming for Continuous Learning
 
Play to Learn: Agile Games with Cards and Dice
Play to Learn: Agile Games with Cards and DicePlay to Learn: Agile Games with Cards and Dice
Play to Learn: Agile Games with Cards and Dice
 
The Quest for Continuous Delivery at Pluralsight
The Quest for Continuous Delivery at PluralsightThe Quest for Continuous Delivery at Pluralsight
The Quest for Continuous Delivery at Pluralsight
 
Software Craftsmanship and Agile Code Games
Software Craftsmanship and Agile Code GamesSoftware Craftsmanship and Agile Code Games
Software Craftsmanship and Agile Code Games
 
Thinking in F#
Thinking in F#Thinking in F#
Thinking in F#
 
Transformation Priority Premise: TDD Test Order Matters
Transformation Priority Premise: TDD Test Order MattersTransformation Priority Premise: TDD Test Order Matters
Transformation Priority Premise: TDD Test Order Matters
 
Power of Patterns: Refactoring to (or away from) Patterns
Power of Patterns: Refactoring to (or away from) PatternsPower of Patterns: Refactoring to (or away from) Patterns
Power of Patterns: Refactoring to (or away from) Patterns
 
Code Katas Spring 2012
Code Katas Spring 2012Code Katas Spring 2012
Code Katas Spring 2012
 
FizzBuzz Guided Kata
FizzBuzz Guided KataFizzBuzz Guided Kata
FizzBuzz Guided Kata
 
Linq (from the inside)
Linq (from the inside)Linq (from the inside)
Linq (from the inside)
 
Code Katas: Practicing Your Craft
Code Katas: Practicing Your CraftCode Katas: Practicing Your Craft
Code Katas: Practicing Your Craft
 
Software Craftsmanship
Software CraftsmanshipSoftware Craftsmanship
Software Craftsmanship
 
Using Rhino Mocks for Effective Unit Testing
Using Rhino Mocks for Effective Unit TestingUsing Rhino Mocks for Effective Unit Testing
Using Rhino Mocks for Effective Unit Testing
 

Último

Exploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone ProcessorsExploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone Processorsdebabhi2
 
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking MenDelhi Call girls
 
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdfThe Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdfEnterprise Knowledge
 
Automating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps ScriptAutomating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps Scriptwesley chun
 
Injustice - Developers Among Us (SciFiDevCon 2024)
Injustice - Developers Among Us (SciFiDevCon 2024)Injustice - Developers Among Us (SciFiDevCon 2024)
Injustice - Developers Among Us (SciFiDevCon 2024)Allon Mureinik
 
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...Neo4j
 
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law DevelopmentsTrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law DevelopmentsTrustArc
 
Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024The Digital Insurer
 
[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdfhans926745
 
A Call to Action for Generative AI in 2024
A Call to Action for Generative AI in 2024A Call to Action for Generative AI in 2024
A Call to Action for Generative AI in 2024Results
 
🐬 The future of MySQL is Postgres 🐘
🐬  The future of MySQL is Postgres   🐘🐬  The future of MySQL is Postgres   🐘
🐬 The future of MySQL is Postgres 🐘RTylerCroy
 
Driving Behavioral Change for Information Management through Data-Driven Gree...
Driving Behavioral Change for Information Management through Data-Driven Gree...Driving Behavioral Change for Information Management through Data-Driven Gree...
Driving Behavioral Change for Information Management through Data-Driven Gree...Enterprise Knowledge
 
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptxEIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptxEarley Information Science
 
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...
Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...Neo4j
 
The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024Rafal Los
 
08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking MenDelhi Call girls
 
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...Drew Madelung
 
Boost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivityBoost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivityPrincipled Technologies
 
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
 
Top 5 Benefits OF Using Muvi Live Paywall For Live Streams
Top 5 Benefits OF Using Muvi Live Paywall For Live StreamsTop 5 Benefits OF Using Muvi Live Paywall For Live Streams
Top 5 Benefits OF Using Muvi Live Paywall For Live StreamsRoshan Dwivedi
 

Último (20)

Exploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone ProcessorsExploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone Processors
 
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
 
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdfThe Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
 
Automating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps ScriptAutomating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps Script
 
Injustice - Developers Among Us (SciFiDevCon 2024)
Injustice - Developers Among Us (SciFiDevCon 2024)Injustice - Developers Among Us (SciFiDevCon 2024)
Injustice - Developers Among Us (SciFiDevCon 2024)
 
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...
 
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law DevelopmentsTrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
 
Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024
 
[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf
 
A Call to Action for Generative AI in 2024
A Call to Action for Generative AI in 2024A Call to Action for Generative AI in 2024
A Call to Action for Generative AI in 2024
 
🐬 The future of MySQL is Postgres 🐘
🐬  The future of MySQL is Postgres   🐘🐬  The future of MySQL is Postgres   🐘
🐬 The future of MySQL is Postgres 🐘
 
Driving Behavioral Change for Information Management through Data-Driven Gree...
Driving Behavioral Change for Information Management through Data-Driven Gree...Driving Behavioral Change for Information Management through Data-Driven Gree...
Driving Behavioral Change for Information Management through Data-Driven Gree...
 
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptxEIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
 
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...
Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...
 
The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024
 
08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men
 
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
 
Boost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivityBoost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivity
 
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
 
Top 5 Benefits OF Using Muvi Live Paywall For Live Streams
Top 5 Benefits OF Using Muvi Live Paywall For Live StreamsTop 5 Benefits OF Using Muvi Live Paywall For Live Streams
Top 5 Benefits OF Using Muvi Live Paywall For Live Streams
 

Bowling Game Kata in C# Adapted

  • 1. Bowling Game KataAdapted for C# and nUnit By Dan Stewart (with modifications by Mike Clement) dan@stewshack.com mike@softwareontheside.com
  • 2. 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.
  • 3. A quick design session Clearly we need the Game class.
  • 4. A quick design session A game has 10 frames.
  • 5. A quick design session A frame has 1 or two rolls.
  • 6. A quick design session The tenth frame has two or three rolls. It is different from all the other frames.
  • 7. A quick design session The score function must include all the frames, and calculate all their scores.
  • 8. A quick design session The score for a spare or a strike depends on the frame’s successor
  • 9. Begin. Create a class library named BowlingGameKata
  • 10. Begin. Add a test fixture named BowlingGameTests to the project usingNUnit.Framework; namespaceBowlingGameKata { [TestFixture] publicclassBowlingGameTests { [Test] publicvoidGutterGameTest() { } } }
  • 11. The first test. [Test] publicvoidGutterGameTest() { Game g = new Game(); }
  • 12. The first test. namespaceBowlingGameKata { publicclassGame { } } [Test] publicvoidGutterGameTest() { Game g = new Game(); }
  • 13. The first test. [Test] publicvoidGutterGameTest() { Game g = new Game(); } publicclassGame { }
  • 14. The first test. [Test] publicvoidGutterGameTest() { Gameg = newGame(); for(int i = 0; i < 20; i++) { g.Roll(0); } } publicclassGame { }
  • 15. The first test. public class Game { publicvoid Roll(int p) { thrownewSystem.NotImplementedException(); } } [Test] publicvoidGutterGameTest() { Gameg = newGame(); for(int i = 0; i < 20; i++) { g.Roll(0); } }
  • 16. The first test. [Test] publicvoidGutterGameTest() { Gameg = newGame(); for(int i = 0; i < 20; i++) { g.Roll(0); } Assert.That(g.Score(), Is.EqualTo(0)); } public class Game { publicvoid Roll(int p) { thrownewSystem.NotImplementedException(); } }
  • 17. The first test. [Test] publicvoidGutterGameTest() { Gameg = newGame(); for(int i = 0; i < 20; i++) { g.Roll(0); } Assert.That(g.Score(), Is.EqualTo(0)); } publicclassGame { publicvoid Roll(int p) { thrownew System.NotImplementedException(); } publicobject Score() { thrownew System.NotImplementedException(); } } Failed GutterGameTestthrew exception
  • 18. The first test. [Test] publicvoidGutterGameTest() { Gameg = newGame(); for(int i = 0; i < 20; i++) { g.Roll(0); } Assert.That(g.Score(), Is.EqualTo(0)); } publicclassGame { privateint score; publicvoid Roll(int pins) { } publicintScore() { returnscore; } }
  • 19. The Second test. [Test] publicvoidAllOnesTest() { Gameg = newGame(); for(int i = 0; i < 20; i++) { g.Roll(1); } Assert.That(g.Score(), Is.EqualTo(20)); } publicclassGame { privateint score; publicvoid Roll(int pins) { } publicintScore() { returnscore; } }
  • 20. The Second test. - Game creation is duplicated - roll loop is duplicated [Test] publicvoidAllOnesTest() { Gameg = newGame(); for(int i = 0; i < 20; i++) { g.Roll(1); } Assert.That(g.Score(), Is.EqualTo(20)); } publicclassGame { privateint score; publicvoid Roll(int pins) { } publicintScore() { returnscore; } }
  • 21. The Second test. - Game creation is duplicated - roll loop is duplicated [Test] publicvoidAllOnesTest() { Gameg = newGame(); for(int i = 0; i < 20; i++) { g.Roll(1); } Assert.That(g.Score(), Is.EqualTo(20)); } publicclassGame { privateint score; publicvoid Roll(int pins) { } publicintScore() { return score; } } Assert.AreEqual failed. Expected:<20>. Actual:<0>.
  • 22. The Second test. - roll loop is duplicated privateGame g; [SetUp] publicvoidSetup() { g = newGame(); } [Test] publicvoidGutterGameTest() { for(int i = 0; i < 20; i++) { g.Roll(0); } Assert.That(g.Score(), Is.EqualTo(0)); } [Test] publicvoidAllOnesTest() { for(int i = 0; i < 20; i++) { g.Roll(1); } Assert.That(g.Score(), Is.EqualTo(20)); } publicclassGame { privateint score; publicvoid Roll(int pins) { score += pins; } publicint Score() { return score; } }
  • 23. The Second test. - roll loop is duplicated [Test] publicvoidGutterGameTest() { int rolls = 20; intpins = 0; for(int i = 0; i < rolls; i++) { g.Roll(pins); } Assert.That(g.Score(), Is.EqualTo(0)); } publicclassGame { privateint score; publicvoid Roll(int pins) { score += pins; } publicint Score() { return score; } }
  • 24. The Second test. - roll loop is duplicated [Test] publicvoidGutterGameTest() { int rolls = 20; intpins = 0; RollMany(rolls, pins); for(int i = 0; i < rolls; i++) { g.Roll(pins); } Assert.That(g.Score(), Is.EqualTo(0)); } publicclassGame { privateint score; publicvoid Roll(int pins) { score += pins; } publicint Score() { return score; } }
  • 25. The Second test. publicclassGame { privateint score; publicvoid Roll(int pins) { score += pins; } publicint Score() { return score; } } [Test] publicvoidGutterGameTest() { RollMany(20, 0); Assert.That(g.Score(), Is.EqualTo(0)); } privatevoidRollMany(introlls, int pins) { for(int i = 0; i < rolls; i++) { g.Roll(pins); } }
  • 26. The Second test. [Test] publicvoidGutterGameTest() { RollMany(20, 0); Assert.That(g.Score(), Is.EqualTo(0)); } [Test] publicvoidAllOnesTest() { RollMany(20, 1); Assert.That(g.Score(), Is.EqualTo(20)); } privatevoidRollMany(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; } }
  • 27. The Third test. - ugly comment in test. [Test] publicvoidOneSpareTest() { g.Roll(5); g.Roll(5); // spare g.Roll(3); RollMany(17, 0); Assert.That(g.Score(), Is.EqualTo(16)); } publicclassGame { privateint score; publicvoid Roll(int pins) { score += pins; } publicint Score() { return score; } } Failed Assert.AreEqual Expected:<16>. Actual:<13>
  • 28. The Third test. - ugly comment in test. publicclassGame { privateint score; publicvoid Roll(int pins) { score += pins; } publicint Score() { return score; } } [Test] publicvoidOneSpareTest() { g.Roll(5); g.Roll(5); // spare g.Roll(3); RollMany(17, 0); Assert.That(g.Score(), Is.EqualTo(16)); } tempted to use flag to remember previous roll. So design must be wrong. Failed Assert.AreEqual Expected:<16>. Actual:<13>
  • 29. 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; } } [Test] publicvoidOneSpareTest() { 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>
  • 30. The Third test. - ugly comment in test. [Test] publicvoidOneSpareTest() { g.Roll(5); g.Roll(5); // spare g.Roll(3); RollMany(17, 0); //Assert.That(g.Score(), Is.EqualTo(16)); } publicclassGame { privateint score; publicvoid Roll(int pins) { score += pins; } publicint Score() { return score; } }
  • 31. 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; } } [Test] publicvoidOneSpareTest() { g.Roll(5); g.Roll(5); // spare g.Roll(3); RollMany(17, 0); //Assert.That(g.Score(), Is.EqualTo(16)); }
  • 32. 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; } } [Test] publicvoidOneSpareTest() { g.Roll(5); g.Roll(5); // spare g.Roll(3); RollMany(17, 0); //Assert.That(g.Score(), Is.EqualTo(16)); }
  • 33. The Third test. - ugly comment in test. [Test] publicvoidOneSpareTest() { g.Roll(5); g.Roll(5); // spare g.Roll(3); RollMany(17, 0); Assert.That(g.Score(), Is.EqualTo(16)); } 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>
  • 34. 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; } [Test] publicvoidOneSpareTest() { g.Roll(5); g.Roll(5); // spare g.Roll(3); RollMany(17, 0); Assert.That(g.Score(), Is.EqualTo(16)); } 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>
  • 35. 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; } } [Test] publicvoidOneSpareTest() { g.Roll(5); g.Roll(5); // spare g.Roll(3); RollMany(17, 0); //Assert.That(g.Score(), Is.EqualTo(16)); Assert.Inconclusive(); }
  • 36. The Third test. - ugly comment in test. publicint Score() { int score = 0; inti = 0; for (int frame = 0; frame < 10; frame++) { score += rolls[i] + rolls[i + 1]; i+= 2; } returnscore; } [Test] publicvoidOneSpareTest() { g.Roll(5); g.Roll(5); // spare g.Roll(3); RollMany(17, 0); //Assert.That(g.Score(), Is.EqualTo(16)); Assert.Inconclusive(); }
  • 37. The Third test. - ugly comment in test. [Test] publicvoidOneSpareTest() { g.Roll(5); g.Roll(5); // spare g.Roll(3); RollMany(17, 0); Assert.That(g.Score(), Is.EqualTo(16)); } publicint Score() { int score = 0; int i = 0; for (int frame = 0; frame < 10; frame++) { score += rolls[i] + rolls[i + 1]; i += 2; } return score; } Failed Assert.AreEqual Expected:<16>. Actual:<13>
  • 38. The Third test. - ugly comment in test. publicint Score() { int score = 0; inti = 0; for (int frame = 0; frame < 10; frame++) { // spare if (rolls[i] + rolls[i + 1] == 10) { score += 10 + rolls[i + 2]; i += 2; } else { score += rolls[i] + rolls[i + 1]; i += 2; } } return score; } [Test] publicvoidOneSpareTest() { g.Roll(5); g.Roll(5); // spare g.Roll(3); RollMany(17, 0); Assert.That(g.Score(), Is.EqualTo(16)); }
  • 39.
  • 40. 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]; roll += 2; } else { score += rolls[roll] + rolls[roll + 1]; roll += 2; } } return score; } [Test] publicvoidOneSpareTest() { g.Roll(5); g.Roll(5); // spare g.Roll(3); RollMany(17, 0); Assert.That(g.Score(), Is.EqualTo(16)); }
  • 41. 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]; roll += 2; } else { score += rolls[roll] + rolls[roll + 1]; roll += 2; } } returnscore; } privateboolIsSpare(int roll) { returnrolls[roll] + rolls[roll + 1] == 10; } [Test] publicvoidOneSpareTest() { g.Roll(5); g.Roll(5); // spare g.Roll(3); RollMany(17, 0); Assert.That(g.Score(), Is.EqualTo(16)); }
  • 42. The Third test. [Test] publicvoidOneSpareTest() { RollSpare(); g.Roll(3); RollMany(17, 0); Assert.That(g.Score(), Is.EqualTo(16)); } privatevoidRollSpare() { 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]; roll += 2; } else { score += rolls[roll] + rolls[roll + 1]; roll += 2; } } returnscore; } privateboolIsSpare(int roll) { returnrolls[roll] + rolls[roll + 1] == 10; }
  • 43. The Fourth test. - ugly comment in OneStrikeTest. [Test] publicvoidOneStrikeTest() { g.Roll(10); // strike g.Roll(3); g.Roll(4); RollMany(16, 0); Assert.That(g.Score(), Is.EqualTo(24)); } 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>
  • 44.
  • 45. ugly comment in conditional.
  • 46. 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; } [Test] publicvoidOneStrikeTest() { g.Roll(10); // strike g.Roll(3); g.Roll(4); RollMany(16, 0); Assert.That(g.Score(), Is.EqualTo(24)); }
  • 47.
  • 48. 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]; } [Test] publicvoidOneStrikeTest() { g.Roll(10); // strike g.Roll(3); g.Roll(4); RollMany(16, 0); Assert.That(g.Score(), Is.EqualTo(24)); }
  • 49. The Fourth test. - ugly comment in OneStrikeTest. 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; } [Test] publicvoidOneStrikeTest() { g.Roll(10); // strike g.Roll(3); g.Roll(4); RollMany(16, 0); Assert.That(g.Score(), Is.EqualTo(24)); }
  • 50. The Fourth test. [Test] publicvoidOneStrikeTest() { RollStrike(); g.Roll(3); g.Roll(4); RollMany(16, 0); Assert.That(g.Score(), Is.EqualTo(24)); } privatevoidRollStrike() { 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; }
  • 51. The Fifth test. [Test] publicvoidPerfectGameTest() { RollMany(12, 10); Assert.That(g.Score(), Is.EqualTo(300)); } 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; }

Notas do Editor

  1. I would like to thank Uncle Bob Martin and Object Mentor for the bowling game kata.