diff --git a/example/src/App.tsx b/example/src/App.tsx
index 043af5e..78ea0e7 100644
--- a/example/src/App.tsx
+++ b/example/src/App.tsx
@@ -1,4 +1,4 @@
-import { useGame, version, calculateMazeScore } from "../../src";
+import { useGame, version, calculateMazeScore, type ScoreManager } from "../../src";
import { useKeyBindings } from "./useKeyBindings";
import { useIsMobile } from "./useIsMobile";
import { useMemo } from "react";
@@ -9,7 +9,12 @@ function App() {
const cols = isMobile ? 12 : 32;
const rows = isMobile ? 8 : 24;
- const gameManager = useGame({ cols, rows }, useKeyBindings);
+ const gameOver = (scroreManager: ScoreManager) => {
+ console.log('gameOver', scroreManager);
+ return scoreManager.efficiency < 70;
+ }
+
+ const gameManager = useGame({ cols, rows, gameOver }, useKeyBindings);
const { containerRef, gameStatus, scoreManager } = gameManager;
const { timeValue, keystrokes, optimalSteps, efficiency } = scoreManager;
@@ -30,41 +35,41 @@ function App() {
VIMazing vim-maze v{version} example
- {(gameStatus === "started" || gameStatus === "has-key" || gameStatus === "game-won") && (
-
-
-
Time
-
{formatTime(timeValue)}
-
-
-
Keystrokes
-
{keystrokes}
-
- {optimalSteps > 0 && (
- <>
-
-
-
Optimal Steps
-
{optimalSteps}
-
-
-
Efficiency
-
{efficiency}%
-
- >
- )}
- {gameStatus === "game-won" && finalScore && (
- <>
-
-
-
Final Score
-
{finalScore}
-
- >
- )}
-
- )}
-
+ {(gameStatus === "started" || gameStatus === "has-key" || gameStatus === "game-won") && (
+
+
+
Time
+
{formatTime(timeValue)}
+
+
+
Keystrokes
+
{keystrokes}
+
+ {optimalSteps > 0 && (
+ <>
+
+
+
Optimal Steps
+
{optimalSteps}
+
+
+
Efficiency
+
{efficiency}%
+
+ >
+ )}
+ {gameStatus === "game-won" && finalScore && (
+ <>
+
+
+
Final Score
+
{finalScore}
+
+ >
+ )}
+
+ )}
+
diff --git a/src/formatGameInfo.ts b/src/formatGameInfo.ts
new file mode 100644
index 0000000..5a8fffe
--- /dev/null
+++ b/src/formatGameInfo.ts
@@ -0,0 +1,54 @@
+import type { GameManager } from './types';
+import { gameInfo as baseGameInfo } from './gameInfo';
+
+/**
+ * Format the gameOver condition as a readable string
+ */
+function formatGameOverCondition(condition: GameManager['gameOverCondition']): string {
+ if (condition === undefined) {
+ return 'None - game continues indefinitely';
+ }
+
+ if (condition === true) {
+ return 'Always (immediate game over)';
+ }
+
+ if (condition === false) {
+ return 'Never (game never ends)';
+ }
+
+ if (typeof condition === 'function') {
+ // Try to get the function source
+ const source = condition.toString();
+ // Clean up and format
+ const cleaned = source
+ .replace(/\s+/g, ' ')
+ .replace(/=>/, '→')
+ .trim();
+ return cleaned.length > 200 ? cleaned.substring(0, 197) + '...' : cleaned;
+ }
+
+ return 'Unknown condition';
+}
+
+/**
+ * Enrich gameInfo with runtime gameOver condition
+ * Returns the base gameInfo plus runtime condition info
+ */
+export function enrichGameInfo(gameManager: GameManager) {
+ const runtimeCondition = formatGameOverCondition(gameManager.gameOverCondition);
+
+ return {
+ ...baseGameInfo,
+ gameOverRuntime: {
+ condition: runtimeCondition,
+ type: gameManager.gameOverCondition === undefined
+ ? 'none'
+ : typeof gameManager.gameOverCondition === 'boolean'
+ ? 'static'
+ : 'function',
+ },
+ };
+}
+
+export { formatGameOverCondition };
diff --git a/src/index.ts b/src/index.ts
index 5f641b8..0447913 100644
--- a/src/index.ts
+++ b/src/index.ts
@@ -3,6 +3,7 @@ export * from './useGame';
export * from './useGameStatus';
export { gameInfo } from './gameInfo';
export { calculateMazeScore } from './useScore';
+export { enrichGameInfo, formatGameOverCondition } from './formatGameInfo';
import { version } from '../package.json';
export type { GameInfo } from './gameInfo';
export { version };
diff --git a/src/types.ts b/src/types.ts
index 517d7b7..ae34e9b 100644
--- a/src/types.ts
+++ b/src/types.ts
@@ -29,4 +29,5 @@ export type GameManager = {
hero: HeroManager;
renderer: HeroRenderManager;
scoreManager: ScoreManager;
+ gameOverCondition?: boolean | ((scoreManager: ScoreManager) => boolean);
} & GameStatusManager & GameKeyManager;
diff --git a/src/useGame.ts b/src/useGame.ts
index f2f7fb4..f375745 100644
--- a/src/useGame.ts
+++ b/src/useGame.ts
@@ -25,6 +25,7 @@ export function useGame(options: GameOptions, platformHook?: unknown): GameManag
hero,
renderer,
scoreManager,
+ gameOverCondition: gameOver,
}
if (typeof platformHook === 'function') {