88 lines
2.2 KiB
TypeScript
88 lines
2.2 KiB
TypeScript
import { PointsCalculation, POINTS } from '../types';
|
|
|
|
interface Score {
|
|
home: number;
|
|
away: number;
|
|
}
|
|
|
|
/**
|
|
* Berechnet die Punkte für einen Tipp.
|
|
*
|
|
* Punkteregeln:
|
|
* - Exaktes Ergebnis: 3 Punkte
|
|
* - Richtige Tendenz: 1 Punkt (Sieg/Unentschieden/Niederlage korrekt)
|
|
* - Falsche Tendenz: 0 Punkte
|
|
*
|
|
* @param tip - Der abgegebene Tipp
|
|
* @param actual - Das tatsächliche Ergebnis
|
|
*/
|
|
export const calculatePoints = (
|
|
tip: Score,
|
|
actual: Score
|
|
): PointsCalculation => {
|
|
// Exaktes Ergebnis
|
|
if (tip.home === actual.home && tip.away === actual.away) {
|
|
return { result: 'exact', points: POINTS.EXACT };
|
|
}
|
|
|
|
// Tendenz prüfen (Sieg Heim / Unentschieden / Sieg Auswärts)
|
|
const tipTendency = getTendency(tip.home, tip.away);
|
|
const actualTendency = getTendency(actual.home, actual.away);
|
|
|
|
if (tipTendency === actualTendency) {
|
|
return { result: 'tendency', points: POINTS.TENDENCY };
|
|
}
|
|
|
|
return { result: 'wrong', points: POINTS.WRONG };
|
|
};
|
|
|
|
type Tendency = 'home' | 'draw' | 'away';
|
|
|
|
const getTendency = (home: number, away: number): Tendency => {
|
|
if (home > away) return 'home';
|
|
if (home < away) return 'away';
|
|
return 'draw';
|
|
};
|
|
|
|
/**
|
|
* Berechnet Punkte für die gesamte Tipp-History eines Users.
|
|
* Nützlich für Statistiken.
|
|
*/
|
|
export const calculateUserStats = (
|
|
tips: Array<{
|
|
tipHome: number;
|
|
tipAway: number;
|
|
actualHome: number | null;
|
|
actualAway: number | null;
|
|
points: number | null;
|
|
}>
|
|
) => {
|
|
const evaluated = tips.filter(
|
|
(t) => t.actualHome !== null && t.actualAway !== null
|
|
);
|
|
|
|
const exactCount = evaluated.filter((t) => t.points === POINTS.EXACT).length;
|
|
const tendencyCount = evaluated.filter(
|
|
(t) => t.points === POINTS.TENDENCY
|
|
).length;
|
|
const wrongCount = evaluated.filter((t) => t.points === POINTS.WRONG).length;
|
|
const totalPoints = evaluated.reduce((sum, t) => sum + (t.points ?? 0), 0);
|
|
|
|
const accuracy =
|
|
evaluated.length > 0
|
|
? Math.round(
|
|
((exactCount + tendencyCount) / evaluated.length) * 100
|
|
)
|
|
: 0;
|
|
|
|
return {
|
|
totalPoints,
|
|
exactCount,
|
|
tendencyCount,
|
|
wrongCount,
|
|
accuracy,
|
|
evaluatedCount: evaluated.length,
|
|
pendingCount: tips.length - evaluated.length,
|
|
};
|
|
};
|