SlideShare a Scribd company logo
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)); }

More Related Content

What's hot

如何使用 Xhprof 分析網站效能 (真實案例2)
如何使用 Xhprof 分析網站效能 (真實案例2)如何使用 Xhprof 分析網站效能 (真實案例2)
如何使用 Xhprof 分析網站效能 (真實案例2)
Cyril Wang
 
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
Lalit Kale
 
Composable and streamable Play apps
Composable and streamable Play appsComposable and streamable Play apps
Composable and streamable Play apps
Yevgeniy Brikman
 
C++ 프로젝트에 단위 테스트 도입하기
C++ 프로젝트에 단위 테스트 도입하기C++ 프로젝트에 단위 테스트 도입하기
C++ 프로젝트에 단위 테스트 도입하기Heo Seungwook
 
Naked Performance With Clojure
Naked Performance With ClojureNaked Performance With Clojure
Naked Performance With Clojure
Metosin Oy
 
Refactoring: A First Example - Martin Fowler’s First Example of Refactoring, ...
Refactoring: A First Example - Martin Fowler’s First Example of Refactoring, ...Refactoring: A First Example - Martin Fowler’s First Example of Refactoring, ...
Refactoring: A First Example - Martin Fowler’s First Example of Refactoring, ...
Philip Schwarz
 
Java Foundations: Data Types and Type Conversion
Java Foundations: Data Types and Type ConversionJava Foundations: Data Types and Type Conversion
Java Foundations: Data Types and Type Conversion
Svetlin Nakov
 
Async js
Async jsAsync js
Automação e virtualização de serviços
Automação e virtualização de serviçosAutomação e virtualização de serviços
Automação e virtualização de serviços
Elias Nogueira
 
Unit Testing in Android
Unit Testing in AndroidUnit Testing in Android
Unit Testing in Android
Md Shamsul Arafin Mahtab
 
09 윈도우스타일
09 윈도우스타일09 윈도우스타일
09 윈도우스타일
jaypi Ko
 
Pipeline oriented programming
Pipeline oriented programmingPipeline oriented programming
Pipeline oriented programming
Scott Wlaschin
 
RxJS & Angular Reactive Forms @ Codemotion 2019
RxJS & Angular Reactive Forms @ Codemotion 2019RxJS & Angular Reactive Forms @ Codemotion 2019
RxJS & Angular Reactive Forms @ Codemotion 2019
Fabio Biondi
 
Java Quiz Questions
Java Quiz QuestionsJava Quiz Questions
Java Quiz Questions
CodeOps Technologies LLP
 
06 일반적 유형의 프로그램
06 일반적 유형의 프로그램06 일반적 유형의 프로그램
06 일반적 유형의 프로그램
jaypi Ko
 
From object oriented to functional domain modeling
From object oriented to functional domain modelingFrom object oriented to functional domain modeling
From object oriented to functional domain modeling
Mario Fusco
 
Mocking in Java with Mockito
Mocking in Java with MockitoMocking in Java with Mockito
Mocking in Java with MockitoRichard Paul
 
Introduction to Linked Data 1/5
Introduction to Linked Data 1/5Introduction to Linked Data 1/5
Introduction to Linked Data 1/5Juan Sequeda
 
Clean backends with NestJs
Clean backends with NestJsClean backends with NestJs
Clean backends with NestJs
Aymene Bennour
 
Whitebox testing of Spring Boot applications
Whitebox testing of Spring Boot applicationsWhitebox testing of Spring Boot applications
Whitebox testing of Spring Boot applications
Yura Nosenko
 

What's hot (20)

如何使用 Xhprof 分析網站效能 (真實案例2)
如何使用 Xhprof 分析網站效能 (真實案例2)如何使用 Xhprof 分析網站效能 (真實案例2)
如何使用 Xhprof 分析網站效能 (真實案例2)
 
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
 
Composable and streamable Play apps
Composable and streamable Play appsComposable and streamable Play apps
Composable and streamable Play apps
 
C++ 프로젝트에 단위 테스트 도입하기
C++ 프로젝트에 단위 테스트 도입하기C++ 프로젝트에 단위 테스트 도입하기
C++ 프로젝트에 단위 테스트 도입하기
 
Naked Performance With Clojure
Naked Performance With ClojureNaked Performance With Clojure
Naked Performance With Clojure
 
Refactoring: A First Example - Martin Fowler’s First Example of Refactoring, ...
Refactoring: A First Example - Martin Fowler’s First Example of Refactoring, ...Refactoring: A First Example - Martin Fowler’s First Example of Refactoring, ...
Refactoring: A First Example - Martin Fowler’s First Example of Refactoring, ...
 
Java Foundations: Data Types and Type Conversion
Java Foundations: Data Types and Type ConversionJava Foundations: Data Types and Type Conversion
Java Foundations: Data Types and Type Conversion
 
Async js
Async jsAsync js
Async js
 
Automação e virtualização de serviços
Automação e virtualização de serviçosAutomação e virtualização de serviços
Automação e virtualização de serviços
 
Unit Testing in Android
Unit Testing in AndroidUnit Testing in Android
Unit Testing in Android
 
09 윈도우스타일
09 윈도우스타일09 윈도우스타일
09 윈도우스타일
 
Pipeline oriented programming
Pipeline oriented programmingPipeline oriented programming
Pipeline oriented programming
 
RxJS & Angular Reactive Forms @ Codemotion 2019
RxJS & Angular Reactive Forms @ Codemotion 2019RxJS & Angular Reactive Forms @ Codemotion 2019
RxJS & Angular Reactive Forms @ Codemotion 2019
 
Java Quiz Questions
Java Quiz QuestionsJava Quiz Questions
Java Quiz Questions
 
06 일반적 유형의 프로그램
06 일반적 유형의 프로그램06 일반적 유형의 프로그램
06 일반적 유형의 프로그램
 
From object oriented to functional domain modeling
From object oriented to functional domain modelingFrom object oriented to functional domain modeling
From object oriented to functional domain modeling
 
Mocking in Java with Mockito
Mocking in Java with MockitoMocking in Java with Mockito
Mocking in Java with Mockito
 
Introduction to Linked Data 1/5
Introduction to Linked Data 1/5Introduction to Linked Data 1/5
Introduction to Linked Data 1/5
 
Clean backends with NestJs
Clean backends with NestJsClean backends with NestJs
Clean backends with NestJs
 
Whitebox testing of Spring Boot applications
Whitebox testing of Spring Boot applicationsWhitebox testing of Spring Boot applications
Whitebox testing of Spring Boot applications
 

Similar to Bowling Game Kata in C# Adapted

Bowling game kata
Bowling game kataBowling game kata
Bowling game kataRahman Ash
 
Bowling game kata
Bowling game kataBowling game kata
Bowling game kataJoe McCall
 
Bowling game kata
Bowling game kataBowling game kata
Bowling game kataCarol Bruno
 
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.pdf
archanaemporium
 
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
asif1401
 
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.pdf
FashionColZone
 
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
info430661
 
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
anjandavid
 
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
udit652068
 
Driver class
Driver classDriver class
Driver class
VenkatRaoJ
 
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
Mahmoud Samir Fayed
 
Tic tac toe on c++ project
Tic tac toe on c++ projectTic tac toe on c++ project
Tic tac toe on c++ project
Utkarsh 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.pdf
fazilfootsteps
 
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
aggarwalshoppe14
 
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
Mahmoud 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 88
Mahmoud Samir Fayed
 
Testing a 2D Platformer with Spock
Testing a 2D Platformer with SpockTesting a 2D Platformer with Spock
Testing a 2D Platformer with Spock
Alexander Tarlinder
 
Write a class (BasketballTeam) encapsulating the concept of a tea.pdf
Write a class (BasketballTeam) encapsulating the concept of a tea.pdfWrite a class (BasketballTeam) encapsulating the concept of a tea.pdf
Write a class (BasketballTeam) encapsulating the concept of a tea.pdf
rozakashif85
 

Similar to 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
 
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
 
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
 
Testing a 2D Platformer with Spock
Testing a 2D Platformer with SpockTesting a 2D Platformer with Spock
Testing a 2D Platformer with Spock
 
Write a class (BasketballTeam) encapsulating the concept of a tea.pdf
Write a class (BasketballTeam) encapsulating the concept of a tea.pdfWrite a class (BasketballTeam) encapsulating the concept of a tea.pdf
Write a class (BasketballTeam) encapsulating the concept of a tea.pdf
 

More from Mike Clement

Collaboration Principles from Mob Programming
Collaboration Principles from Mob ProgrammingCollaboration Principles from Mob Programming
Collaboration Principles from Mob Programming
Mike 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 Action
Mike 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 touch
Mike Clement
 
Develop your sense of code smell
Develop your sense of code smellDevelop your sense of code smell
Develop your sense of code smell
Mike 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 Picture
Mike 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 Development
Mike Clement
 
Put the Tests Before the Code
Put the Tests Before the CodePut the Tests Before the Code
Put the Tests Before the Code
Mike Clement
 
Mob Programming for Continuous Learning
Mob Programming for Continuous LearningMob Programming for Continuous Learning
Mob Programming for Continuous Learning
Mike 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 Dice
Mike 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 Pluralsight
Mike Clement
 
Software Craftsmanship and Agile Code Games
Software Craftsmanship and Agile Code GamesSoftware Craftsmanship and Agile Code Games
Software Craftsmanship and Agile Code Games
Mike Clement
 
Thinking in F#
Thinking in F#Thinking in F#
Thinking in F#
Mike 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 Matters
Mike 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) Patterns
Mike 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 Craft
Mike 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
 

More from 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
 

Recently uploaded

Pushing the limits of ePRTC: 100ns holdover for 100 days
Pushing the limits of ePRTC: 100ns holdover for 100 daysPushing the limits of ePRTC: 100ns holdover for 100 days
Pushing the limits of ePRTC: 100ns holdover for 100 days
Adtran
 
GDG Cloud Southlake #33: Boule & Rebala: Effective AppSec in SDLC using Deplo...
GDG Cloud Southlake #33: Boule & Rebala: Effective AppSec in SDLC using Deplo...GDG Cloud Southlake #33: Boule & Rebala: Effective AppSec in SDLC using Deplo...
GDG Cloud Southlake #33: Boule & Rebala: Effective AppSec in SDLC using Deplo...
James Anderson
 
Monitoring Java Application Security with JDK Tools and JFR Events
Monitoring Java Application Security with JDK Tools and JFR EventsMonitoring Java Application Security with JDK Tools and JFR Events
Monitoring Java Application Security with JDK Tools and JFR Events
Ana-Maria Mihalceanu
 
Essentials of Automations: The Art of Triggers and Actions in FME
Essentials of Automations: The Art of Triggers and Actions in FMEEssentials of Automations: The Art of Triggers and Actions in FME
Essentials of Automations: The Art of Triggers and Actions in FME
Safe Software
 
GraphSummit Singapore | The Future of Agility: Supercharging Digital Transfor...
GraphSummit Singapore | The Future of Agility: Supercharging Digital Transfor...GraphSummit Singapore | The Future of Agility: Supercharging Digital Transfor...
GraphSummit Singapore | The Future of Agility: Supercharging Digital Transfor...
Neo4j
 
DevOps and Testing slides at DASA Connect
DevOps and Testing slides at DASA ConnectDevOps and Testing slides at DASA Connect
DevOps and Testing slides at DASA Connect
Kari Kakkonen
 
Climate Impact of Software Testing at Nordic Testing Days
Climate Impact of Software Testing at Nordic Testing DaysClimate Impact of Software Testing at Nordic Testing Days
Climate Impact of Software Testing at Nordic Testing Days
Kari Kakkonen
 
Why You Should Replace Windows 11 with Nitrux Linux 3.5.0 for enhanced perfor...
Why You Should Replace Windows 11 with Nitrux Linux 3.5.0 for enhanced perfor...Why You Should Replace Windows 11 with Nitrux Linux 3.5.0 for enhanced perfor...
Why You Should Replace Windows 11 with Nitrux Linux 3.5.0 for enhanced perfor...
SOFTTECHHUB
 
20240607 QFM018 Elixir Reading List May 2024
20240607 QFM018 Elixir Reading List May 202420240607 QFM018 Elixir Reading List May 2024
20240607 QFM018 Elixir Reading List May 2024
Matthew Sinclair
 
A tale of scale & speed: How the US Navy is enabling software delivery from l...
A tale of scale & speed: How the US Navy is enabling software delivery from l...A tale of scale & speed: How the US Navy is enabling software delivery from l...
A tale of scale & speed: How the US Navy is enabling software delivery from l...
sonjaschweigert1
 
GraphRAG is All You need? LLM & Knowledge Graph
GraphRAG is All You need? LLM & Knowledge GraphGraphRAG is All You need? LLM & Knowledge Graph
GraphRAG is All You need? LLM & Knowledge Graph
Guy Korland
 
State of ICS and IoT Cyber Threat Landscape Report 2024 preview
State of ICS and IoT Cyber Threat Landscape Report 2024 previewState of ICS and IoT Cyber Threat Landscape Report 2024 preview
State of ICS and IoT Cyber Threat Landscape Report 2024 preview
Prayukth K V
 
FIDO Alliance Osaka Seminar: FIDO Security Aspects.pdf
FIDO Alliance Osaka Seminar: FIDO Security Aspects.pdfFIDO Alliance Osaka Seminar: FIDO Security Aspects.pdf
FIDO Alliance Osaka Seminar: FIDO Security Aspects.pdf
FIDO Alliance
 
Generative AI Deep Dive: Advancing from Proof of Concept to Production
Generative AI Deep Dive: Advancing from Proof of Concept to ProductionGenerative AI Deep Dive: Advancing from Proof of Concept to Production
Generative AI Deep Dive: Advancing from Proof of Concept to Production
Aggregage
 
LF Energy Webinar: Electrical Grid Modelling and Simulation Through PowSyBl -...
LF Energy Webinar: Electrical Grid Modelling and Simulation Through PowSyBl -...LF Energy Webinar: Electrical Grid Modelling and Simulation Through PowSyBl -...
LF Energy Webinar: Electrical Grid Modelling and Simulation Through PowSyBl -...
DanBrown980551
 
Uni Systems Copilot event_05062024_C.Vlachos.pdf
Uni Systems Copilot event_05062024_C.Vlachos.pdfUni Systems Copilot event_05062024_C.Vlachos.pdf
Uni Systems Copilot event_05062024_C.Vlachos.pdf
Uni Systems S.M.S.A.
 
Smart TV Buyer Insights Survey 2024 by 91mobiles.pdf
Smart TV Buyer Insights Survey 2024 by 91mobiles.pdfSmart TV Buyer Insights Survey 2024 by 91mobiles.pdf
Smart TV Buyer Insights Survey 2024 by 91mobiles.pdf
91mobiles
 
Introduction to CHERI technology - Cybersecurity
Introduction to CHERI technology - CybersecurityIntroduction to CHERI technology - Cybersecurity
Introduction to CHERI technology - Cybersecurity
mikeeftimakis1
 
Encryption in Microsoft 365 - ExpertsLive Netherlands 2024
Encryption in Microsoft 365 - ExpertsLive Netherlands 2024Encryption in Microsoft 365 - ExpertsLive Netherlands 2024
Encryption in Microsoft 365 - ExpertsLive Netherlands 2024
Albert Hoitingh
 
GraphSummit Singapore | Graphing Success: Revolutionising Organisational Stru...
GraphSummit Singapore | Graphing Success: Revolutionising Organisational Stru...GraphSummit Singapore | Graphing Success: Revolutionising Organisational Stru...
GraphSummit Singapore | Graphing Success: Revolutionising Organisational Stru...
Neo4j
 

Recently uploaded (20)

Pushing the limits of ePRTC: 100ns holdover for 100 days
Pushing the limits of ePRTC: 100ns holdover for 100 daysPushing the limits of ePRTC: 100ns holdover for 100 days
Pushing the limits of ePRTC: 100ns holdover for 100 days
 
GDG Cloud Southlake #33: Boule & Rebala: Effective AppSec in SDLC using Deplo...
GDG Cloud Southlake #33: Boule & Rebala: Effective AppSec in SDLC using Deplo...GDG Cloud Southlake #33: Boule & Rebala: Effective AppSec in SDLC using Deplo...
GDG Cloud Southlake #33: Boule & Rebala: Effective AppSec in SDLC using Deplo...
 
Monitoring Java Application Security with JDK Tools and JFR Events
Monitoring Java Application Security with JDK Tools and JFR EventsMonitoring Java Application Security with JDK Tools and JFR Events
Monitoring Java Application Security with JDK Tools and JFR Events
 
Essentials of Automations: The Art of Triggers and Actions in FME
Essentials of Automations: The Art of Triggers and Actions in FMEEssentials of Automations: The Art of Triggers and Actions in FME
Essentials of Automations: The Art of Triggers and Actions in FME
 
GraphSummit Singapore | The Future of Agility: Supercharging Digital Transfor...
GraphSummit Singapore | The Future of Agility: Supercharging Digital Transfor...GraphSummit Singapore | The Future of Agility: Supercharging Digital Transfor...
GraphSummit Singapore | The Future of Agility: Supercharging Digital Transfor...
 
DevOps and Testing slides at DASA Connect
DevOps and Testing slides at DASA ConnectDevOps and Testing slides at DASA Connect
DevOps and Testing slides at DASA Connect
 
Climate Impact of Software Testing at Nordic Testing Days
Climate Impact of Software Testing at Nordic Testing DaysClimate Impact of Software Testing at Nordic Testing Days
Climate Impact of Software Testing at Nordic Testing Days
 
Why You Should Replace Windows 11 with Nitrux Linux 3.5.0 for enhanced perfor...
Why You Should Replace Windows 11 with Nitrux Linux 3.5.0 for enhanced perfor...Why You Should Replace Windows 11 with Nitrux Linux 3.5.0 for enhanced perfor...
Why You Should Replace Windows 11 with Nitrux Linux 3.5.0 for enhanced perfor...
 
20240607 QFM018 Elixir Reading List May 2024
20240607 QFM018 Elixir Reading List May 202420240607 QFM018 Elixir Reading List May 2024
20240607 QFM018 Elixir Reading List May 2024
 
A tale of scale & speed: How the US Navy is enabling software delivery from l...
A tale of scale & speed: How the US Navy is enabling software delivery from l...A tale of scale & speed: How the US Navy is enabling software delivery from l...
A tale of scale & speed: How the US Navy is enabling software delivery from l...
 
GraphRAG is All You need? LLM & Knowledge Graph
GraphRAG is All You need? LLM & Knowledge GraphGraphRAG is All You need? LLM & Knowledge Graph
GraphRAG is All You need? LLM & Knowledge Graph
 
State of ICS and IoT Cyber Threat Landscape Report 2024 preview
State of ICS and IoT Cyber Threat Landscape Report 2024 previewState of ICS and IoT Cyber Threat Landscape Report 2024 preview
State of ICS and IoT Cyber Threat Landscape Report 2024 preview
 
FIDO Alliance Osaka Seminar: FIDO Security Aspects.pdf
FIDO Alliance Osaka Seminar: FIDO Security Aspects.pdfFIDO Alliance Osaka Seminar: FIDO Security Aspects.pdf
FIDO Alliance Osaka Seminar: FIDO Security Aspects.pdf
 
Generative AI Deep Dive: Advancing from Proof of Concept to Production
Generative AI Deep Dive: Advancing from Proof of Concept to ProductionGenerative AI Deep Dive: Advancing from Proof of Concept to Production
Generative AI Deep Dive: Advancing from Proof of Concept to Production
 
LF Energy Webinar: Electrical Grid Modelling and Simulation Through PowSyBl -...
LF Energy Webinar: Electrical Grid Modelling and Simulation Through PowSyBl -...LF Energy Webinar: Electrical Grid Modelling and Simulation Through PowSyBl -...
LF Energy Webinar: Electrical Grid Modelling and Simulation Through PowSyBl -...
 
Uni Systems Copilot event_05062024_C.Vlachos.pdf
Uni Systems Copilot event_05062024_C.Vlachos.pdfUni Systems Copilot event_05062024_C.Vlachos.pdf
Uni Systems Copilot event_05062024_C.Vlachos.pdf
 
Smart TV Buyer Insights Survey 2024 by 91mobiles.pdf
Smart TV Buyer Insights Survey 2024 by 91mobiles.pdfSmart TV Buyer Insights Survey 2024 by 91mobiles.pdf
Smart TV Buyer Insights Survey 2024 by 91mobiles.pdf
 
Introduction to CHERI technology - Cybersecurity
Introduction to CHERI technology - CybersecurityIntroduction to CHERI technology - Cybersecurity
Introduction to CHERI technology - Cybersecurity
 
Encryption in Microsoft 365 - ExpertsLive Netherlands 2024
Encryption in Microsoft 365 - ExpertsLive Netherlands 2024Encryption in Microsoft 365 - ExpertsLive Netherlands 2024
Encryption in Microsoft 365 - ExpertsLive Netherlands 2024
 
GraphSummit Singapore | Graphing Success: Revolutionising Organisational Stru...
GraphSummit Singapore | Graphing Success: Revolutionising Organisational Stru...GraphSummit Singapore | Graphing Success: Revolutionising Organisational Stru...
GraphSummit Singapore | Graphing Success: Revolutionising Organisational Stru...
 

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; }

Editor's Notes

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