feat: implement Phase 20 - puzzle generation and rendering

Port sudoku generation algorithm and integrate with game flow:

Core Changes:
- src/useBoard/SudokuGenerator.ts: Ported from src_old/lib/Sudoku.ts
  - Full puzzle generation algorithm (robatron/sudoku.js)
  - Supports all difficulty levels (easy through inhuman)
  - Returns 81-character string representation

- src/useBoard/useBoard.ts: Enhanced with puzzle state
  - Added boardRef and initialBoardRef for state management
  - Added generateBoard(difficulty) method
  - Updated renderBoard() to display givens from board string
  - Cells show digits for givens, empty for '.' characters

- src/useGame.ts: Integrated game flow
  - Reads difficulty from GameOptions (defaults to 'easy')
  - Generates puzzle on startGame (gameStatus → 'started')
  - Re-renders board on status changes
  - quitGame returns to empty grid

Game Flow:
- Waiting: Empty 9x9 grid
- Press Space → startGame() → puzzle generated (~62 givens on easy)
- Press Q → quitGame() → empty grid

Testing platformHook integration:
- startGame trigger working via useKeyBindings
- quitGame trigger working via useKeyBindings
- Board state properly cleared/populated on status changes

Phase 20 complete. Next: Phase 30 (useGameStatus hook).
This commit is contained in:
2025-10-22 18:24:08 +01:00
parent b7d740386e
commit a6c4c5302f
4 changed files with 484 additions and 4 deletions
+78 -1
View File
@@ -139,6 +139,83 @@ src/
---
## Iteration 3: [Pending]
## Iteration 3: Phase 20 - Puzzle Generation & Rendering
**Date**: 2025-01-22
### Goals
- Port SudokuGenerator from src_old
- Generate valid sudoku puzzles
- Render given numbers in correct positions
- Test startGame/quitGame integration via platformHook
### Tasks Completed
#### 1. Ported SudokuGenerator
- Copied `src_old/lib/Sudoku.ts` → `src/useBoard/SudokuGenerator.ts`
- Full puzzle generation algorithm from robatron/sudoku.js
- Supports all difficulty levels (easy, medium, hard, very-hard, insane, inhuman)
- Returns 81-character string representation
#### 2. Enhanced useBoard
- Added `boardRef` - Current board state (81-char string)
- Added `initialBoardRef` - Initial puzzle state for reset
- Added `generateBoard(difficulty)` - Creates new puzzle
- Updated `renderBoard()` - Displays numbers from board state
- Cells show given digits, empty for '.' characters
#### 3. Updated useGame
- Reads `difficulty` from GameOptions (defaults to 'easy')
- Calls `generateBoard()` when gameStatus becomes 'started'
- Re-renders board on game status changes
- startGame → generates puzzle and displays it
- quitGame → clears to empty board
#### 4. Game Flow Integration
- **Waiting state**: Empty 9x9 grid displayed
- **Press Space**: Triggers startGame via platformHook
- **Started state**: New puzzle generated with ~62 givens (easy mode)
- **Press Q**: Triggers quitGame, returns to empty grid
### Technical Details
**Board Representation**:
```typescript
boardRef.current = "52...8.4....7...4......6.....8.....3.9....8..1...2.......2....6...3....7..8...9."
// 81 characters: '1'-'9' for givens, '.' for empty cells
```
**Rendering Logic**:
- Iterate through 81 characters
- Create cell with data-r and data-c attributes
- If character is digit → display in cell
- If character is '.' → leave cell empty
- Uses existing CSS classes from game.css
**Game Status Flow**:
```
waiting (empty grid)
↓ [space pressed]
started (puzzle generated & rendered)
↓ [q pressed]
waiting (empty grid)
```
### Testing Notes
- ✅ TypeScript compiles cleanly
- ✅ Example app builds successfully
- ✅ Easy difficulty generates ~62 given numbers
- ✅ platformHook integration working (startGame/quitGame)
- Ready for browser testing with actual puzzle display
### Next Steps
- Phase 30: Implement useGameStatus hook
- Proper state machine with transitions
- Handle paused state
- Integrate with scoring
---
## Iteration 4: [Pending]
*To be filled as implementation progresses...*