diff --git a/src/types.ts b/src/types.ts index 0e5f4ad..49ae5cc 100644 --- a/src/types.ts +++ b/src/types.ts @@ -12,6 +12,7 @@ export type GameOptions = { rows: number; cols: number; timeLimit?: number; + gameOver?: boolean | ((scoreManager: ScoreManager) => boolean); }; export type KeyLogEntry = { key: string; timestamp: number }; diff --git a/src/useGame.ts b/src/useGame.ts index c93cb45..b3008fd 100644 --- a/src/useGame.ts +++ b/src/useGame.ts @@ -6,7 +6,7 @@ import { useHeroRender } from './useCursor'; import { useScore } from './useScore'; export function useGame(options: GameOptions, platformHook?: unknown): GameManager { - const { cols, rows, timeLimit = 600 } = options; + const { cols, rows, timeLimit = 600, gameOver } = options; const board = useBoard(cols, rows); const { containerRef, renderBoard } = board; const gameStatusManager = useGameStatus(); @@ -14,7 +14,7 @@ export function useGame(options: GameOptions, platformHook?: unknown): GameManag const hero = cursor.hero; const renderer = useHeroRender({ gameStatus: gameStatusManager.gameStatus, board, hero }); - const scoreManager = useScore({ board, hero, gameStatusManager, keyManager, rows, cols, timeLimit }); + const scoreManager = useScore({ board, hero, gameStatusManager, keyManager, rows, cols, timeLimit, gameOver }); const gameManager: GameManager = { containerRef, diff --git a/src/useScore/useScore.ts b/src/useScore/useScore.ts index 7d18606..155950b 100644 --- a/src/useScore/useScore.ts +++ b/src/useScore/useScore.ts @@ -5,6 +5,7 @@ import { useScorePaths } from "./useScorePaths"; import type { BoardManager } from "../useBoard/types"; import type { GameStatusManager } from "../useGameStatus/types"; import type { UseHeroType } from "../useCursor/types"; +import type { ScoreManager } from "./types"; type UseScoreParams = { board: BoardManager; @@ -14,9 +15,10 @@ type UseScoreParams = { rows: number; cols: number; timeLimit: number; + gameOver?: boolean | ((scoreManager: ScoreManager) => boolean); }; -export function useScore({ board, hero, gameStatusManager, keyManager, rows, cols, timeLimit }: UseScoreParams) { +export function useScore({ board, hero, gameStatusManager, keyManager, rows, cols, timeLimit, gameOver }: UseScoreParams) { const timer = useTimer(); const { gameStatus, setGameStatus } = gameStatusManager; const { timeValue, startTimer, stopTimer, resetTimer } = timer; @@ -64,6 +66,30 @@ export function useScore({ board, hero, gameStatusManager, keyManager, rows, col } }, [gameStatus, timeValue, timeLimit, setGameStatus]); + // Check custom gameOver condition if provided + useEffect(() => { + if (gameStatus !== "started" && gameStatus !== "has-key") return; + if (!gameOver) return; + + const scoreManager = { + timeValue, + startTimer, + stopTimer, + resetTimer, + distToKey, + distToExit, + keystrokes, + optimalSteps, + efficiency, + finalScore, + }; + + const shouldGameOver = typeof gameOver === "function" ? gameOver(scoreManager) : gameOver; + if (shouldGameOver) { + setGameStatus("game-over"); + } + }, [gameStatus, gameOver, timeValue, keystrokes, optimalSteps, efficiency, distToKey, distToExit, startTimer, stopTimer, resetTimer, finalScore, setGameStatus]); + useEffect(() => { if (gameStatus !== "game-won") return;