Skip to content

Commit

Permalink
Finished scoring for all categories
Browse files Browse the repository at this point in the history
  • Loading branch information
andrearonsen committed Dec 8, 2011
1 parent e46fc1d commit dd2849b
Show file tree
Hide file tree
Showing 3 changed files with 215 additions and 50 deletions.
1 change: 1 addition & 0 deletions README
@@ -0,0 +1 @@
Playing with the brand new buster.js and doing the Yahtzee kata.
151 changes: 122 additions & 29 deletions lib/scoring.js
Expand Up @@ -2,28 +2,128 @@ var YAHTZEE = this.YAHTZEE || {};

(function () {
"use strict";

var oneToSixMap = { One: 1, Two: 2, Three: 3, Four: 4, Five: 5, Six: 6 };

var oneToSixStrategy = {
var strategy = (function () {
var strategies = [];

function simpleNameMatcher(category) {
return function (matchCategory) {
return category === matchCategory;
};
};

var strategy_if = {};

var nullStrategy = {
match: function (category) { return true; },
calculate: function (roll) { return 0; }
};

strategy_if.add = function (name, spec) {
var newStrategy = {
name: name,
calculate: spec.calculate,
match: nullStrategy.match
};

if (spec.match) {
newStrategy.match = spec.match;
} else if (name) {
newStrategy.match = simpleNameMatcher(name);
}

strategies.push(newStrategy);
};

strategy_if.find = function (category) {
var matches = strategies.filter(function (s) {
return s.match(category);
});
return matches.length > 0? matches[0] : nullStrategy;
};

strategy_if.oneToSixMap = { One: 1, Two: 2, Three: 3, Four: 4, Five: 5, Six: 6 };

return strategy_if;
}());

strategy.add("One to Six", {
match: function (category) {
this.category = category;
return oneToSixMap[category]? true : false
return strategy.oneToSixMap[category]? true : false;
},
calculate: function (roll) {
return addElementsOfKind(roll, oneToSixMap[this.category]);
return sumElementsOfKind(roll, strategy.oneToSixMap[this.category]);
}
};
});

strategy.add("Pair", {
calculate: function (roll) {
return findSumHighestRepeatedNumber(roll, 2);
}
});

strategy.add("TwoPairs", {
calculate: function (roll) {
var repnum = findRepeatedNumbers(roll, 2);
if (repnum.length === 1 && repnum[0].count === 4) {
return repnum[0].dice * 4;
}
return repnum.length === 2? repnum[0].dice * 2 + repnum[1].dice * 2 : 0;
}
});

strategy.add("ThreeOfAKind", {
calculate: function (roll) {
return findSumHighestRepeatedNumber(roll, 3);
}
});

strategy.add("FourOfAKind", {
calculate: function (roll) {
return findSumHighestRepeatedNumber(roll, 4);
}
});

strategy.add("SmallStraight", {
calculate: function (roll) {
return rollEquals(roll, [1,2,3,4,5])? 15 : 0;
}
});

var scoreStrategies = [
oneToSixStrategy
];
strategy.add("LargeStraight", {
calculate: function (roll) {
return rollEquals(roll, [2,3,4,5,6])? 20 : 0;
}
});

strategy.add("FullHouse", {
calculate: function (roll) {
var repnum2 = findRepeatedNumbers(roll, 2).filter(function (r) { return r.count === 2; });
var repnum3 = findRepeatedNumbers(roll, 3).filter(function (r) { return r.count === 3; });
if (repnum2.length !== 1 || repnum3.length !== 1 || repnum2[0].dice === repnum3[0].dice) return 0;

return repnum2[0].dice * 2 + repnum3[0].dice * 3;
}
});

strategy.add("Yahtzee", {
calculate: function (roll) {
return allElementsAreEqual(roll)? 50 : 0;
}
});

strategy.add("Chance", {
calculate: function (roll) {
return roll.reduce(add, 0);
}
});

function add(a, b) {
return a + b;
}

function addElementsOfKind(roll, kind) {
function sumElementsOfKind(roll, kind) {
return roll.filter(function (element) {
return element === kind;
}).reduce(add, 0);
Expand All @@ -50,33 +150,26 @@ var YAHTZEE = this.YAHTZEE || {};
return true;
}

function findRepeatedNumber(roll, count) {
var repeated = [1,2,3,4,5,6].map(function (x) {
function findRepeatedNumbers(roll, count) {
return [6,5,4,3,2,1].map(function (x) {
return {
dice: x,
count: roll.filter(function (el) { return el === x; }).length
};
}).filter(function (c) { return c.count === count; });
}).filter(function (c) { return c.count >= count; });
}

return repeated.length === 1? repeated[0].dice : 0;
function findHighestRepeatedNumber(roll, count) {
var repeated = findRepeatedNumbers(roll, count);
return repeated.length >= 1? repeated[0].dice : 0;
}

function calculateScore(roll, category) {
if (oneToSixStrategy.match(category)) {
return oneToSixStrategy.calculate(roll);
} else if (category === "Yahtzee") {
return allElementsAreEqual(roll)? 50 : 0;
} else if (category === "Chance") {
return roll.reduce(add, 0);
} else if (category === "SmallStraight") {
return rollEquals(roll, [1,2,3,4,5])? 15 : 0;
} else if (category === "LargeStraight") {
return rollEquals(roll, [2,3,4,5,6])? 20 : 0;
} else if (category === "FourOfAKind") {
return findRepeatedNumber(roll, 4) * 4;
}
function findSumHighestRepeatedNumber(roll, count) {
return findHighestRepeatedNumber(roll, count) * count;
}

return undefined;
function calculateScore(roll, category) {
return strategy.find(category).calculate(roll);
}

YAHTZEE.scoring = {
Expand Down
113 changes: 92 additions & 21 deletions test/scoring-test.js
Expand Up @@ -15,100 +15,171 @@ var scoring = require("../lib/scoring");
});

buster.testCase('Scoring One - Six', {
"should calculate score 5 for roll [1,1,1,1,2] placed on One]": function () {
"should calculate score 5 for roll [1,1,1,1,2]]": function () {
assert.score([1,1,1,1,2], "One", 4);
},

"should calculate score 10 for roll [2,2,2,2,3] placed on Two": function () {
"should calculate score 10 for roll [2,2,2,2,3]": function () {
assert.score([2,2,2,2,3], "Two", 8);
},

"should calculate score 2 for roll [1,1,2,3,4] placed on One]": function () {
"should calculate score 2 for roll [1,1,2,3,4]]": function () {
assert.score([1,1,2,3,4], "One", 2);
},

"should calculate score 4 for roll [2,2,3,4,5] placed on Two": function () {
"should calculate score 4 for roll [2,2,3,4,5]": function () {
assert.score([2,2,3,4,5], "Two" , 4);
},

"should calculate score 9 for roll [3,3,3,4,5] placed on Three": function () {
"should calculate score 9 for roll [3,3,3,4,5]": function () {
assert.score([3,3,3,4,5], "Three", 9);
},

"should calculate score 4 for roll [4,1,2,3,5] placed on Four": function () {
"should calculate score 4 for roll [4,1,2,3,5]": function () {
assert.score([4,1,2,3,5], "Four", 4);
},

"should calculate score 15 for roll [5,5,1,2,3] placed on Five": function () {
"should calculate score 15 for roll [5,5,1,2,3]": function () {
assert.score([5,5,1,2,3], "Five", 10);
},

"should calculate score 12 for roll [1,6,1,6,1] placed on Six": function () {
"should calculate score 12 for roll [1,6,1,6,1]": function () {
assert.score([1,6,1,6,1], "Six", 12);
},

"should calculate score 0 for roll [1,2,3,4,4] placed on Five": function () {
"should calculate score 0 for roll [1,2,3,4,4]": function () {
assert.score([1,2,3,4,4], "Five", 0);
}
});

buster.testCase("Scoring Yahtzee", {
"should calculate score 50 for roll [1,1,1,1,1] placed on Yahtzee]": function () {
"should calculate score 50 for roll [1,1,1,1,1]]": function () {
assert.score([1,1,1,1,1], "Yahtzee", 50);
},

"should calculate score 0 for roll [1,2,3,4,5] placed on Yahtzee": function () {
"should calculate score 0 for roll [1,2,3,4,5]": function () {
assert.score([1,2,3,4,5], "Yahtzee", 0);
}
});

buster.testCase("Scoring Chance", {
"should calculate score 30 for roll [6,6,6,6,6] placed on Chance": function () {
"should calculate score 30 for roll [6,6,6,6,6]": function () {
assert.score([6,6,6,6,6], "Chance", 30);
},

"should calculate score 15 for roll [1,2,3,4,5] placed on Chance": function () {
"should calculate score 15 for roll [1,2,3,4,5]": function () {
assert.score([1,2,3,4,5], "Chance", 15);
}
});

buster.testCase("Scoring SmallStraight", {
"should calculate score 15 for small straight placed on SmallStraight": function () {
"should calculate score 15 for small straight": function () {
assert.score([1,2,3,4,5], "SmallStraight", 15);
},

"should calculate score 0 when not small straight placed on SmallStraight": function () {
"should calculate score 0 when not small straight": function () {
assert.score([1,2,3,4,4], "SmallStraight", 0);
}
});

buster.testCase("Scoring LargeStraight", {
"should calculate score 20 for large straight placed on LargeStraight": function () {
"should calculate score 20 for large straight": function () {
assert.score([2,3,4,5,6], "LargeStraight", 20);
},

"should calculate score 0 when not large straight placed on LargeStraight": function () {
"should calculate score 0 when not large straight": function () {
assert.score([2,3,4,5,1], "LargeStraight", 0);
}
});

buster.testCase("Scoring FourOfAKind", {
"should calculate score 4 for roll [1,1,1,1,x] when placed on FourOfAKind": function () {
"should calculate score 4 for roll [1,1,1,1,x]": function () {
assert.score([1,1,1,1,6], "FourOfAKind", 4);
},

"should calculate score 8 for roll [2,2,2,2,x] when placed on FourOfAKind": function () {
"should calculate score 8 for roll [2,2,2,2,x]": function () {
assert.score([2,2,2,2,6], "FourOfAKind", 8);
},

"should calculate score 24 for roll [6,6,6,6,x] when placed on FourOfAKind": function () {
"should calculate score 24 for roll [6,6,6,6,x]": function () {
assert.score([6,6,6,6,1], "FourOfAKind", 24);
},

"should calculate score 0 for not 4 of a kind when placed on FourOfAKind": function () {
"should calculate score 0 for not 4 of a kind": function () {
assert.score([2,2,2,1,1], "FourOfAKind", 0);
}
});

buster.testCase("Scoring Pair", {
"should calculate score 2 when roll [1,1,2,3,4]": function () {
assert.score([1,1,2,3,4], "Pair", 2);
},

"should calculate score 12 when two pairs with highest pair of 6": function () {
assert.score([1,1,6,6,2], "Pair", 12);
},

"should calculate score 12 when four of a kind (6)": function () {
assert.score([6,6,6,6,1], "Pair", 12);
},

"should calculate score 0 when no pair": function () {
assert.score([1,2,3,4,5], "Pair", 0);
}
});

buster.testCase("Scoring ThreeOfAKind", {
"should calculate score 3 for roll [1,1,1,x,x]]": function () {
assert.score([1,1,1,2,3], "ThreeOfAKind", 3);
},

"should calculate score 18 for roll [6,6,6,x,x]]": function () {
assert.score([6,6,6,2,3], "ThreeOfAKind", 18);
},

"should calculate score 6 for 5 2's]": function () {
assert.score([2,2,2,2,2], "ThreeOfAKind", 6);
},

"should calculate score 0 for roll without three of a kind]": function () {
assert.score([1,1,2,3,4], "ThreeOfAKind", 0);
}
});

buster.testCase("Scoring TwoPairs", {
"should calculate score 6 for roll [1,1,2,2,6]": function () {
assert.score([1,1,2,2,6], "TwoPairs", 6);
},

"should calculate score 22 for roll [6,6,5,5,1]": function () {
assert.score([6,6,5,5,1], "TwoPairs", 22);
},

"should calculate score 24 for four 6's": function () {
assert.score([6,6,6,6,1], "TwoPairs", 24);
}
});

buster.testCase("Scoring FullHouse", {
"should calculate score 8 for roll [1,1,2,2,2]": function () {
assert.score([1,1,2,2,2], "FullHouse", 8);
},

"should calculate score 28 for roll [5,5,6,6,6]": function () {
assert.score([5,5,6,6,6], "FullHouse", 28);
},

"should calculate score 27 for roll [6,6,5,5,5]": function () {
assert.score([6,6,5,5,5], "FullHouse", 27);
},

"should calculate score 0 for yahtzee": function () {
assert.score([6,6,6,6,6], "FullHouse", 0);
},

"should calculate score 0 for nothing": function () {
assert.score([1,1,2,3,4], "FullHouse", 0);
}
});

}(scoring));
Expand Down

0 comments on commit dd2849b

Please sign in to comment.