feat: add 7th guess with 60s unlock and update docs
This commit is contained in:
@@ -5,7 +5,7 @@ Eine Web-App inspiriert von Heardle, bei der Nutzer täglich einen Song anhand k
|
||||
## Features
|
||||
|
||||
- **Tägliches Rätsel:** Jeden Tag ein neuer Song für alle Nutzer.
|
||||
- **Inkrementelle Hinweise:** Startet mit 2 Sekunden, dann 4s, 7s, 11s, 16s, bis 30s.
|
||||
- **Inkrementelle Hinweise:** Startet mit 2 Sekunden, dann 4s, 7s, 11s, 16s, 30s, bis 60s (7 Versuche).
|
||||
- **Admin Dashboard:**
|
||||
- Upload von MP3-Dateien.
|
||||
- Automatische Extraktion von ID3-Tags (Titel, Interpret).
|
||||
|
||||
@@ -17,7 +17,7 @@ interface GameProps {
|
||||
} | null;
|
||||
}
|
||||
|
||||
const UNLOCK_STEPS = [2, 4, 7, 11, 16, 30];
|
||||
const UNLOCK_STEPS = [2, 4, 7, 11, 16, 30, 60];
|
||||
|
||||
export default function Game({ dailyPuzzle }: GameProps) {
|
||||
const { gameState, statistics, addGuess } = useGameState();
|
||||
@@ -48,17 +48,17 @@ export default function Game({ dailyPuzzle }: GameProps) {
|
||||
setHasWon(true);
|
||||
} else {
|
||||
addGuess(song.title, false);
|
||||
if (gameState.guesses.length + 1 >= 6) {
|
||||
if (gameState.guesses.length + 1 >= 7) {
|
||||
setHasLost(true);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const unlockedSeconds = UNLOCK_STEPS[Math.min(gameState.guesses.length, 5)];
|
||||
const unlockedSeconds = UNLOCK_STEPS[Math.min(gameState.guesses.length, 6)];
|
||||
|
||||
const handleShare = () => {
|
||||
let emojiGrid = '';
|
||||
const totalGuesses = 6;
|
||||
const totalGuesses = 7;
|
||||
|
||||
// Build the grid
|
||||
for (let i = 0; i < totalGuesses; i++) {
|
||||
@@ -110,7 +110,7 @@ export default function Game({ dailyPuzzle }: GameProps) {
|
||||
|
||||
<div style={{ borderBottom: '1px solid #e5e7eb', paddingBottom: '1rem' }}>
|
||||
<div className="status-bar">
|
||||
<span>Attempt {gameState.guesses.length + 1} / 6</span>
|
||||
<span>Attempt {gameState.guesses.length + 1} / 7</span>
|
||||
<span>{unlockedSeconds}s unlocked</span>
|
||||
</div>
|
||||
<AudioPlayer
|
||||
@@ -140,7 +140,7 @@ export default function Game({ dailyPuzzle }: GameProps) {
|
||||
onClick={() => addGuess("SKIPPED", false)}
|
||||
className="skip-button"
|
||||
>
|
||||
Skip (+{UNLOCK_STEPS[Math.min(gameState.guesses.length + 1, 5)] - unlockedSeconds}s)
|
||||
Skip (+{UNLOCK_STEPS[Math.min(gameState.guesses.length + 1, 6)] - unlockedSeconds}s)
|
||||
</button>
|
||||
</>
|
||||
)}
|
||||
|
||||
@@ -13,6 +13,7 @@ const BADGES = {
|
||||
4: '⭐', // Star
|
||||
5: '✨', // Sparkles
|
||||
6: '💫', // Dizzy
|
||||
7: '🎵', // Musical note
|
||||
failed: '❌', // Cross mark
|
||||
};
|
||||
|
||||
@@ -24,6 +25,7 @@ export default function Statistics({ statistics }: StatisticsProps) {
|
||||
statistics.solvedIn4 +
|
||||
statistics.solvedIn5 +
|
||||
statistics.solvedIn6 +
|
||||
statistics.solvedIn7 +
|
||||
statistics.failed;
|
||||
|
||||
const stats = [
|
||||
@@ -33,6 +35,7 @@ export default function Statistics({ statistics }: StatisticsProps) {
|
||||
{ attempts: 4, count: statistics.solvedIn4, badge: BADGES[4] },
|
||||
{ attempts: 5, count: statistics.solvedIn5, badge: BADGES[5] },
|
||||
{ attempts: 6, count: statistics.solvedIn6, badge: BADGES[6] },
|
||||
{ attempts: 7, count: statistics.solvedIn7, badge: BADGES[7] },
|
||||
{ attempts: 'Failed', count: statistics.failed, badge: BADGES.failed },
|
||||
];
|
||||
|
||||
|
||||
@@ -17,6 +17,7 @@ export interface Statistics {
|
||||
solvedIn4: number;
|
||||
solvedIn5: number;
|
||||
solvedIn6: number;
|
||||
solvedIn7: number;
|
||||
failed: number;
|
||||
}
|
||||
|
||||
@@ -64,7 +65,12 @@ export function useGameState() {
|
||||
// Load statistics
|
||||
const storedStats = localStorage.getItem(STATS_KEY);
|
||||
if (storedStats) {
|
||||
setStatistics(JSON.parse(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,
|
||||
@@ -73,6 +79,7 @@ export function useGameState() {
|
||||
solvedIn4: 0,
|
||||
solvedIn5: 0,
|
||||
solvedIn6: 0,
|
||||
solvedIn7: 0,
|
||||
failed: 0,
|
||||
};
|
||||
setStatistics(newStats);
|
||||
@@ -98,6 +105,7 @@ export function useGameState() {
|
||||
case 4: newStats.solvedIn4++; break;
|
||||
case 5: newStats.solvedIn5++; break;
|
||||
case 6: newStats.solvedIn6++; break;
|
||||
case 7: newStats.solvedIn7++; break;
|
||||
}
|
||||
} else {
|
||||
newStats.failed++;
|
||||
@@ -112,7 +120,7 @@ export function useGameState() {
|
||||
|
||||
const newGuesses = [...gameState.guesses, guess];
|
||||
const isSolved = correct;
|
||||
const isFailed = !correct && newGuesses.length >= 6;
|
||||
const isFailed = !correct && newGuesses.length >= 7;
|
||||
|
||||
const newState = {
|
||||
...gameState,
|
||||
|
||||
Reference in New Issue
Block a user