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).
This commit is contained in:
-101
@@ -1,101 +0,0 @@
|
||||
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;
|
||||
}
|
||||
Reference in New Issue
Block a user