If bowling was scored just by knocking down pins, our job would be easy. The first special case is the game where you knock down a few pins on your first throw and then knock down the rest on the next throw. This is called a "spare".
When you make a spare, you darken half the score box. You also get a bonus. You take the 10 pins you knocked down in the frame and add the amount of the first roll in the next frame.
In our example above: 10 + 3 = 13. The rest of the game is scored normally.
Let's compile and run the test.
1 test failed "Expected 16 but was 13"
We didn't get our bonus. Our code has no concept of keeping track of frames and adding a bonus to an earlier score.
We need to fix this, but we don't want to break our earlier code. Let's make this test assert inconclusive with a message. That way we can check-in our code, leave work for the day, and not break the build.
Now when we run the tests we see yellow.
Inconclusive: A game with a spare is not giving the bonus.
Right now our Game is using a variable to hold the score. This score is now conditional on the need to add a bonus. Looking at Uncle Bob's Priority Premise the next step after the use of a variable is an unconditional statement.
Let's start by adding the unconditional statement of keeping track of every roll in every frame.
This code passes our existing tests, but it still fails to give a bonus to a spare.
The next step in Uncle Bob's Priority Premise is an "if" statement. We wrote unconditional statements in the form of for loops, now we need a conditional statement to determine if the frame had a spare.
Now we take out the inconclusive assertion and run the tests.
3 tests passed
Our tests are passing, it's time to refactor.
The line "if (rolls[roll] + rolls[roll + 1] == 10)" means we rolled a spare. Let's extract a method that tells us this.
We compile and run the after refactoring.
3 tests passed
Looking at our test we see that these two lines simulate rolling a spare:
Again, we extract these two lines out to a method.