This is a paired-programming exercise.
The goal of this activity is to practice the red-green-refactor cycle:
RED: You must add a new test or some new code to an ongoing test, which causes the test to fail.GREEN: You must add the code needed to make the failing test pass.REFACTOR: You must clean up the code, including test code, to make them more readable; must do before moving on to writing the next test.Use the red-green-refactor prop as you work through this activity to help you internalize the process.
General Rules to follow (TDD Rules):
| Frame | Roll 1 | Roll 2 | Special | Extra Points | Frame Score | Game Score |
|---|---|---|---|---|---|---|
| 1 | 1 | 4 | 0 | 5 | 5 | |
| 2 | 4 | 5 | 0 | 9 | 14 | |
| 3 | 6 | 4 | Spare | 5 | 15 | 29 |
| 4 | 5 | 5 | Spare | 10 | 20 | 49 |
| 5 | 10 | Strike | 1 | 11 | 60 | |
| 6 | 0 | 1 | 0 | 1 | 61 | |
| 7 | 7 | 3 | Spare | 6 | 16 | 77 |
| 8 | 6 | 4 | Spare | 10 | 20 | 97 |
| 9 | 10 | Strike | 10 | 20 | 117 | |
| 10 | 2 | 8 | Spare | 6 | 16 | 133 |
| 6 | 133 |
| Frame | Roll 1 | Roll 2 | Special | Extra Points | Frame Score | Game Score |
|---|---|---|---|---|---|---|
| 1 | 10 | Strike | 20 | 30 | 30 | |
| 2 | 10 | Strike | 20 | 30 | 60 | |
| 3 | 10 | Strike | 20 | 30 | 90 | |
| 4 | 10 | Strike | 20 | 30 | 120 | |
| 5 | 10 | Strike | 20 | 30 | 150 | |
| 6 | 10 | Strike | 20 | 30 | 180 | |
| 7 | 10 | Strike | 20 | 30 | 210 | |
| 8 | 10 | Strike | 20 | 30 | 240 | |
| 9 | 10 | Strike | 20 | 30 | 270 | |
| 10 | 10 | Strike | 20 | 30 | 300 | |
| 10 | 10 | 300 |
These are the steps (as represented by test cases) that you will be going through to develop the bowling game scorer.
REDBowlingTest.java class in the test directory.nothing() test with the @Test annotation.GREENorg.junit.test.REFACTORREDnothing test to canCreateGame.Game g = new Game(); line to the test.GREENGame.REFACTORREDcanCreateGame test to canRoll.g.roll(0); to the test.GREENroll in Game.pins.REFACTORREDgutterGame test.g, then roll twenty zeroes (for loop).GREENassertEquals to import the static method from org.junit.score to create a score method in Game.REFACTORGame g variable, and have it initialized in the setUp method.g variable from any of the tests, so that the field variable is used.canRoll test.Exception to remove the unneeded throws Exception.REDallOnes test.assertEquals(20, g.score());.GREENGame, create a field score, initialize it to 0, and return it in the score method.roll method, increment the score by the pins.REFACTORgutterGame test, perform Extract Variable on the 0 within the roll, to variable pins. Move it above the loop.20 in the loop, to variable n.rollMany, place parameters in order n, pins, and replace duplicates.gutterGame test, perform Inline on the local variables n and pins.rollMany method, to the Game class.PRE-REFACTORrolls in Game, to store array of ints. Initialize it to an array of length 21.currentRoll in Game, initialized to 0. Delete the score field.roll method, add the pins to the currentRoll spot in the rolls array, and increment currentRoll. Remove the score increment.score method, loop over the rolls array up to the currentRoll, and accumulate the values in a local variable score, then return that variable.for loop in score so that it loops over 10 frames. Create a local firstInFrame variable starting at 0. For each frame add to the score the value of rolls at firstInFrame and firstInFrame + 1, then increment firstInFrame by 2.REDoneSpare test, on which you roll 5, 5 and 3, then roll 17 zeroes (using rollMany).GREENrolls[firstInFrame] + rolls[firstInFrame + 1] equals 10. If it is, increment the score by 10 + rolls[firstInFrame + 2] then increment firstInFrame by 2.REFACTORif into a method isSpare.rollSpare method.REDoneStrike test, on which you roll 10, then 3 and 4, then 17 zeroes.GREENrolls[firstInFrame] equals 10. Place an else before the next if.score by 10 plus rolls[firstInFrame + 1] + rolls[firstInFrame + 2], then increment firstInFrame by 1.REFACTORisStrike method (don’t fold parameters).rolls[firstInFrame + 1] + rolls[firstInFrame + 2] part of the strike conditional branch into a nextTwoBallsForStrike method.rolls[firstInFrame + 2] part of the spare conditional branch into a nextBallForSpare method (don’t process duplicates).rolls[firstInFrame] + rolls[firstInFrame + 1]; part of the normal frame part into a twoBallsInFrame method.REDperfectGame test, on which you roll twelve 10s.GREENREFACTOR