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 it's 5:00 and we need to go home. Let's ignore this test for now and add 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.
We come back to work the next day ready to tackle the "spare" problem. We can pick right back up where we left off by running the tests and seeing the comment.
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.
We can remove the Ignore attribute and run the tests. 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.
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 tests.
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.