Files
vim-sudoku/src_failed/useGame.ts
T
pastilhas 9292b83dd0 feat: prepare vim-sudoku for unified API implementation
- Archive previous implementation attempt (src -> src_failed)
- Create comprehensive IMPLEMENTATION_PLAN.md with phased approach
- Create IMPLEMENTATION.md to track implementation progress
- Update example app to match vim-maze patterns:
  - Simplify UI to desktop-only (no mobile support)
  - Add score metrics display (time, keystrokes, final score)
  - Update instructions for sudoku-specific keys (hjkl, i for edit)
  - Remove unnecessary mobile hooks

Phase 5 complete. Ready to begin Phase 10 (Setup & Core Types).
2025-10-22 18:08:33 +01:00

101 lines
2.9 KiB
TypeScript

import { useEffect } from 'react';
import { useBoard } from './useBoard';
import { useCursor } from './useCursor';
import { useGameStatus } from './useGameStatus';
import { useScore } from './useScore';
import type { GameManager, GameOptions } from './types';
export function useGame(options: GameOptions, platformHook?: unknown): GameManager {
const board = useBoard();
const gameStatusManager = useGameStatus();
const { cursor, keyManager } = useCursor(board);
const scoreManager = useScore({
board,
gameStatusManager,
keystrokeCount: keyManager.keyLog.length
});
useEffect(() => {
board.generateBoard('medium');
}, [board]);
useEffect(() => {
const { gameStatus } = gameStatusManager;
if (gameStatus === 'waiting') {
board.renderBoard();
} else {
board.renderBoard();
const container = board.containerRef.current;
if (container) {
const pos = cursor.position();
const cellEl = container.querySelector(`.sudoku-cell[data-row="${pos.row}"][data-col="${pos.col}"]`) as HTMLElement;
if (cellEl) {
cellEl.classList.add('cursor');
if (cursor.mode() === 'edit') {
cellEl.classList.add('edit-mode');
}
}
}
}
}, [gameStatusManager.gameStatus, board, cursor]);
useEffect(() => {
const container = board.containerRef.current;
if (!container) return;
const handleCellClick = (e: MouseEvent) => {
const target = e.target as HTMLElement;
const cellEl = target.closest('.sudoku-cell') as HTMLElement;
if (!cellEl) return;
const row = parseInt(cellEl.dataset.row || '0');
const col = parseInt(cellEl.dataset.col || '0');
const currentPos = cursor.position();
if (currentPos.row !== row || currentPos.col !== col) {
cursor.move(row - currentPos.row, col - currentPos.col, 1);
}
};
container.addEventListener('click', handleCellClick);
return () => container.removeEventListener('click', handleCellClick);
}, [board, cursor]);
const startGame = () => {
board.generateBoard('medium');
gameStatusManager.startGame();
};
const togglePause = (pause?: boolean) => {
gameStatusManager.togglePause(pause);
};
const quitGame = () => {
gameStatusManager.quitGame();
};
const gameManager: GameManager = {
containerRef: board.containerRef,
renderBoard: board.renderBoard,
gameStatus: gameStatusManager.gameStatus,
setGameStatus: gameStatusManager.setGameStatus,
startGame,
togglePause,
quitGame,
cursor,
scoreManager,
keyLog: keyManager.keyLog,
clearKeyLog: keyManager.clearKeyLog,
getKeyLog: keyManager.getKeyLog,
board,
solveBoard: board.solveBoard,
resetBoard: board.resetBoard
};
if (typeof platformHook === 'function') {
platformHook(gameManager);
}
return gameManager;
}