153 lines
6.5 KiB
JavaScript
Executable File
153 lines
6.5 KiB
JavaScript
Executable File
export const SCORE_CATEGORIES = {
|
|
upper: [
|
|
{ id: 'ones', name: 'Ettor', maxCount: 5, multiple: 1, inputType: 'count' },
|
|
{ id: 'twos', name: 'Tvåor', maxCount: 5, multiple: 2, inputType: 'count' },
|
|
{ id: 'threes', name: 'Treor', maxCount: 5, multiple: 3, inputType: 'count' },
|
|
{ id: 'fours', name: 'Fyror', maxCount: 5, multiple: 4, inputType: 'count' },
|
|
{ id: 'fives', name: 'Femmor', maxCount: 5, multiple: 5, inputType: 'count' },
|
|
{ id: 'sixes', name: 'Sexor', maxCount: 5, multiple: 6, inputType: 'count' }
|
|
],
|
|
lower: [
|
|
{ id: 'pair', name: 'Ett par', inputType: 'options', options: [2, 4, 6, 8, 10, 12] },
|
|
{ id: 'twoPair', name: 'Två par', min: 6, max: 22, inputType: 'score' },
|
|
{ id: 'threeOfAKind', name: 'Tretal', inputType: 'options', options: [3, 6, 9, 12, 15, 18] },
|
|
{ id: 'fourOfAKind', name: 'Fyrtal', inputType: 'options', options: [4, 8, 12, 16, 20, 24] },
|
|
{ id: 'smallStraight', name: 'Liten stege', fixed: 15, inputType: 'score' },
|
|
{ id: 'largeStraight', name: 'Stor stege', fixed: 20, inputType: 'score' },
|
|
{ id: 'fullHouse', name: 'Kåk', min: 7, max: 28, inputType: 'score' },
|
|
{ id: 'chance', name: 'Chans', min: 5, max: 30, inputType: 'score' },
|
|
{ id: 'yatzee', name: 'Yatzy', fixed: 50, inputType: 'score' }
|
|
]
|
|
};
|
|
|
|
export const ALL_CATEGORIES = [...SCORE_CATEGORIES.upper, ...SCORE_CATEGORIES.lower];
|
|
|
|
// Hjälpfunktion för att räkna förekomsten av varje tärningsvärde
|
|
function countDice(dice) {
|
|
const counts = { 1: 0, 2: 0, 3: 0, 4: 0, 5: 0, 6: 0 };
|
|
dice.forEach(die => {
|
|
counts[die]++;
|
|
});
|
|
return counts;
|
|
}
|
|
|
|
// Hjälpfunktion för att beräkna poäng för en specifik kategori
|
|
function calculateCategoryScore(dice, categoryId) {
|
|
const counts = countDice(dice);
|
|
|
|
switch (categoryId) {
|
|
case 'ones':
|
|
return counts[1] * 1;
|
|
case 'twos':
|
|
return counts[2] * 2;
|
|
case 'threes':
|
|
return counts[3] * 3;
|
|
case 'fours':
|
|
return counts[4] * 4;
|
|
case 'fives':
|
|
return counts[5] * 5;
|
|
case 'sixes':
|
|
return counts[6] * 6;
|
|
case 'pair':
|
|
for (let i = 6; i >= 1; i--) {
|
|
if (counts[i] >= 2) return i * 2;
|
|
}
|
|
return 0;
|
|
case 'twoPair':
|
|
const pairs = [];
|
|
for (let i = 6; i >= 1; i--) {
|
|
if (counts[i] >= 2) pairs.push(i * 2);
|
|
}
|
|
if (pairs.length >= 2) {
|
|
return pairs[0] + pairs[1];
|
|
} else if (pairs.length === 1) {
|
|
// Om det bara finns ett par, ta det högsta möjliga paret och lägg till högsta enkeltärning
|
|
const highestSingle = Math.max(...dice.filter(die => counts[die] === 1));
|
|
return pairs[0] + (highestSingle || 0);
|
|
}
|
|
return 0;
|
|
case 'threeOfAKind':
|
|
for (let i = 6; i >= 1; i--) {
|
|
if (counts[i] >= 3) return i * 3;
|
|
}
|
|
return 0;
|
|
case 'fourOfAKind':
|
|
for (let i = 6; i >= 1; i--) {
|
|
if (counts[i] >= 4) return i * 4;
|
|
}
|
|
return 0;
|
|
case 'smallStraight':
|
|
const hasSmallStraight = dice.some(die => {
|
|
const has1234 = dice.includes(1) && dice.includes(2) && dice.includes(3) && dice.includes(4);
|
|
const has2345 = dice.includes(2) && dice.includes(3) && dice.includes(4) && dice.includes(5);
|
|
const has3456 = dice.includes(3) && dice.includes(4) && dice.includes(5) && dice.includes(6);
|
|
return has1234 || has2345 || has3456;
|
|
});
|
|
return hasSmallStraight ? 15 : 0;
|
|
case 'largeStraight':
|
|
const has12345 = dice.includes(1) && dice.includes(2) && dice.includes(3) && dice.includes(4) && dice.includes(5);
|
|
const has23456 = dice.includes(2) && dice.includes(3) && dice.includes(4) && dice.includes(5) && dice.includes(6);
|
|
return (has12345 || has23456) ? 20 : 0;
|
|
case 'fullHouse':
|
|
const hasThreeOfAKind = Object.values(counts).some(count => count >= 3);
|
|
const hasPair = Object.values(counts).some(count => count >= 2);
|
|
return (hasThreeOfAKind && hasPair) ? dice.reduce((sum, die) => sum + die, 0) : 0;
|
|
case 'chance':
|
|
return dice.reduce((sum, die) => sum + die, 0);
|
|
case 'yatzee':
|
|
return Object.values(counts).some(count => count === 5) ? 50 : 0;
|
|
default:
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
// Funktion för att beräkna möjliga poäng för en kategori
|
|
export function calculatePossibleScores(gameData, playerId, categoryId) {
|
|
// Hämta de senast kastade tärningarna för spelaren (detta måste implementeras i main.js)
|
|
const currentDice = gameData.currentDice || [1, 1, 1, 1, 1]; // Exempelvärden, ersätt med riktiga tärningar
|
|
|
|
const category = ALL_CATEGORIES.find(cat => cat.id === categoryId);
|
|
if (!category) return [];
|
|
|
|
const score = calculateCategoryScore(currentDice, categoryId);
|
|
|
|
if (category.inputType === 'count') {
|
|
return [score];
|
|
} else if (category.inputType === 'options') {
|
|
return category.options.includes(score) ? [score] : [0];
|
|
} else if (category.inputType === 'score') {
|
|
if (category.fixed) {
|
|
return [category.fixed];
|
|
} else if (category.min !== undefined && category.max !== undefined) {
|
|
return score >= category.min && score <= category.max ? [score] : [0];
|
|
} else {
|
|
return [score];
|
|
}
|
|
}
|
|
|
|
return [score];
|
|
}
|
|
|
|
export function calculateTotals(gameData) {
|
|
const playerTotals = {};
|
|
gameData.players.forEach(p => {
|
|
const pScores = gameData.scores[p.id] || {};
|
|
const upperSum = SCORE_CATEGORIES.upper.reduce((sum, cat) => sum + (pScores[cat.id] || 0), 0);
|
|
const upperBonus = upperSum >= 63 ? 50 : 0;
|
|
const upperTotal = upperSum + upperBonus;
|
|
const lowerTotal = SCORE_CATEGORIES.lower.reduce((sum, cat) => sum + (pScores[cat.id] || 0), 0);
|
|
const grandTotal = upperTotal + lowerTotal;
|
|
playerTotals[p.id] = { upperSum, upperBonus, upperTotal, lowerTotal, grandTotal };
|
|
});
|
|
return playerTotals;
|
|
}
|
|
|
|
export function isGameComplete(gameData) {
|
|
if (!gameData || !gameData.players || !gameData.scores) return false;
|
|
return gameData.players.every(p => {
|
|
return ALL_CATEGORIES.every(cat => {
|
|
return gameData.scores[p.id]?.[cat.id] !== null && gameData.scores[p.id]?.[cat.id] !== undefined;
|
|
});
|
|
});
|
|
}
|