143 lines
4.2 KiB
TypeScript
143 lines
4.2 KiB
TypeScript
'use client';
|
|
|
|
import { useState, useEffect } from 'react';
|
|
|
|
export interface GameState {
|
|
date: string;
|
|
guesses: string[]; // Array of song titles or IDs guessed
|
|
isSolved: boolean;
|
|
isFailed: boolean;
|
|
lastPlayed: number; // Timestamp
|
|
}
|
|
|
|
export interface Statistics {
|
|
solvedIn1: number;
|
|
solvedIn2: number;
|
|
solvedIn3: number;
|
|
solvedIn4: number;
|
|
solvedIn5: number;
|
|
solvedIn6: number;
|
|
solvedIn7: number;
|
|
failed: number;
|
|
}
|
|
|
|
const STORAGE_KEY = 'hoerdle_game_state';
|
|
const STATS_KEY = 'hoerdle_statistics';
|
|
|
|
export function useGameState() {
|
|
const [gameState, setGameState] = useState<GameState | null>(null);
|
|
const [statistics, setStatistics] = useState<Statistics | null>(null);
|
|
|
|
useEffect(() => {
|
|
// Load game state
|
|
const stored = localStorage.getItem(STORAGE_KEY);
|
|
const today = new Date().toISOString().split('T')[0];
|
|
|
|
if (stored) {
|
|
const parsed: GameState = JSON.parse(stored);
|
|
if (parsed.date === today) {
|
|
setGameState(parsed);
|
|
} else {
|
|
// New day
|
|
const newState: GameState = {
|
|
date: today,
|
|
guesses: [],
|
|
isSolved: false,
|
|
isFailed: false,
|
|
lastPlayed: Date.now(),
|
|
};
|
|
setGameState(newState);
|
|
localStorage.setItem(STORAGE_KEY, JSON.stringify(newState));
|
|
}
|
|
} else {
|
|
// No state
|
|
const newState: GameState = {
|
|
date: today,
|
|
guesses: [],
|
|
isSolved: false,
|
|
isFailed: false,
|
|
lastPlayed: Date.now(),
|
|
};
|
|
setGameState(newState);
|
|
localStorage.setItem(STORAGE_KEY, JSON.stringify(newState));
|
|
}
|
|
|
|
// Load statistics
|
|
const storedStats = localStorage.getItem(STATS_KEY);
|
|
if (storedStats) {
|
|
const parsedStats = JSON.parse(storedStats);
|
|
// Migration for existing stats without solvedIn7
|
|
if (parsedStats.solvedIn7 === undefined) {
|
|
parsedStats.solvedIn7 = 0;
|
|
}
|
|
setStatistics(parsedStats);
|
|
} else {
|
|
const newStats: Statistics = {
|
|
solvedIn1: 0,
|
|
solvedIn2: 0,
|
|
solvedIn3: 0,
|
|
solvedIn4: 0,
|
|
solvedIn5: 0,
|
|
solvedIn6: 0,
|
|
solvedIn7: 0,
|
|
failed: 0,
|
|
};
|
|
setStatistics(newStats);
|
|
localStorage.setItem(STATS_KEY, JSON.stringify(newStats));
|
|
}
|
|
}, []);
|
|
|
|
const saveState = (newState: GameState) => {
|
|
setGameState(newState);
|
|
localStorage.setItem(STORAGE_KEY, JSON.stringify(newState));
|
|
};
|
|
|
|
const updateStatistics = (attempts: number, solved: boolean) => {
|
|
if (!statistics) return;
|
|
|
|
const newStats = { ...statistics };
|
|
|
|
if (solved) {
|
|
switch (attempts) {
|
|
case 1: newStats.solvedIn1++; break;
|
|
case 2: newStats.solvedIn2++; break;
|
|
case 3: newStats.solvedIn3++; break;
|
|
case 4: newStats.solvedIn4++; break;
|
|
case 5: newStats.solvedIn5++; break;
|
|
case 6: newStats.solvedIn6++; break;
|
|
case 7: newStats.solvedIn7++; break;
|
|
}
|
|
} else {
|
|
newStats.failed++;
|
|
}
|
|
|
|
setStatistics(newStats);
|
|
localStorage.setItem(STATS_KEY, JSON.stringify(newStats));
|
|
};
|
|
|
|
const addGuess = (guess: string, correct: boolean) => {
|
|
if (!gameState) return;
|
|
|
|
const newGuesses = [...gameState.guesses, guess];
|
|
const isSolved = correct;
|
|
const isFailed = !correct && newGuesses.length >= 7;
|
|
|
|
const newState = {
|
|
...gameState,
|
|
guesses: newGuesses,
|
|
isSolved,
|
|
isFailed,
|
|
lastPlayed: Date.now(),
|
|
};
|
|
|
|
saveState(newState);
|
|
|
|
// Update statistics when game ends
|
|
if (isSolved || isFailed) {
|
|
updateStatistics(newGuesses.length, isSolved);
|
|
}
|
|
};
|
|
|
|
return { gameState, statistics, addGuess };
|
|
}
|