REFACTOR: break down the logic into dedicated methods, tests cleaned up
This commit is contained in:
parent
8474b20e85
commit
a93a6abb28
2 changed files with 88 additions and 33 deletions
|
|
@ -1,35 +1,58 @@
|
|||
class BowlingGame {
|
||||
static const _totalFrames = 10;
|
||||
static const _allPins = 10;
|
||||
static const _rollsInNormalFrame = 2;
|
||||
static const _rollsInStrike = 1;
|
||||
|
||||
final List<int> _rolls = [];
|
||||
|
||||
void roll(int pins) {
|
||||
_rolls.add(pins);
|
||||
}
|
||||
void roll(int pins) => _rolls.add(pins);
|
||||
|
||||
int score() {
|
||||
int totalScore = 0;
|
||||
int total = 0;
|
||||
int rollIndex = 0;
|
||||
|
||||
for (int frame = 0; frame < 10; frame++) {
|
||||
for (int frame = 0; frame < _totalFrames; frame++) {
|
||||
if (_isStrike(rollIndex)) {
|
||||
totalScore += 10 + _rolls[rollIndex + 1] + _rolls[rollIndex + 2];
|
||||
rollIndex += 1;
|
||||
total += _strikeScore(rollIndex);
|
||||
rollIndex += _rollsInStrike;
|
||||
} else if (_isSpare(rollIndex)) {
|
||||
totalScore += 10 + _rolls[rollIndex + 2];
|
||||
rollIndex += 2;
|
||||
total += _spareScore(rollIndex);
|
||||
rollIndex += _rollsInNormalFrame;
|
||||
} else {
|
||||
totalScore += _rolls[rollIndex] + _rolls[rollIndex + 1];
|
||||
rollIndex += 2;
|
||||
total += _normalScore(rollIndex);
|
||||
rollIndex += _rollsInNormalFrame;
|
||||
}
|
||||
}
|
||||
|
||||
return totalScore;
|
||||
return total;
|
||||
}
|
||||
|
||||
int _strikeScore(int rollIndex) {
|
||||
return _allPins + _nextTwoRollsBonus(rollIndex);
|
||||
}
|
||||
|
||||
int _spareScore(int rollIndex) {
|
||||
return _allPins + _nextRollBonus(rollIndex);
|
||||
}
|
||||
|
||||
int _normalScore(int rollIndex) {
|
||||
return _rolls[rollIndex] + _rolls[rollIndex + 1];
|
||||
}
|
||||
|
||||
int _nextTwoRollsBonus(int rollIndex) {
|
||||
return _rolls[rollIndex + 1] + _rolls[rollIndex + 2];
|
||||
}
|
||||
|
||||
int _nextRollBonus(int rollIndex) {
|
||||
return _rolls[rollIndex + 2];
|
||||
}
|
||||
|
||||
bool _isSpare(int rollIndex) {
|
||||
return _rolls[rollIndex] + _rolls[rollIndex + 1] == 10;
|
||||
return _rolls[rollIndex] + _rolls[rollIndex + 1] == _allPins;
|
||||
}
|
||||
|
||||
bool _isStrike(int rollIndex) {
|
||||
return _rolls[rollIndex] == 10;
|
||||
return _rolls[rollIndex] == _allPins;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ import 'package:tdd_katas/bowling_game.dart';
|
|||
import 'package:test/test.dart';
|
||||
|
||||
void main() {
|
||||
group('Bowling Game', () {
|
||||
group('Bowling Game Scoring', () {
|
||||
late BowlingGame game;
|
||||
|
||||
setUp(() {
|
||||
|
|
@ -15,32 +15,64 @@ void main() {
|
|||
}
|
||||
}
|
||||
|
||||
test('gutter game - all zeros', () {
|
||||
group('Basic Scoring', () {
|
||||
test('gutter game - no pins knocked', () {
|
||||
rollMany(20, 0);
|
||||
expect(game.score(), 0);
|
||||
});
|
||||
|
||||
test('all ones - score is 20', () {
|
||||
test('all ones - simple addition', () {
|
||||
rollMany(20, 1);
|
||||
expect(game.score(), 20);
|
||||
});
|
||||
});
|
||||
|
||||
test('one spare', () {
|
||||
group('Spare Bonus (next 1 roll)', () {
|
||||
test('one spare in first frame', () {
|
||||
game.roll(5);
|
||||
game.roll(5); // spare
|
||||
game.roll(3); // bonus for spare
|
||||
rollMany(17, 0); // rest are gutter balls
|
||||
rollMany(17, 0);
|
||||
|
||||
expect(game.score(), 16); // 10 (spare) + 3 (bonus) + 3 (normal roll)
|
||||
expect(game.score(), 16); // 10 + 3 (bonus) + 3
|
||||
});
|
||||
|
||||
test('one strike', () {
|
||||
test('all spares with 5 pins each', () {
|
||||
rollMany(21, 5); // 10 frames of 5,5 + 1 bonus roll
|
||||
expect(game.score(), 150);
|
||||
});
|
||||
});
|
||||
|
||||
group('Strike Bonus (next 2 rolls)', () {
|
||||
test('one strike in first frame', () {
|
||||
game.roll(10); // Strike!
|
||||
game.roll(3);
|
||||
game.roll(4); // Next 2 rolls are bonus
|
||||
rollMany(16, 0);
|
||||
|
||||
expect(game.score(), 24); // 10 + 3 + 4 (strike) + 3 + 4 (frame 2) = 24
|
||||
expect(game.score(), 24); // 10 + 3 + 4 (bonus) + 7
|
||||
});
|
||||
|
||||
test('perfect game - twelve consecutive strikes', () {
|
||||
rollMany(12, 10);
|
||||
expect(game.score(), 300);
|
||||
});
|
||||
});
|
||||
|
||||
group('Complex Scenarios', () {
|
||||
test('combination of strikes, spares, and normal frames', () {
|
||||
game.roll(10); // Frame 1: Strike
|
||||
game.roll(5);
|
||||
game.roll(5); // Frame 2: Spare
|
||||
game.roll(7);
|
||||
game.roll(2); // Frame 3: Normal
|
||||
rollMany(15, 0);
|
||||
|
||||
// Frame 1: 10 + 5 + 5 = 20
|
||||
// Frame 2: 10 + 7 = 17
|
||||
// Frame 3: 7 + 2 = 9
|
||||
expect(game.score(), 46);
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue