refactor: separate score calculation from score management

BREAKING CHANGES:
- Remove timeLimit from GameOptions (use gameOver function instead)
- Remove finalScore from ScoreManager (pure data collection only)
- Remove rows/cols parameters from useScore
- Remove finalScore calculation logic from useScore hook

ADDITIONS:
- Create calculateMazeScore() utility function
- ScoreManager now only returns raw metrics: timeValue, keystrokes, optimalSteps, efficiency, distToKey, distToExit
- Score calculation moved to consumer (calculateMazeScore takes scoreManager + mazeSize)
- Example app now uses calculateMazeScore to compute final score on game-won

BENEFITS:
- ScoreManager is now a pure data collector with no side effects
- Scoring algorithm is reusable and testable in isolation
- Game-over conditions fully controlled via gameOver option
- Clear separation of concerns: collection vs calculation
This commit is contained in:
2025-11-02 17:04:21 +00:00
parent 060c8abb24
commit 0749aba648
8 changed files with 46 additions and 41 deletions
+9 -2
View File
@@ -1,6 +1,7 @@
import { useGame, version } from "../../src";
import { useGame, version, calculateMazeScore } from "../../src";
import { useKeyBindings } from "./useKeyBindings";
import { useIsMobile } from "./useIsMobile";
import { useMemo } from "react";
import '../../src/game.css';
function App() {
@@ -10,7 +11,13 @@ function App() {
const gameManager = useGame({ cols, rows }, useKeyBindings);
const { containerRef, gameStatus, scoreManager } = gameManager;
const { timeValue, keystrokes, optimalSteps, efficiency, finalScore } = scoreManager;
const { timeValue, keystrokes, optimalSteps, efficiency } = scoreManager;
const mazeSize = rows * cols;
const finalScore = useMemo(
() => gameStatus === "game-won" ? calculateMazeScore(scoreManager, mazeSize) : null,
[gameStatus, scoreManager, mazeSize]
);
const formatTime = (ms: number) => {
const seconds = Math.floor(ms / 1000);