In my last post, I presented an enhancement to a "bowling score calculator" problem being discussed on the Extreme Programming Mailing List. My solution extended a not-very-OO
solution presented here; though not object oriented, it was short and clear. I generally write intensively OO code, so I found this interesting.
A contention on the list, though, was that the procedural solution could not be extended to support more features easily. Today I’d added even more features, just to see if this is true:
- Know how many pins are standing, and prevent the caller from knocking down
more pins than are up.
- Know which rolls occurred in which frame; be able to answer "what were
the rolls in frame N?"
- Present an HTML representation of the state of the game after each roll.
As usual, I added this features a test at a time a bit at a time. It turned out to be easy to keep track of which rolls go in which frame. The updated source code can be downloaded: bowling-java-3c.tgz and is also on github. As before the download includes the tests also. I’ve renamed a few things for greater clarity. (I’ve updated the file a couple of times since posting it, to fix a problem in the final output, and separate some tests I had combined.)
I was surprised to find that adding these features didn’t add much complexity to the code. When I look at this code, it cries out to have a class of some kind extracted – but I’ve tried extracting, for example, the idea of a Frame and been unsatisfied. Perhaps I’ll explore that more another day. These variable:
private int[] frameScores = new int[NUM_FRAMES];
private int[] firstRollInFrame = new int[NUM_FRAMES + 1];
private int scoredFrame;
private int finishedFrame;
could form the starting point for that, like so:
class Frame {
private int score;
private int firstRoll;
private boolean scored;
private boolean finished;
}
The Game class is in its entirety is
available here (syntax highlighted HTML) or in the download above.
I implemented the HTML rendering of frames without aid of test cases. The code is included
in the download above, and produces output like the sample run below. The output looks
much better when not included inside a WordPress post – the sample below is
partially mangled.
The main
loop of the demo program biases the random numbers toward high scores:
while (!game.gameOver()) {
// Bias our guy toward good rolls:
int n = rnd.nextInt(game.pinsStanding() + 4);
int pins = Math.min(n, game.pinsStanding());
renderer.tellAboutPins(pins);
game.roll(pins);
renderer.printGame(game);
}
Rolling… 7 pins
Rolling… 3 pins
Rolling… 10 pins
Rolling… 4 pins
Rolling… 2 pins
Rolling… 10 pins
Rolling… 0 pins
Rolling… 3 pins
Rolling… 10 pins
Rolling… 3 pins
Rolling… 5 pins
Rolling… 10 pins
Rolling… 4 pins
Rolling… 0 pins
20
|
36
|
42
|
55
|
58
|
76
|
84
|
98
|
102
|
|
Rolling… 1 pins
20
|
36
|
42
|
55
|
58
|
76
|
84
|
98
|
102
|
|
Rolling… 1 pins
20
|
36
|
42
|
55
|
58
|
76
|
84
|
98
|
102
|
104
|
Comments welcome, via email (address below).