Commit 12379035 authored by Lucas BRETTES's avatar Lucas BRETTES

Merge branch 'develop' into 'master'

Refactor: Yatzy services & tests + add new npm dependencies

See merge request !1
parents bd5bf142 4a4bb0b9
#!/bin/sh
. "$(dirname "$0")/_/husky.sh"
npx --no-install commitlint --edit $1
module.exports = { extends: ['@commitlint/config-conventional'] };
module.exports = {
"roots": [
"<rootDir>/src"
],
"testMatch": [
"**/__tests__/**/*.+(ts|tsx|js)",
"**/?(*.)+(spec|test).+(ts|tsx|js)"
],
"transform": {
"^.+\\.(ts|tsx)$": "ts-jest"
},
}
\ No newline at end of file
This diff is collapsed.
......@@ -9,14 +9,17 @@
"@types/node": "*"
},
"devDependencies": {
"@types/mocha": "^5.2.0",
"mocha": "^8.2.1",
"ts-node": "^6.0.5",
"typescript": "^2.8.3"
"@commitlint/cli": "^12.1.4",
"@commitlint/config-conventional": "^12.1.4",
"@types/jest": "^26.0.24",
"husky": "^7.0.1",
"jest": "^27.0.6",
"ts-jest": "^27.0.3",
"typescript": "^4.3.5"
},
"scripts": {
"test": "mocha --require ts-node/register/transpile-only 'test/**/*.ts'",
"watch": "mocha --require ts-node/register --watch --watch-files src, test/**/*.ts"
"test": "jest",
"watch": "jest --watch --verbose"
},
"private": true
}
import assert from 'assert';
import Yatzy from './Yatzy';
import Yatzy from '../src/Yatzy';
describe('Chance', () => {
it('scores sum of all dice', () => {
assert.strictEqual(15, Yatzy.chance(2, 3, 4, 5, 1));
assert.strictEqual(16, Yatzy.chance(3, 3, 4, 5, 1));
assert.strictEqual(15, new Yatzy(2, 3, 4, 5, 1).chance());
assert.strictEqual(16, new Yatzy(3, 3, 4, 5, 1).chance());
});
});
describe('Yatzy', () => {
it('scores 50', () => {
assert.strictEqual(50, Yatzy.yatzy(4, 4, 4, 4, 4));
assert.strictEqual(50, Yatzy.yatzy(6, 6, 6, 6, 6));
assert.strictEqual(0, Yatzy.yatzy(6, 6, 6, 6, 3));
assert.strictEqual(0, new Yatzy(6, 6, 6, 6, 3).yatzy());
assert.strictEqual(50, new Yatzy(4, 4, 4, 4, 4).yatzy());
assert.strictEqual(50, new Yatzy(6, 6, 6, 6, 6).yatzy());
});
});
describe('Ones', () => {
it('score the sum of 1s', () => {
assert.strictEqual(1, Yatzy.ones(1, 2, 3, 4, 5));
assert.strictEqual(2, Yatzy.ones(1, 2, 1, 4, 5));
assert.strictEqual(0, Yatzy.ones(6, 2, 2, 4, 5));
assert.strictEqual(4, Yatzy.ones(1, 2, 1, 1, 1));
assert.strictEqual(0, new Yatzy(6, 2, 2, 4, 5).ones());
assert.strictEqual(1, new Yatzy(1, 2, 3, 4, 5).ones());
assert.strictEqual(2, new Yatzy(1, 2, 1, 4, 5).ones());
assert.strictEqual(4, new Yatzy(1, 2, 1, 1, 1).ones());
});
});
describe('Twos', () => {
it('score the sum of 2s', () => {
assert.strictEqual(4, Yatzy.twos(1, 2, 3, 2, 6));
assert.strictEqual(10, Yatzy.twos(2, 2, 2, 2, 2));
assert.strictEqual(0, new Yatzy(1, 4, 3, 5, 6).twos());
assert.strictEqual(4, new Yatzy(1, 2, 3, 2, 6).twos());
assert.strictEqual(10, new Yatzy(2, 2, 2, 2, 2).twos());
});
});
describe('Threes', () => {
it('score the sum of 3s', () => {
assert.strictEqual(6, Yatzy.threes(1, 2, 3, 2, 3));
assert.strictEqual(12, Yatzy.threes(2, 3, 3, 3, 3));
assert.strictEqual(6, new Yatzy(1, 2, 3, 2, 3).threes());
assert.strictEqual(12, new Yatzy(2, 3, 3, 3, 3).threes());
});
});
......@@ -66,54 +67,63 @@ describe('Sixes', () => {
describe('One pair', () => {
it('scores the sum of the highest pair', () => {
assert.strictEqual(6, Yatzy.score_pair(3, 4, 3, 5, 6));
assert.strictEqual(10, Yatzy.score_pair(5, 3, 3, 3, 5));
assert.strictEqual(12, Yatzy.score_pair(5, 3, 6, 6, 5));
assert.strictEqual(0, new Yatzy(3, 4, 1, 5, 6).onePair());
assert.strictEqual(6, new Yatzy(3, 4, 3, 5, 6).onePair());
assert.strictEqual(10, new Yatzy(5, 3, 3, 3, 5).onePair());
assert.strictEqual(12, new Yatzy(5, 3, 6, 6, 5).onePair());
});
});
describe('Two pair', () => {
it('scores the sum of the two pairs', () => {
assert.strictEqual(16, Yatzy.two_pair(3, 3, 5, 4, 5));
assert.strictEqual(16, Yatzy.two_pair(3, 3, 5, 5, 5));
assert.strictEqual(0, new Yatzy(3, 3, 2, 4, 5).twoPair());
assert.strictEqual(16, new Yatzy(3, 3, 5, 4, 5).twoPair());
assert.strictEqual(16, new Yatzy(3, 3, 5, 5, 5).twoPair());
});
});
describe('Three of a kind', () => {
it('scores the sum of the three of the kind', () => {
assert.strictEqual(9, Yatzy.three_of_a_kind(3, 3, 3, 4, 5));
assert.strictEqual(15, Yatzy.three_of_a_kind(5, 3, 5, 4, 5));
assert.strictEqual(9, Yatzy.three_of_a_kind(3, 3, 3, 3, 5));
assert.strictEqual(0, new Yatzy(3, 3, 4, 4, 5).threeOfAKind());
assert.strictEqual(9, new Yatzy(3, 3, 3, 4, 5).threeOfAKind());
assert.strictEqual(15, new Yatzy(5, 3, 5, 4, 5).threeOfAKind());
assert.strictEqual(9, new Yatzy(3, 3, 3, 3, 5).threeOfAKind());
});
});
describe('Four of a kind', () => {
it('scores the sum of the four of the kind', () => {
assert.strictEqual(12, Yatzy.four_of_a_kind(3, 3, 3, 3, 5));
assert.strictEqual(20, Yatzy.four_of_a_kind(5, 5, 5, 4, 5));
assert.strictEqual(9, Yatzy.three_of_a_kind(3, 3, 3, 3, 3));
assert.strictEqual(0, new Yatzy(3, 3, 3, 5, 5).fourOfAKind());
assert.strictEqual(12, new Yatzy(3, 3, 3, 3, 5).fourOfAKind());
assert.strictEqual(20, new Yatzy(5, 5, 5, 4, 5).fourOfAKind());
assert.strictEqual(12, new Yatzy(3, 3, 3, 3, 3).fourOfAKind());
});
});
describe('Small straight', () => {
it('scores 15', () => {
assert.strictEqual(15, Yatzy.smallStraight(1, 2, 3, 4, 5));
assert.strictEqual(15, Yatzy.smallStraight(2, 3, 4, 5, 1));
assert.strictEqual(0, Yatzy.smallStraight(1, 2, 2, 4, 5));
assert.strictEqual(0, new Yatzy(1, 2, 4, 5, 6).smallStraight());
assert.strictEqual(0, new Yatzy(1, 2, 2, 4, 5).smallStraight());
assert.strictEqual(0, new Yatzy(2, 3, 4, 5, 6).smallStraight());
assert.strictEqual(15, new Yatzy(1, 2, 3, 4, 5).smallStraight());
assert.strictEqual(15, new Yatzy(2, 3, 4, 5, 1).smallStraight());
});
});
describe('Large straight', () => {
it('scores 20', () => {
assert.strictEqual(20, Yatzy.largeStraight(6, 2, 3, 4, 5));
assert.strictEqual(20, Yatzy.largeStraight(2, 3, 4, 5, 6));
assert.strictEqual(0, Yatzy.largeStraight(1, 2, 2, 4, 5));
assert.strictEqual(0, new Yatzy(1, 2, 2, 4, 5).largeStraight());
assert.strictEqual(0, new Yatzy(1, 2, 3, 4, 5).largeStraight());
assert.strictEqual(0, new Yatzy(1, 2, 4, 5, 6).largeStraight());
assert.strictEqual(20, new Yatzy(6, 2, 3, 4, 5).largeStraight());
assert.strictEqual(20, new Yatzy(2, 3, 4, 5, 6).largeStraight());
});
});
describe('Full house', () => {
it('scores the sum of the full house', () => {
assert.strictEqual(18, Yatzy.fullHouse(6, 2, 2, 2, 6));
assert.strictEqual(0, Yatzy.fullHouse(2, 3, 4, 5, 6));
assert.strictEqual(0, new Yatzy(2, 3, 4, 5, 6).fullHouse());
assert.strictEqual(22, new Yatzy(2, 2, 6, 6, 6).fullHouse());
assert.strictEqual(18, new Yatzy(6, 2, 2, 2, 6).fullHouse());
});
});
type D6 = 1 | 2 | 3 | 4 | 5 | 6;
export default class Yatzy {
private dice: number[];
constructor(d1: number, d2: number, d3: number, d4: number, _5: number) {
this.dice = [];
this.dice[0] = d1;
this.dice[1] = d2;
this.dice[2] = d3;
this.dice[3] = d4;
this.dice[4] = _5;
}
static chance(d1: number, d2: number, d3: number, d4: number, d5: number): number {
var total = 0;
total += d1;
total += d2;
total += d3;
total += d4;
total += d5;
return total;
}
static yatzy(...args: number[]): number {
var counts = [0, 0, 0, 0, 0, 0, 0, 0];
for (var i = 0; i != args.length; ++i) {
var die = args[i];
counts[die - 1]++;
}
for (i = 0; i != 6; i++) if (counts[i] == 5) return 50;
return 0;
}
static ones(d1: number, d2: number, d3: number, d4: number, d5: number): number {
var sum = 0;
if (d1 == 1) sum++;
if (d2 == 1) sum++;
if (d3 == 1) sum++;
if (d4 == 1) sum++;
if (d5 == 1) sum++;
return sum;
}
static twos(d1: number, d2: number, d3: number, d4: number, d5: number): number {
var sum = 0;
if (d1 == 2) sum += 2;
if (d2 == 2) sum += 2;
if (d3 == 2) sum += 2;
if (d4 == 2) sum += 2;
if (d5 == 2) sum += 2;
return sum;
}
static threes(d1: number, d2: number, d3: number, d4: number, d5: number): number {
var s;
s = 0;
if (d1 == 3) s += 3;
if (d2 == 3) s += 3;
if (d3 == 3) s += 3;
if (d4 == 3) s += 3;
if (d5 == 3) s += 3;
return s;
}
static score_pair(d1: number, d2: number, d3: number, d4: number, d5: number): number {
var counts = [0, 0, 0, 0, 0, 0, 0, 0, 0];
counts[d1 - 1]++;
counts[d2 - 1]++;
counts[d3 - 1]++;
counts[d4 - 1]++;
counts[d5 - 1]++;
var at;
for (at = 0; at != 6; at++) if (counts[6 - at - 1] >= 2) return (6 - at) * 2;
return 0;
}
static two_pair(d1: number, d2: number, d3: number, d4: number, d5: number): number {
var counts = [0, 0, 0, 0, 0, 0, 0, 0, 0];
counts[d1 - 1]++;
counts[d2 - 1]++;
counts[d3 - 1]++;
counts[d4 - 1]++;
counts[d5 - 1]++;
var n = 0;
var score = 0;
for (let i = 0; i < 6; i += 1)
if (counts[6 - i - 1] >= 2) {
n++;
score += 6 - i;
}
if (n == 2) return score * 2;
else return 0;
}
static four_of_a_kind(_1: number, _2: number, d3: number, d4: number, d5: number): number {
var tallies;
tallies = [0, 0, 0, 0, 0, 0, 0, 0];
tallies[_1 - 1]++;
tallies[_2 - 1]++;
tallies[d3 - 1]++;
tallies[d4 - 1]++;
tallies[d5 - 1]++;
for (let i = 0; i < 6; i++) if (tallies[i] >= 4) return (i + 1) * 4;
return 0;
}
static three_of_a_kind(d1: number, d2: number, d3: number, d4: number, d5: number): number {
var t;
t = [0, 0, 0, 0, 0, 0, 0, 0, 0];
t[d1 - 1]++;
t[d2 - 1]++;
t[d3 - 1]++;
t[d4 - 1]++;
t[d5 - 1]++;
for (let i = 0; i < 6; i++) if (t[i] >= 3) return (i + 1) * 3;
return 0;
}
static smallStraight(d1: number, d2: number, d3: number, d4: number, d5: number): number {
var tallies;
tallies = [0, 0, 0, 0, 0, 0, 0];
tallies[d1 - 1] += 1;
tallies[d2 - 1] += 1;
tallies[d3 - 1] += 1;
tallies[d4 - 1] += 1;
tallies[d5 - 1] += 1;
if (tallies[0] == 1 && tallies[1] == 1 && tallies[2] == 1 && tallies[3] == 1 && tallies[4] == 1) return 15;
return 0;
}
static largeStraight(d1: number, d2: number, d3: number, d4: number, d5: number): number {
var tallies;
tallies = [0, 0, 0, 0, 0, 0, 0, 0];
tallies[d1 - 1] += 1;
tallies[d2 - 1] += 1;
tallies[d3 - 1] += 1;
tallies[d4 - 1] += 1;
tallies[d5 - 1] += 1;
if (tallies[1] == 1 && tallies[2] == 1 && tallies[3] == 1 && tallies[4] == 1 && tallies[5] == 1) return 20;
return 0;
}
static fullHouse(d1: number, d2: number, d3: number, d4: number, d5: number): number {
var tallies;
var _2 = false;
var i;
var _2_at = 0;
var _3 = false;
var _3_at = 0;
tallies = [0, 0, 0, 0, 0, 0, 0, 0];
tallies[d1 - 1] += 1;
tallies[d2 - 1] += 1;
tallies[d3 - 1] += 1;
tallies[d4 - 1] += 1;
tallies[d5 - 1] += 1;
for (i = 0; i != 6; i += 1)
if (tallies[i] == 2) {
_2 = true;
_2_at = i + 1;
}
for (i = 0; i != 6; i += 1)
if (tallies[i] == 3) {
_3 = true;
_3_at = i + 1;
}
if (_2 && _3) return _2_at * 2 + _3_at * 3;
else return 0;
private readonly dice: number[];
constructor(d1: D6, d2: D6, d3: D6, d4: D6, d5: D6) {
this.dice = [d1, d2, d3, d4, d5];
}
chance(): number {
return this.dice.reduce((previous, next) => previous + next);
}
yatzy(): number {
return (new Set(this.dice).size === 1) ? 50 : 0;
}
ones(): number {
return this.singles(this.dice, 1);
}
twos(): number {
return this.singles(this.dice, 2);
}
threes(): number {
return this.singles(this.dice, 3);
}
fours(): number {
var sum;
sum = 0;
for (let at = 0; at != 5; at++) {
if (this.dice[at] == 4) {
sum += 4;
}
}
return sum;
return this.singles(this.dice, 4);
}
fives(): number {
let s = 0;
var i;
for (i = 0; i < this.dice.length; i++) if (this.dice[i] == 5) s = s + 5;
return s;
return this.singles(this.dice, 5);
}
sixes(): number {
let sum = 0;
for (var at = 0; at < this.dice.length; at++) if (this.dice[at] == 6) sum = sum + 6;
return sum;
return this.singles(this.dice, 6);
}
onePair(): number {
const diceMap = this.toDiceMap(this.dice);
const keyPairs = Object.entries(diceMap).filter(([key, value]) => value >= 2).map(([key, value]) => +key);
return keyPairs.length > 0 ? Math.max(...keyPairs) * 2 : 0;
}
twoPair(): number {
const diceMap = this.toDiceMap(this.dice);
const keyPairs = Object.entries(diceMap).filter(([key, value]) => value >= 2).map(([key, value]) => +key);
return keyPairs.length == 2 ? keyPairs.reduce((firstPair, secondPair) => (firstPair*2) + (secondPair*2)) : 0;
}
threeOfAKind(): number {
const diceMap = this.toDiceMap(this.dice);
const threeOfAKindDice = Object.keys(diceMap).find(k => diceMap[k] >= 3);
return threeOfAKindDice ? +threeOfAKindDice * 3 : 0;
}
fourOfAKind(): number {
const diceMap = this.toDiceMap(this.dice);
const fourOfAKindDice = Object.keys(diceMap).find(k => diceMap[k] >= 4);
return fourOfAKindDice ? +fourOfAKindDice * 4 : 0;
}
smallStraight(): number {
return this.isConsecutives(this.dice) && Math.min(...this.dice) === 1 ? 15 : 0;
}
largeStraight(): number {
return this.isConsecutives(this.dice) && Math.max(...this.dice) === 6 ? 20 : 0;
}
fullHouse(): number {
const diceMap = this.toDiceMap(this.dice);
return Object.keys(diceMap).length == 2 ? Object.keys(diceMap).reduce((sum, key) => sum += (+key * diceMap[key]), 0) : 0;
}
private singles(dice: number[], selectedValue: number): number {
return dice.filter(d => d === selectedValue).reduce((previous, next) => previous + next, 0);
}
private toDiceMap(dice: number[]): {[key:string]: number} {
const diceMap: {[key:string]:number} = {};
for(const d of dice) {
diceMap[d] = diceMap[d] ? ++diceMap[d] : 1;
}
return diceMap;
}
private isConsecutives(dice: number[]): boolean {
return dice.sort().every((d, index) => (dice[index+1] || d+1)-d === 1);
}
}
......@@ -7,7 +7,7 @@
"rootDir": ".",
"strict": true,
"noUnusedLocals": true,
"types": ["node", "mocha"],
"types": ["node", "jest"],
"allowSyntheticDefaultImports": true,
"esModuleInterop": true
},
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment