Commit a1d3f272 authored by Lucas BRETTES's avatar Lucas BRETTES
Browse files

refactor: move private functions to dice-utils 馃摝

parent fb3f295f
import assert from 'assert'; import assert from 'assert';
import Yatzy from './Yatzy'; import Yatzy from './yatzy';
describe('Chance', () => { describe('Chance', () => {
......
import { isConsecutives, sumOfSelectedValue, toDiceMap } from './dice-utils';
type D6 = 1 | 2 | 3 | 4 | 5 | 6; type D6 = 1 | 2 | 3 | 4 | 5 | 6;
export default class Yatzy { export default class Yatzy {
...@@ -17,82 +18,66 @@ export default class Yatzy { ...@@ -17,82 +18,66 @@ export default class Yatzy {
} }
ones(): number { ones(): number {
return this.singles(this.dice, 1); return sumOfSelectedValue(this.dice, 1);
} }
twos(): number { twos(): number {
return this.singles(this.dice, 2); return sumOfSelectedValue(this.dice, 2);
} }
threes(): number { threes(): number {
return this.singles(this.dice, 3); return sumOfSelectedValue(this.dice, 3);
} }
fours(): number { fours(): number {
return this.singles(this.dice, 4); return sumOfSelectedValue(this.dice, 4);
} }
fives(): number { fives(): number {
return this.singles(this.dice, 5); return sumOfSelectedValue(this.dice, 5);
} }
sixes(): number { sixes(): number {
return this.singles(this.dice, 6); return sumOfSelectedValue(this.dice, 6);
} }
onePair(): number { onePair(): number {
const diceMap = this.toDiceMap(this.dice); const diceMap = toDiceMap(this.dice);
const keyPairs = Object.entries(diceMap).filter(([key, value]) => value >= 2).map(([key, value]) => +key); const keyPairs = Object.entries(diceMap).filter(([key, value]) => value >= 2).map(([key, value]) => +key);
return keyPairs.length > 0 ? Math.max(...keyPairs) * 2 : 0; return keyPairs.length > 0 ? Math.max(...keyPairs) * 2 : 0;
} }
twoPair(): number { twoPair(): number {
const diceMap = this.toDiceMap(this.dice); const diceMap = toDiceMap(this.dice);
const keyPairs = Object.entries(diceMap).filter(([key, value]) => value >= 2).map(([key, value]) => +key); 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; return keyPairs.length === 2 ? keyPairs.reduce((firstPair, secondPair) => (firstPair*2) + (secondPair*2)) : 0;
} }
threeOfAKind(): number { threeOfAKind(): number {
const diceMap = this.toDiceMap(this.dice); const diceMap = toDiceMap(this.dice);
const threeOfAKindDice = Object.keys(diceMap).find(k => diceMap[k] >= 3); const threeOfAKindDice = Object.keys(diceMap).find(k => diceMap[k] >= 3);
return threeOfAKindDice ? +threeOfAKindDice * 3 : 0; return threeOfAKindDice ? +threeOfAKindDice * 3 : 0;
} }
fourOfAKind(): number { fourOfAKind(): number {
const diceMap = this.toDiceMap(this.dice); const diceMap = toDiceMap(this.dice);
const fourOfAKindDice = Object.keys(diceMap).find(k => diceMap[k] >= 4); const fourOfAKindDice = Object.keys(diceMap).find(k => diceMap[k] >= 4);
return fourOfAKindDice ? +fourOfAKindDice * 4 : 0; return fourOfAKindDice ? +fourOfAKindDice * 4 : 0;
} }
smallStraight(): number { smallStraight(): number {
return this.isConsecutives(this.dice) && Math.min(...this.dice) === 1 ? 15 : 0; return isConsecutives(this.dice) && Math.min(...this.dice) === 1 ? 15 : 0;
} }
largeStraight(): number { largeStraight(): number {
return this.isConsecutives(this.dice) && Math.max(...this.dice) === 6 ? 20 : 0; return isConsecutives(this.dice) && Math.max(...this.dice) === 6 ? 20 : 0;
} }
fullHouse(): number { fullHouse(): number {
const diceMap = this.toDiceMap(this.dice); const diceMap = toDiceMap(this.dice);
return Object.keys(diceMap).length === 2 && Object.values(diceMap).some(d => d === 2 || d === 3) return Object.keys(diceMap).length === 2 && Object.values(diceMap).some(d => d === 2 || d === 3)
? Object.keys(diceMap).reduce((sum, key) => sum += (+key * diceMap[key]), 0) : 0; ? 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);
}
} }
import { isConsecutives, sumOfSelectedValue, toDiceMap } from './dice-utils';
describe('Sum of selected value in array', () => {
it('should give the sum of a selected value in an array', () => {
expect(sumOfSelectedValue([1, 1, 2, 20, 5, 4, 1], 1)).toBe(3);
expect(sumOfSelectedValue([1, 1, 2, 20, 5, 4, 1], 9)).toBe(0)
});
});
describe('Convert dice array to map', () => {
it('should return a map with the dice face as key and his number of occurences as value', () => {
expect(toDiceMap([1, 1, 1, 2, 2, 3])).toStrictEqual({'1': 3, '2': 2, '3':1});
});
});
describe('Check if array contains only consecutives values', () => {
it('should return true', () => {
expect(isConsecutives([2, 1, 5, 4, 3])).toBe(true);
});
it('should return false', () => {
expect(isConsecutives([2, 1, 5, 3, 7, 8])).toBe(false);
})
});
\ No newline at end of file
export const sumOfSelectedValue = (dice: number[], selectedValue: number) : number =>
dice.filter(d => d === selectedValue).reduce((previous, next) => previous + next, 0);
export const 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;
}
export const isConsecutives = (dice: number[]): boolean =>
dice.sort().every((d, index) => (dice[index+1] || d+1)-d === 1);
\ No newline at end of file
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