Create a gist now

Instantly share code, notes, and snippets.

Array.prototype.foldLeft = function(seed, f) {
var accumulation = seed;
for(var i=0; i < this.length; ++i) {
accumulation = f(accumulation, this[i]);
}
return accumulation;
}
Number.prototype.times = function(f) {
for(var i=0; i < this; ++i) {
f();
}
return this;
};
function range(start, end) {
var values = []
for(var i=start; i <= end; ++i) {
values.push(i);
}
return values;
}
BowlingGame = function() {
var scope = this;
scope.rolls = [];
scope.roll = function(bowl) {
scope.rolls.push(bowl);
if(bowl === 10 && isFirstThrowOfFrame())
scope.rolls.push(undefined);
};
scope.score = function() {
return range(1,10).foldLeft(0, function(total, frame){
return total + scoreForFrame(frame);
});
};
function isFirstThrowOfFrame() {
return scope.rolls.length % 2 !== 0;
}
function scoreForFrame(frame) {
if(hasStrike(frame)) return normalScoreFor(frame) + nextTwoThrows(frame);
if(hasSpare(frame)) return normalScoreFor(frame) + firstThrowFor(frame + 1);
return normalScoreFor(frame);
};
function nextTwoThrows(frame) {
if(hasStrike(frame + 1)) {
return firstThrowFor(frame + 1) + firstThrowFor(frame + 2);
}
return normalScoreFor(frame + 1);
}
function normalScoreFor(frame) {
return firstThrowFor(frame) + secondThrowFor(frame) ;
}
function hasSpare(frame) {
return firstThrowFor(frame) + secondThrowFor(frame) === 10;
}
function hasStrike(frame) {
return firstThrowFor(frame) === 10;
}
function firstThrowFor(frame) {
return scoreAtThrow(indexForFrame(frame));
}
function secondThrowFor(frame) {
return scoreAtThrow(indexForFrame(frame) + 1);
}
function scoreAtThrow(index) {
return scope.rolls[index] || 0;
}
function indexForFrame(frame) {
return (frame - 1) * 2;
}
return scope;
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment