feat: implement Phase 30 - useGameStatus hook
Extract game status logic into dedicated hook following vim-maze pattern: New Module Structure: - src/useGameStatus/types.ts: GameStatus and GameStatusManager types - src/useGameStatus/useGameStatus.ts: Hook implementation - src/useGameStatus/index.ts: Public exports Hook Implementation: - State machine with 5 states (waiting/started/paused/game-over/game-won) - Methods: startGame, togglePause, quitGame, setGameStatus - Clean state transitions with useState - Simpler than vim-maze (no intermediate 'has-key' state) Updated Core Files: - src/useGame.ts: Use useGameStatus() instead of inline useState - Compose gameStatusManager into GameManager - Cleaner separation of concerns - src/types.ts: Import and re-export GameStatus types - GameManager extends GameStatusManager (intersection type) - Single source of truth for status types - src/index.ts: Export useGameStatus hook publicly Benefits: - Reusable state machine - Easier to test in isolation - Follows unified API architecture - Matches vim-maze patterns State Transitions: waiting → startGame() → started ↔ togglePause() ↔ paused started → (win/lose) → game-won/game-over * → quitGame() → waiting Phase 30 complete. Next: Phase 40 (useCursor composition).
This commit is contained in:
+6
-17
@@ -1,13 +1,16 @@
|
||||
import { useState, useEffect } from 'react';
|
||||
import type { GameManager, GameOptions, GameStatus } from './types';
|
||||
import type { GameManager, GameOptions } from './types';
|
||||
import { useBoard } from './useBoard/useBoard';
|
||||
import { useGameStatus } from './useGameStatus';
|
||||
|
||||
export function useGame(options: GameOptions = {}, platformHook?: unknown): GameManager {
|
||||
const { difficulty = 'easy' } = options;
|
||||
const board = useBoard();
|
||||
const { containerRef, renderBoard, generateBoard } = board;
|
||||
|
||||
const [gameStatus, setGameStatus] = useState<GameStatus>('waiting');
|
||||
const gameStatusManager = useGameStatus();
|
||||
const { gameStatus } = gameStatusManager;
|
||||
|
||||
const [keyLog, setKeyLog] = useState<{ key: string; timestamp: number }[]>([]);
|
||||
|
||||
useEffect(() => {
|
||||
@@ -26,21 +29,7 @@ export function useGame(options: GameOptions = {}, platformHook?: unknown): Game
|
||||
const gameManager: GameManager = {
|
||||
containerRef,
|
||||
renderBoard,
|
||||
gameStatus,
|
||||
setGameStatus,
|
||||
startGame: () => {
|
||||
setGameStatus('started');
|
||||
},
|
||||
togglePause: (pause?: boolean) => {
|
||||
if (typeof pause === 'boolean') {
|
||||
setGameStatus(pause ? 'paused' : 'started');
|
||||
} else {
|
||||
setGameStatus(prev => prev === 'paused' ? 'started' : 'paused');
|
||||
}
|
||||
},
|
||||
quitGame: () => {
|
||||
setGameStatus('waiting');
|
||||
},
|
||||
...gameStatusManager,
|
||||
cursor: {},
|
||||
scoreManager: {
|
||||
timeValue: 0,
|
||||
|
||||
Reference in New Issue
Block a user