-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathbowling.js
69 lines (54 loc) · 2.11 KB
/
bowling.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
'use strict';
function Bowling(rolls) {
this.rolls = rolls;
}
Bowling.prototype.score = function() {
var initialState = {
frameNumber: 1,
rollNumber: 1,
pinsRemaining: 10,
spareLastFrame: false,
strikeLastFrame: false,
twoStrikesInARow: false,
fillBall: false,
score: 0
};
var finalState = this.rolls.reduce(function(state, roll) {
if (roll < 0 || roll > 10) {
throw new Error('Pins must have a value from 0 to 10');
}
if (roll > state.pinsRemaining) {
throw new Error('Pin count exceeds pins on the lane');
}
if (state.frameNumber > 10) {
throw new Error('Should not be able to roll after game is over');
}
var finalFrame = state.frameNumber === 10;
var strike = state.rollNumber === 1 && roll === 10;
var spare = state.rollNumber === 2 && roll === state.pinsRemaining;
var frameOver = finalFrame
? (!state.fillBall && !spare && state.rollNumber === 2) || state.rollNumber === 3
: strike || spare || state.rollNumber === 2;
var score = state.score + roll;
if (state.strikeLastFrame && state.rollNumber < 3) { score += roll; }
if (state.spareLastFrame && state.rollNumber === 1) { score += roll; }
if (state.twoStrikesInARow && state.rollNumber === 1) { score += roll; }
var next = {};
next.frameNumber = frameOver ? state.frameNumber + 1 : state.frameNumber;
next.rollNumber = frameOver ? 1: state.rollNumber + 1;
next.pinsRemaining = finalFrame
? ((strike || spare) ? 10 : state.pinsRemaining - roll)
: (frameOver ? 10 : state.pinsRemaining - roll);
next.spareLastFrame = frameOver ? spare : state.spareLastFrame;
next.strikeLastFrame = frameOver ? strike : state.strikeLastFrame;
next.twoStrikesInARow = frameOver ? strike && state.strikeLastFrame : state.twoStrikesInARow;
next.fillBall = next.fillBall || (finalFrame && (strike || spare));
next.score = score;
return next;
}, initialState);
if (finalState.frameNumber !== 11) {
throw new Error('Score cannot be taken until the end of the game');
}
return finalState.score;
};
module.exports = Bowling;