- Change endlos raceTo from 0 to Infinity to prevent automatic completion - Update NewGame component to handle Infinity values properly - Add Infinity checks in game completion and winner logic - Fix game progress calculation for endless games Fixes issue where selecting 'endlos' mode would end the match immediately when any player scored their first point.
108 lines
3.1 KiB
TypeScript
108 lines
3.1 KiB
TypeScript
import type { Game, StandardGame, EndlosGame } from '../types/game';
|
|
|
|
/**
|
|
* Game utility functions for common operations
|
|
*/
|
|
|
|
export function isEndlosGame(game: Game): game is EndlosGame {
|
|
return 'players' in game;
|
|
}
|
|
|
|
export function isStandardGame(game: Game): game is StandardGame {
|
|
return !('players' in game);
|
|
}
|
|
|
|
export function formatGameTime(dateString: string): string {
|
|
const date = new Date(dateString);
|
|
const now = new Date();
|
|
const diffInHours = (now.getTime() - date.getTime()) / (1000 * 60 * 60);
|
|
|
|
if (diffInHours < 1) {
|
|
return 'vor wenigen Minuten';
|
|
} else if (diffInHours < 24) {
|
|
return `vor ${Math.floor(diffInHours)} Stunde${Math.floor(diffInHours) !== 1 ? 'n' : ''}`;
|
|
} else if (diffInHours < 168) { // 7 days
|
|
const days = Math.floor(diffInHours / 24);
|
|
return `vor ${days} Tag${days !== 1 ? 'en' : ''}`;
|
|
} else {
|
|
return date.toLocaleDateString('de-DE');
|
|
}
|
|
}
|
|
|
|
export function getGameDuration(game: Game): string {
|
|
const start = new Date(game.createdAt);
|
|
const end = new Date(game.updatedAt);
|
|
const diffInMinutes = (end.getTime() - start.getTime()) / (1000 * 60);
|
|
|
|
if (diffInMinutes < 60) {
|
|
return `${Math.floor(diffInMinutes)} Min`;
|
|
} else {
|
|
const hours = Math.floor(diffInMinutes / 60);
|
|
const minutes = Math.floor(diffInMinutes % 60);
|
|
return `${hours}h ${minutes}m`;
|
|
}
|
|
}
|
|
|
|
export function calculateGameProgress(game: Game): number {
|
|
// If raceTo is Infinity, progress is always 0 (endless game)
|
|
if (game.raceTo === Infinity) return 0;
|
|
|
|
if (isEndlosGame(game)) {
|
|
const maxScore = Math.max(...game.players.map(p => p.score));
|
|
return Math.min((maxScore / game.raceTo) * 100, 100);
|
|
} else {
|
|
const scores = [game.score1, game.score2, game.score3 || 0];
|
|
const maxScore = Math.max(...scores);
|
|
return Math.min((maxScore / game.raceTo) * 100, 100);
|
|
}
|
|
}
|
|
|
|
export function getGameWinner(game: Game): string | null {
|
|
if (game.status !== 'completed') return null;
|
|
|
|
if ('winner' in game && game.winner) {
|
|
return game.winner;
|
|
}
|
|
|
|
// If raceTo is Infinity, there's no automatic winner
|
|
if (game.raceTo === Infinity) return null;
|
|
|
|
if (isEndlosGame(game)) {
|
|
const winner = game.players.find(player => player.score >= game.raceTo);
|
|
return winner?.name || null;
|
|
} else {
|
|
if (game.score1 >= game.raceTo) return game.player1;
|
|
if (game.score2 >= game.raceTo) return game.player2;
|
|
if (game.player3 && game.score3 && game.score3 >= game.raceTo) return game.player3;
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
export function getGamePlayers(game: Game): Array<{ name: string; score: number }> {
|
|
if (isEndlosGame(game)) {
|
|
return game.players.map(player => ({
|
|
name: player.name,
|
|
score: player.score,
|
|
}));
|
|
} else {
|
|
const players = [
|
|
{ name: game.player1, score: game.score1 },
|
|
{ name: game.player2, score: game.score2 },
|
|
];
|
|
if (game.player3) {
|
|
players.push({ name: game.player3, score: game.score3 || 0 });
|
|
}
|
|
return players;
|
|
}
|
|
}
|
|
|
|
export function validateGameData(data: any): boolean {
|
|
return !!(
|
|
data.player1?.trim() &&
|
|
data.player2?.trim() &&
|
|
data.gameType &&
|
|
data.raceTo &&
|
|
parseInt(data.raceTo) > 0
|
|
);
|
|
} |