# vim-sudoku Unified API Implementation Plan ## Overview Port vim-sudoku to the unified API architecture established by vim-maze, following the composable hook pattern with `useGame()` as the single entry point. ## Goals 1. Follow unified API architecture from UNIFIED_API.md 2. Maintain vim-maze patterns and conventions 3. Preserve all working functionality from src_old 4. Support platform integration via optional platformHook parameter 5. Enable code reuse across games (vim-maze, vim-sudoku, vim-snake) ## Architecture ### Core Composition ```tsx // Inside useGame: const board = useBoard(); const gameStatusManager = useGameStatus(); const { cursor, keyManager } = useCursor(board, gameStatusManager); const scoreManager = useScore({ board, gameStatusManager, keyManager }); // Returns unified GameManager interface ``` ## File Structure ``` src/ ├── index.ts # Main package exports ├── types.ts # Re-exports all types from modules ├── useGame.ts # Main orchestrator hook ├── useGameStatus/ │ ├── index.ts # Public exports │ ├── types.ts # GameStatus, GameStatusManager │ └── useGameStatus.ts # Game state management ├── useBoard/ │ ├── index.ts # Public exports │ ├── types.ts # SudokuBoard, SudokuCell, Difficulty, BoardManager │ ├── useBoard.ts # Board management hook │ ├── SudokuGenerator.ts # Puzzle generation (from src_old/lib/Sudoku.ts) │ └── SudokuRenderer.ts # DOM rendering for sudoku grid ├── useCursor/ │ ├── index.ts # Public exports │ ├── types.ts # CursorManager, CursorMode, VimMotionSystem, CellEditor │ ├── useCursor.ts # Main cursor/input hook │ ├── useCellEditor.ts # Cell editing logic (analog to useHero) │ ├── useCursorRender.ts # Cursor rendering on DOM (analog to useHeroRender) │ ├── useVimMotions.ts # Vim keybinding system │ └── useGameKeys.ts # Game-specific key handling └── useScore/ ├── index.ts # Public exports ├── types.ts # TimerManager, ScoreManager ├── useScore.ts # Main scoring hook └── useTimer.ts # Timer state management ``` ## Implementation Steps ### Phase 5: Prepare Example App - [x] Update example/src/App.tsx to match vim-maze structure - [x] Update App to display score metrics (time, keystrokes, final score) - [x] Update App to show game status messages - [x] Update App instructions for sudoku-specific keys (i for edit) - [x] Keep it simple - no mobile support for now ### Phase 10: Setup & Core Types - [ ] Create clean src/ directory structure - [ ] Define all types in module-specific types.ts files - [ ] Create index.ts exports for each module - [ ] Set up main types.ts re-export file ### Phase 20: useBoard Hook - [x] Port SudokuGenerator from src_old/lib/Sudoku.ts (Robatron's implementation) - [x] Basic puzzle generation and rendering - [x] Game flow integration (startGame/quitGame) ### Phase 21: Replace with Better Generation Algorithm - [ ] Replace Robatron's algorithm with pattern-based generation - [ ] Implement SudokuGenerator class (from src_old/sudoku/) - [ ] Implement SudokuRenderer class for clean separation - [ ] Update useBoard to use new classes - [ ] Store both puzzle and solution refs - [ ] Port unit tests for validation - [ ] Three difficulty levels with configurable cell removal ### Phase 30: useGameStatus Hook - [x] Implement GameStatus state machine - 'waiting' → 'started' → 'game-won' / 'game-over' - 'paused' state support - [x] Methods: startGame, togglePause, quitGame, setGameStatus - [x] Extract from inline useState in useGame - [x] Create dedicated hook following vim-maze pattern ### Phase 40: useCursor Hook Composition #### 40.1 useCellEditor (analog to useHero) - [ ] Manage cursor position (row, col) - [ ] Handle cell editing operations - [ ] Validate edits against isGiven cells - [ ] Trigger validation on cell changes - [ ] Handle win condition detection #### 40.2 useVimMotions - [ ] Port vim motion system from vim-maze - [ ] Support: h/j/k/l, ^/$, g/G, . (repeat) - [ ] Support: i (insert), r (replace), x (delete) - [ ] Count prefix handling (e.g., 5j) - [ ] Mode transitions (normal ↔ edit) #### 40.3 useGameKeys - [ ] Keyboard event listener - [ ] Route keys through vim motion processor - [ ] Execute cursor movements - [ ] Execute cell editing commands - [ ] Track keystroke history - [ ] Handle game-specific keys (q, p, space) #### 40.4 useCursorRender (analog to useHeroRender) - [ ] Render cursor highlight on current cell - [ ] Show edit mode indicator - [ ] Flash animations (valid/invalid/locked) - [ ] Highlight conflict cells #### 40.5 useCursor Main Hook - [ ] Compose cellEditor, vimMotions, gameKeys, cursorRender - [ ] Return unified CursorManager interface - [ ] Split keyManager for useGame composition ### Phase 50: useScore Hook - [ ] Port timer from src_old/useScore/hooks/useTimer.ts - [ ] Track keystrokes from keyManager.keyLog - [ ] Calculate efficiency metrics - [ ] Detect win/loss conditions based on completion - [ ] Compute final score on game-won ### Phase 60: useGame Orchestrator - [ ] Compose all hooks (board, cursor, gameStatus, score) - [ ] Handle initial board generation - [ ] Coordinate rendering updates - [ ] Expose unified GameManager interface - [ ] Support optional platformHook parameter ### Phase 70: Testing & Refinement - [ ] Test with example app - [ ] Verify all vim motions work - [ ] Verify edit mode (i/r/x) works - [ ] Verify validation and conflicts work - [ ] Verify win condition triggers - [ ] Test platform hook integration - [ ] Update UNIFIED_API.md with sudoku specifics ## Key Design Decisions ### 1. Board Representation **Choice**: Use 2D array of SudokuCell objects ```typescript type SudokuCell = { value: string; // '1'-'9' or '' isGiven: boolean; // true for puzzle clues hasConflict: boolean; // validation state }; type SudokuBoard = SudokuCell[][]; ``` **Rationale**: Easier to work with than 81-char string, matches vim-maze pattern of using structured data. ### 2. Cell Editing (analog to Hero Movement) **Choice**: useCellEditor hook manages cell editing state - Similar to useHero managing hero position in maze - Handles validation before setting values - Triggers game status changes on completion **Rationale**: Keeps editing logic separate from cursor movement, following vim-maze separation of concerns. ### 3. Edit Mode vs Insert Mode **Choice**: Two modes - 'normal' and 'edit' - Normal mode: vim navigation + commands (i/r/x/d) - Edit mode: digit entry (1-9) + erase (x/Backspace) - i = insert (enter edit mode on empty cell) - r = replace (enter edit mode on filled cell) - Escape/Enter = exit edit mode **Rationale**: Matches vim philosophy and src_old behavior. ### 4. Rendering Strategy **Choice**: Keep rendering separate from state - SudokuRenderer handles DOM generation - useCursorRender handles cursor highlighting - useBoard calls renderer with board data **Rationale**: Matches vim-maze pattern (MazeRenderer + useHeroRender). ### 5. Validation Approach **Choice**: Validate on setCell, show conflicts visually - Real-time validation when setting digits - Flash animations for feedback - Highlight conflicting cells temporarily - Don't prevent invalid moves (optional strictMode) **Rationale**: Provides immediate feedback without blocking player exploration. ## Type Mappings (vim-maze → vim-sudoku) | vim-maze | vim-sudoku | Notes | |----------|------------|-------| | MazeCell[][] | SudokuBoard | Board structure | | Coord | Coord | Same (row, col) | | useHero | useCellEditor | Cell editing vs movement | | useHeroRender | useCursorRender | Visual feedback | | MazeGenerator | SudokuGenerator | Puzzle generation | | MazeRenderer | SudokuRenderer | Grid rendering | | hero.moveTo | cellEditor.setValue | Action semantics | | 'entrance'/'exit'/'key' | 'isGiven'/'value' | Cell metadata | ## Differences from vim-maze 1. **No pathfinding**: Simple grid bounds checking 2. **Edit mode**: Need mode toggle for digit entry 3. **Validation**: Real-time conflict detection 4. **Win condition**: Complete + valid vs reach exit 5. **No animation**: Cursor moves instantly (no multi-step) 6. **Board generation**: On-demand vs one-time initialization ## Success Criteria - [ ] All functionality from src_old preserved - [ ] Follows unified API architecture - [ ] Types match vim-maze patterns - [ ] Hook composition mirrors vim-maze - [ ] Example app works identically to src_old version - [ ] Platform hook integration works - [ ] Code is clean, documented, and maintainable - [ ] UNIFIED_API.md updated with vim-sudoku section ## Notes - Keep game.css from src_old for styling - Port sudoku generation algorithm directly (working code) - Maintain existing vim keybindings (h/j/k/l, ^/$, g/G, ., i/r/x) - Preserve flash animations for visual feedback - Follow AGENTS.md conventions throughout