diff --git a/IMPLEMENTATION.md b/IMPLEMENTATION.md index c813594..42ff78f 100644 --- a/IMPLEMENTATION.md +++ b/IMPLEMENTATION.md @@ -1544,6 +1544,167 @@ Hard mode (100 points/hint): --- -## Iteration 15: [Pending] +## Iteration 15: Game Over Logic + +**Date**: 2025-01-22 + +### Goals +- Implement time limit for gameplay +- Implement hint limit based on penalty points +- Provide clear feedback on why game ended +- Make time limit configurable via game options + +### Tasks Completed + +#### 1. Added Time Limit Configuration +**File: `src/types.ts`** + +**GameOptions Extended:** +```typescript +export type GameOptions = { + difficulty?: Difficulty; + timeLimit?: number; // In seconds, default 600 (10 minutes) +}; +``` + +**Default:** 10 minutes (600 seconds) for all difficulty levels +**Rationale:** Harder puzzles naturally take longer, creating appropriate challenge + +#### 2. Implemented Game Over Triggers +**File: `src/useScore/useScore.ts`** + +**Two conditions trigger game-over:** + +**Condition 1: Time Limit Exceeded** +```typescript +const timeLimitMs = timeLimit * 1000; +if (timeValue >= timeLimitMs) { + setGameOverReason("Time's up!"); + setGameStatus('game-over'); + return; +} +``` + +**Condition 2: Hint Penalty Limit** +```typescript +const hintPenalty = hintsUsed * HINT_PENALTY[difficulty]; +if (hintPenalty >= 500) { + setGameOverReason('Too many hints!'); + setGameStatus('game-over'); + return; +} +``` + +**Hint Limits by Difficulty:** +- Easy (25 pts/hint): 20 hints max → 500 points +- Medium (50 pts/hint): 10 hints max → 500 points +- Hard (100 pts/hint): 5 hints max → 500 points + +#### 3. Added Game Over Reason Tracking +**ScoreManager Extended:** +```typescript +export type ScoreManager = { + // ... existing fields + gameOverReason: string | null; // "Time's up!" or "Too many hints!" +}; +``` + +**Reason Management:** +- Set when game-over triggered +- Reset on new game start +- Displayed to player in UI + +#### 4. Updated Game Lifecycle +**Status Flow:** +``` +waiting → started → [time/hints exceeded] → game-over + → [puzzle complete] → game-won + +game-over → [press space] → waiting → started (new game) +``` + +**Timer Behavior:** +- Stops on game-over +- Stops on game-won +- Resets on waiting + +#### 5. Updated Example App Display +**Game Over Message:** +```tsx +{gameStatus === "game-over" && ( +
{gameOverReason || "Game Over!"} Press space to restart
+)} +``` + +Shows specific reason: +- "Time's up! Press space to restart" +- "Too many hints! Press space to restart" + +### Technical Details + +**Check Frequency:** +- Both checks run on every render during 'started' state +- useEffect dependencies: `[gameStatus, timeValue, hintsUsed, difficulty, timeLimit]` +- Checks happen before win condition check + +**Priority:** +1. Game-over checks (time, hints) +2. Win condition check (board complete) + +**Time Limit Examples:** +``` +Default (10 minutes): +- Player has 600 seconds to complete puzzle +- At 600s: game-over triggered + +Custom (5 minutes): +- GameOptions: { timeLimit: 300 } +- Player has 300 seconds to complete +``` + +**Hint Limit Examples:** +``` +Easy mode (25 pts/hint, 500 limit): +- Hint 1-19: OK +- Hint 20: 20 × 25 = 500 → game-over + +Hard mode (100 pts/hint, 500 limit): +- Hint 1-4: OK +- Hint 5: 5 × 100 = 500 → game-over +``` + +### Design Rationale + +**Why Same Time Limit for All Difficulties?** +- Harder puzzles naturally take longer to solve +- Creates appropriate pressure at each level +- Simple and consistent rule + +**Why 500 Point Hint Limit?** +- Half of max score (1000) +- Prevents hint abuse +- Scales appropriately with difficulty: + - Easy: More hints allowed (puzzle easier) + - Hard: Fewer hints allowed (puzzle harder) + +**Why Two Separate Conditions?** +- Time limit: Encourages speed +- Hint limit: Encourages skill +- Both contribute to challenge + +### Build Status +- ✅ TypeScript compiles cleanly +- ✅ Both game-over conditions working +- ✅ Reasons displayed correctly +- ✅ Timer stops on game-over +- ✅ Configurable time limit working + +### Next Steps +- Final polish and testing +- Update UNIFIED_API.md + +--- + +## Iteration 16: [Pending] *To be filled as implementation progresses...* diff --git a/example/src/App.tsx b/example/src/App.tsx index 37b3ed5..84c2b51 100644 --- a/example/src/App.tsx +++ b/example/src/App.tsx @@ -8,7 +8,7 @@ function App() { const [difficulty, setDifficulty] = useStatePress space to start
} {gameStatus === "started" &&Use hjkl to navigate • Press i to edit • Press Shift+H for hint • Press q to quit
} - {gameStatus === "game-over" &&Game Over! Press space to restart
} + {gameStatus === "game-over" &&{gameOverReason || "Game Over!"} Press space to restart
} {gameStatus === "game-won" &&You Won! Press space to play again
}