Skip to content

Instantly share code, notes, and snippets.

@alexander-williamson
Last active September 10, 2019 22:25
Show Gist options
  • Save alexander-williamson/2ae91c8f51a7815363c2784a9e9c7dfd to your computer and use it in GitHub Desktop.
Save alexander-williamson/2ae91c8f51a7815363c2784a9e9c7dfd to your computer and use it in GitHub Desktop.
Javascript Bowling Kata
function bowlingScore(frames) {
const rolls = frames.split("").filter(function(value, index) { return value != " " });
var frames = getFramesFromRolls(rolls);
var score = calculateScoreFromFrames(rolls, frames);
return score;
}
function getFramesFromRolls(rolls) {
if (rolls === undefined || rolls.length == 0) { return []; }
var frames= [];
var frame = new Frame(0);
for(var i = 0; i < rolls.length; i++)
{
if(frames.length < 9) {
frame.addRoll(i);
if(frame.getRolls().length == 2 || hasSpare(rolls, frame.getRolls()) || hasStrike(rolls, frame.getRolls())) {
frames.push(frame);
frame = new Frame(frames.length);
}
} else {
// final frame
frame.addRoll(i);
}
}
frames.push(frame);
return frames;
}
function calculateScoreFromFrames(rolls, frames) {
if (frames === undefined || frames.length == 0) { return []; }
for(var i = 0; i < frames.length; i++)
{
var frame = frames[i];
if(i < 9) {
var rollValuesInThisFrame = getRollValues(rolls, frame.getRolls());
var score = getScoresFromRollValues(rollValuesInThisFrame);
var firstRollPosition = frame.getRolls()[0];
var futures = [];
var spare = hasSpare(rolls, frame.getRolls());
var strike = hasStrike(rolls, frame.getRolls());
var bonus = 0;
if(strike) {
if(rolls[firstRollPosition + 1] !== undefined) futures.push(firstRollPosition + 1);
if(rolls[firstRollPosition + 2] !== undefined) futures.push(firstRollPosition + 2);
}
else if(spare) {
if(rolls[firstRollPosition + 2] !== undefined) futures.push(firstRollPosition + 2);
}
if(futures.length > 0) {
bonus = getScoresFromRollValues(getRollValues(rolls, futures));
}
frame.setBonus(bonus);
frame.setScore(score);
} else {
var rollValuesInThisFrame = getRollValues(rolls, frame.getRolls());
var score = getScoresFromRollValues(rollValuesInThisFrame);
frame.setBonus(0);
frame.setScore(score);
}
}
var result = frames
.map(function(r) { return r.getTotal(); })
.reduce(function(a,b) { return a + b; });
return result;
}
function hasSpare(rolls, positions) {
return getRollValues(rolls, positions).includes("/");
}
function hasStrike(rolls, positions) {
return getRollValues(rolls, positions).includes("X");
}
function getRollValues(rolls, positions) {
return positions.map(function(i) { return rolls[i]; });
}
function getScoresFromRollValues(values) {
return values
.map(function(element, index) {
if(element == "X") { return 10; }
if(element == "/") { return 10 - parseInt(values[index - 1]); } // hack
if(values[index + 1] == undefined) { return parseInt(element); }
return parseInt(element);
})
.reduce(function(a,b) { return a + b; });
}
class Frame {
constructor(id)
{
this.rolls = [];
this.bonus = 0;
this.score = 0;
this.id = id;
};
setBonus(value) { this.bonus = value; }
setScore(value) { this.score = value; }
getTotal() { return this.score + this.bonus; }
addRoll(roll) { this.rolls.push(roll); }
getRolls() { return this.rolls; }
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment