Component ID: PG-012 Version: 1.0.0 Date: January 6, 2026 Status: Implementation Ready Dependencies: PE-001 (Puzzle Engine)
| ADR | Relationship |
|---|---|
| ADR-010: Immutable Puzzle Engine | Foundation spec |
The Randomized Puzzle Generation component extends the existing Sudoku system to support:
- Seed-Based Generation: Reproducible puzzle creation using deterministic random number generation
- Variable Grid Sizes: Support for 4×4, 9×9, 16×16, and 25×25 Sudoku grids
- Difficulty Control: Precise difficulty targeting through strategic cell removal
- Batch Generation: Efficient creation of multiple puzzles with sequential or random seeds
- Puzzle Validation: Ensures unique solutions and solvability guarantees
Current Limitations:
- Static JSON puzzle files limit training data variety
- No ability to reproduce specific puzzles
- Fixed 9×9 grid size only
- LLM learning may overfit to known puzzles
Benefits of Randomized Generation:
- Unlimited Training Data: Generate infinite unique puzzles for LLM learning
- Reproducibility: Seed numbers allow exact puzzle recreation for debugging/testing
- Scalability: Support different grid sizes for complexity scaling
- A/B Testing: Generate matched-difficulty puzzle pairs for benchmarking
- Overfitting Prevention: LLM trains on diverse, never-seen-before puzzles
┌─────────────────────────────────────────────────────────┐
│ MACHINE DREAM PUZZLE SYSTEM │
├─────────────────────────────────────────────────────────┤
│ │
│ ┌───────────────────────────────────────────┐ │
│ │ LLM Sudoku Player (depends on PG) │ │
│ └───────────────────────────────────────────┘ │
│ ↓ │
│ ┌───────────────────────────────────────────┐ │
│ │ PUZZLE GENERATION (PG-012) ← NEW │ │
│ │ │ │
│ │ • Seed-Based Random Generator │ │
│ │ • Variable Grid Sizes (4-25) │ │
│ │ • Difficulty Targeting │ │
│ │ • Batch Generation │ │
│ │ • Validation & Uniqueness │ │
│ └───────────────────────────────────────────┘ │
│ ↓ │
│ ┌───────────────────────────────────────────┐ │
│ │ PUZZLE ENGINE (PE-001) │ │
│ │ (Grid, Validation, Candidates) │ │
│ └───────────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────┘
FR-2.1.1: Deterministic PRNG
- MUST implement seeded pseudo-random number generator (PRNG)
- MUST produce identical puzzle for same seed value
- MUST support seed range: 0 to 2^32-1 (4,294,967,295)
- MUST use seedable algorithm (e.g., Mulberry32, xoshiro128**)
- MUST NOT use Math.random() for puzzle generation
FR-2.1.2: Seed Specification
- MUST accept seed as number parameter
- MUST accept seed as string (parsed to number)
- MUST generate random seed if not provided
- MUST log/return seed used for puzzle generation
- MUST support seed serialization in puzzle metadata
Acceptance Criteria:
// Test 1: Same seed produces identical puzzles
const gen1 = new PuzzleGenerator({ seed: 12345 });
const puzzle1 = gen1.generate();
const gen2 = new PuzzleGenerator({ seed: 12345 });
const puzzle2 = gen2.generate();
expect(puzzle1.grid).toEqual(puzzle2.grid);
// Test 2: Different seeds produce different puzzles
const gen3 = new PuzzleGenerator({ seed: 67890 });
const puzzle3 = gen3.generate();
expect(puzzle3.grid).not.toEqual(puzzle1.grid);
// Test 3: Random seed generation
const genAuto = new PuzzleGenerator(); // No seed
const puzzleAuto = genAuto.generate();
expect(puzzleAuto.seed).toBeDefined();
expect(puzzleAuto.seed).toBeGreaterThan(0);FR-2.2.1: Grid Size Configuration
- MUST support grid sizes: 4×4, 9×9, 16×16, 25×25
- MUST validate grid size is perfect square with integer box size
- MUST adapt box dimensions: 2×2 (4×4), 3×3 (9×9), 4×4 (16×16), 5×5 (25×25)
- MUST support value ranges: 1-4 (4×4), 1-9 (9×9), 1-16 (16×16), 1-25 (25×25)
FR-2.2.2: Size-Specific Generation
- MUST generate valid completed grid for each size
- MUST ensure all constraints satisfied for grid size
- MUST scale cell removal strategy by grid size
- MUST provide difficulty mapping per grid size
FR-2.2.3: Default Behavior
- MUST default to 9×9 grid if size not specified
- MUST preserve backward compatibility with existing code
- MUST validate size parameter before generation
Acceptance Criteria:
// Test 1: 4×4 generation
const gen4 = new PuzzleGenerator({ size: 4, seed: 123 });
const puzzle4 = gen4.generate();
expect(puzzle4.grid.length).toBe(4);
expect(puzzle4.grid[0].length).toBe(4);
expect(Math.max(...puzzle4.grid.flat())).toBeLessThanOrEqual(4);
// Test 2: 9×9 generation (default)
const gen9 = new PuzzleGenerator({ seed: 123 });
const puzzle9 = gen9.generate();
expect(puzzle9.grid.length).toBe(9);
// Test 3: 16×16 generation
const gen16 = new PuzzleGenerator({ size: 16, seed: 123 });
const puzzle16 = gen16.generate();
expect(puzzle16.grid.length).toBe(16);
expect(Math.max(...puzzle16.grid.flat())).toBeLessThanOrEqual(16);
// Test 4: 25×25 generation
const gen25 = new PuzzleGenerator({ size: 25, seed: 123 });
const puzzle25 = gen25.generate();
expect(puzzle25.grid.length).toBe(25);
// Test 5: Invalid size rejected
expect(() => new PuzzleGenerator({ size: 7 }))
.toThrow('Invalid grid size: must be 4, 9, 16, or 25');FR-2.3.1: Difficulty Levels
- MUST support difficulty levels: easy, medium, hard, expert, diabolical
- MUST map difficulty to clue count ranges (size-specific)
- MUST ensure generated puzzles match target difficulty
- MUST validate puzzle difficulty after generation
FR-2.3.2: Difficulty Mapping (9×9 Grid)
| Difficulty | Clue Range | Min Strategy | Characteristics |
|---|---|---|---|
| easy | 36-46 | Naked singles | Many naked singles |
| medium | 32-35 | Hidden singles | Some hidden singles |
| hard | 28-31 | Pairs/pointing | Advanced techniques |
| expert | 24-27 | X-Wing/chains | Minimal backtracking |
| diabolical | 22-23 | Trial & error | Heavy backtracking |
FR-2.3.3: Size-Specific Scaling
- MUST scale clue counts proportionally to grid size
- MUST maintain relative difficulty across sizes
- MUST provide difficulty estimation function
Acceptance Criteria:
// Test 1: Easy puzzle generation
const genEasy = new PuzzleGenerator({
seed: 123,
difficulty: 'easy'
});
const puzzleEasy = genEasy.generate();
const clueCount = countClues(puzzleEasy.grid);
expect(clueCount).toBeGreaterThanOrEqual(36);
expect(clueCount).toBeLessThanOrEqual(46);
// Test 2: Expert puzzle generation
const genExpert = new PuzzleGenerator({
seed: 456,
difficulty: 'expert'
});
const puzzleExpert = genExpert.generate();
const expertClues = countClues(puzzleExpert.grid);
expect(expertClues).toBeGreaterThanOrEqual(24);
expect(expertClues).toBeLessThanOrEqual(27);
// Test 3: Difficulty validation
const difficulty = estimateDifficulty(puzzleEasy.grid);
expect(difficulty).toBe('easy');FR-2.4.1: Solution Uniqueness
- MUST guarantee exactly one solution per generated puzzle
- MUST validate uniqueness before returning puzzle
- MUST retry generation if multiple solutions found
- MUST limit retry attempts (max 100) to prevent infinite loops
FR-2.4.2: Solvability Guarantee
- MUST ensure puzzle is solvable without guessing (for easy/medium)
- MUST verify required strategy complexity matches difficulty
- MUST validate no impossible states created
FR-2.4.3: Symmetry Options
- SHOULD support symmetrical cell removal patterns
- MUST support symmetry types: none, rotational, reflectional, diagonal
- MUST preserve uniqueness when using symmetry
Acceptance Criteria:
// Test 1: Unique solution
const gen = new PuzzleGenerator({ seed: 789 });
const puzzle = gen.generate();
const solutions = findAllSolutions(puzzle.grid, { maxSolutions: 2 });
expect(solutions.length).toBe(1);
// Test 2: Solvability (easy)
const genEasy = new PuzzleGenerator({ seed: 111, difficulty: 'easy' });
const puzzleEasy = genEasy.generate();
const solvable = isSolvableWithoutGuessing(puzzleEasy.grid);
expect(solvable).toBe(true);
// Test 3: Symmetry
const genSym = new PuzzleGenerator({
seed: 222,
symmetry: 'rotational'
});
const puzzleSym = genSym.generate();
expect(hasRotationalSymmetry(puzzleSym.grid)).toBe(true);FR-2.5.1: Multi-Puzzle Generation
- MUST support generating N puzzles in one call
- MUST allow sequential seeds (seed, seed+1, seed+2, ...) or random
- MUST return array of generated puzzles with metadata
- MUST support progress callbacks for long-running batch jobs
FR-2.5.2: Batch Configuration
- MUST allow mixed difficulties in batch
- MUST allow mixed grid sizes in batch
- MUST support parallel generation (optional optimization)
- MUST provide batch summary statistics
Acceptance Criteria:
// Test 1: Sequential seed batch
const batch = generateBatch({
count: 5,
seedStart: 1000,
seedMode: 'sequential',
difficulty: 'medium'
});
expect(batch.length).toBe(5);
expect(batch[0].seed).toBe(1000);
expect(batch[1].seed).toBe(1001);
expect(batch[4].seed).toBe(1004);
// Test 2: Random seed batch
const randomBatch = generateBatch({
count: 10,
seedMode: 'random',
difficulty: 'hard'
});
expect(randomBatch.length).toBe(10);
const seeds = randomBatch.map(p => p.seed);
expect(new Set(seeds).size).toBe(10); // All unique
// Test 3: Mixed difficulty batch
const mixedBatch = generateBatch({
count: 6,
difficulties: ['easy', 'easy', 'medium', 'medium', 'hard', 'hard']
});
expect(mixedBatch.filter(p => p.difficulty === 'easy').length).toBe(2);FR-2.6.1: Metadata Capture
- MUST include seed in puzzle metadata
- MUST include grid size in metadata
- MUST include actual difficulty (estimated)
- MUST include target difficulty (requested)
- MUST include generation timestamp
- MUST include generation time (ms)
FR-2.6.2: Export Formats
- MUST support export to JSON with seed
- MUST support export to string with seed in comment
- MUST support import from seed (regenerate puzzle)
- MUST provide CLI command for generation
Acceptance Criteria:
// Test 1: Metadata completeness
const gen = new PuzzleGenerator({ seed: 5555, difficulty: 'hard' });
const puzzle = gen.generate();
expect(puzzle.seed).toBe(5555);
expect(puzzle.size).toBe(9);
expect(puzzle.targetDifficulty).toBe('hard');
expect(puzzle.actualDifficulty).toBeDefined();
expect(puzzle.generatedAt).toBeDefined();
expect(puzzle.generationTimeMs).toBeGreaterThan(0);
// Test 2: JSON export with seed
const json = puzzleToJSON(puzzle);
expect(json.seed).toBe(5555);
// Test 3: Regeneration from seed
const regenerated = generateFromSeed(5555, { difficulty: 'hard' });
expect(regenerated.grid).toEqual(puzzle.grid);| Operation | Target | Measurement |
|---|---|---|
| 4×4 puzzle generation | < 10ms | Average over 100 puzzles |
| 9×9 puzzle generation | < 100ms | Average over 100 puzzles |
| 16×16 puzzle generation | < 500ms | Average over 100 puzzles |
| 25×25 puzzle generation | < 2000ms | Average over 100 puzzles |
| Uniqueness validation | < 200ms | Per puzzle (9×9) |
| Batch generation (10 puzzles) | < 1000ms | 9×9, medium difficulty |
Rationale: Fast generation enables real-time LLM training data creation and interactive puzzle selection in TUI.
| Component | Maximum Memory | Notes |
|---|---|---|
| Generator instance | < 10KB | PRNG state + config |
| 9×9 puzzle generation | < 50KB | Temporary working space |
| 25×25 puzzle generation | < 500KB | Larger grid overhead |
| Batch (100 puzzles, 9×9) | < 10MB | Acceptable for training |
- Type Safety: 100% TypeScript strict mode
- Test Coverage: Minimum 90% line coverage
- Documentation: JSDoc comments for all public functions
- Reproducibility: 100% deterministic given same seed
- Validation: All generated puzzles must pass uniqueness check
/**
* Configuration for puzzle generation
*/
export interface PuzzleGenerationConfig {
seed?: number; // Random seed (auto-generated if not provided)
size?: 4 | 9 | 16 | 25; // Grid size (default: 9)
difficulty?: DifficultyLevel; // Target difficulty (default: 'medium')
symmetry?: SymmetryType; // Cell removal symmetry (default: 'none')
validateUniqueness?: boolean; // Ensure single solution (default: true)
maxRetries?: number; // Max retry attempts (default: 100)
}
/**
* Generated puzzle with metadata
*/
export interface GeneratedPuzzle extends PuzzleState {
seed: number; // Seed used for generation
size: number; // Grid size
targetDifficulty: DifficultyLevel; // Requested difficulty
actualDifficulty: DifficultyLevel; // Estimated difficulty
symmetry: SymmetryType; // Symmetry pattern used
generatedAt: number; // Timestamp (ms)
generationTimeMs: number; // Generation time
retryCount: number; // Attempts needed for uniqueness
}
/**
* Symmetry types for cell removal
*/
export type SymmetryType = 'none' | 'rotational' | 'reflectional' | 'diagonal';
/**
* Seeded random number generator for reproducible puzzles
*/
export class SeededRandom {
constructor(seed: number);
next(): number; // Returns [0, 1)
nextInt(min: number, max: number): number; // Returns [min, max]
shuffle<T>(array: T[]): T[]; // Fisher-Yates shuffle
}
/**
* Main puzzle generator class
*/
export class PuzzleGenerator {
constructor(config?: PuzzleGenerationConfig);
/**
* Generates a single puzzle
*/
generate(): GeneratedPuzzle;
/**
* Gets the current seed (useful if auto-generated)
*/
getSeed(): number;
/**
* Gets the current configuration
*/
getConfig(): PuzzleGenerationConfig;
}
/**
* Generates a puzzle from a specific seed
*/
export function generateFromSeed(
seed: number,
config?: Omit<PuzzleGenerationConfig, 'seed'>
): GeneratedPuzzle;
/**
* Generates a random seed
*/
export function generateRandomSeed(): number;/**
* Configuration for batch generation
*/
export interface BatchGenerationConfig {
count: number; // Number of puzzles to generate
seedStart?: number; // Starting seed (auto if not provided)
seedMode?: 'sequential' | 'random'; // Seed selection (default: 'sequential')
size?: 4 | 9 | 16 | 25; // Grid size
difficulty?: DifficultyLevel | DifficultyLevel[]; // Single or per-puzzle
symmetry?: SymmetryType; // Symmetry pattern
onProgress?: (progress: BatchProgress) => void; // Progress callback
}
/**
* Batch progress information
*/
export interface BatchProgress {
current: number; // Current puzzle number
total: number; // Total puzzles to generate
successful: number; // Successfully generated
failed: number; // Failed validation
averageTimeMs: number; // Average generation time
}
/**
* Batch generation result
*/
export interface BatchGenerationResult {
puzzles: GeneratedPuzzle[]; // Generated puzzles
summary: {
total: number;
successful: number;
failed: number;
totalTimeMs: number;
averageTimeMs: number;
};
}
/**
* Generates a batch of puzzles
*/
export function generateBatch(
config: BatchGenerationConfig
): Promise<BatchGenerationResult>;/**
* Validation result for puzzle uniqueness
*/
export interface UniquenessValidation {
isUnique: boolean; // True if exactly one solution
solutionCount: number; // Number of solutions found (0-2+)
solutions?: Grid[]; // Solutions found (if requested)
}
/**
* Validates puzzle has unique solution
*/
export function validateUniqueness(
grid: Grid,
options?: {
maxSolutions?: number; // Stop after finding N solutions (default: 2)
includeSolutions?: boolean; // Return solutions (default: false)
}
): UniquenessValidation;
/**
* Estimates actual difficulty of generated puzzle
*/
export function estimateGeneratedDifficulty(
grid: Grid,
size: number
): DifficultyLevel;
/**
* Checks if puzzle is solvable without guessing
*/
export function isSolvableWithoutGuessing(
grid: Grid
): boolean;/**
* CLI commands for puzzle generation (to be added to Spec 09)
*/
// Generate single puzzle
machine-dream puzzle generate \
--seed 12345 \
--size 9 \
--difficulty medium \
--output puzzles/generated-001.json
// Generate puzzle with random seed (seed printed)
machine-dream puzzle generate \
--size 16 \
--difficulty hard \
--output puzzles/generated-002.json
// Generate batch of puzzles
machine-dream puzzle batch \
--count 10 \
--seed-start 1000 \
--seed-mode sequential \
--difficulty medium \
--output-dir puzzles/batch-001/
// Generate from seed (recreate puzzle)
machine-dream puzzle from-seed 12345 \
--size 9 \
--difficulty medium \
--output puzzles/recreated.json
// Validate puzzle uniqueness
machine-dream puzzle validate puzzles/custom.json \
--check-uniqueness/**
* TUI Puzzle Generator Screen
*
* - Seed input field (number or "random")
* - Size selector (4x4 / 9x9 / 16x16 / 25x25)
* - Difficulty selector
* - Symmetry selector
* - Generate button
* - Preview generated puzzle
* - Save to file option
* - Use for LLM play option
*/Files to Create:
src/engine/SeededRandom.ts- Seeded PRNG implementationsrc/engine/PuzzleGenerator.ts- Enhanced generator with seed supportsrc/engine/PuzzleValidator.ts- Uniqueness and solvability validation
Files to Modify:
src/engine/SudokuGenerator.ts- Deprecate or migrate to new system
Implementation Steps:
- Implement
SeededRandomclass using Mulberry32 algorithm - Extend
PuzzleGeneratorwith seed and size support - Add uniqueness validation using solution counter
- Add difficulty estimation based on clue count + strategy analysis
- Comprehensive unit tests (90%+ coverage)
Estimated Time: 1 day (8 hours)
Implementation Steps:
- Add size parameter validation (4, 9, 16, 25)
- Update box calculation for each size
- Scale value ranges per grid size
- Add size-specific difficulty mapping
- Test all sizes with various difficulties
Estimated Time: 0.5 days (4 hours)
Implementation Steps:
- Implement
generateBatch()function - Add progress callbacks
- Support sequential and random seed modes
- Add batch summary statistics
- Performance optimization for large batches
Estimated Time: 0.5 days (4 hours)
Files to Modify:
src/cli/commands/puzzle.ts(NEW) - Puzzle generation commands
Implementation Steps:
- Add
puzzle generatecommand - Add
puzzle batchcommand - Add
puzzle from-seedcommand - Add
puzzle validatecommand - Update Spec 09 documentation
Estimated Time: 0.5 days (4 hours)
Files to Create:
src/tui-ink/screens/GeneratorScreen.tsx- Puzzle generator UIsrc/tui-ink/screens/GeneratorScreen.interactive.tsx- Interactive version
Files to Modify:
src/tui-ink/App.tsx- Add generator menu itemsrc/tui-ink/services/CLIExecutor.ts- Add generator methods
Implementation Steps:
- Create generator configuration form
- Add live preview of generated puzzle
- Add save/export functionality
- Add "Use for LLM Play" quick action
- Update Spec 10 documentation
Estimated Time: 0.5 days (4 hours)
Implementation Steps:
- Update USER_GUIDE.md with generation examples
- Update README.md with seed-based features
- Create RANDOMIZED_PUZZLES.md tutorial
- Integration tests with LLM player
- Performance benchmarks
Estimated Time: 0.5 days (4 hours)
Total Estimated Time: 3.5 days (28 hours)
// Use generated puzzles for LLM training
const gen = new PuzzleGenerator({
seed: Date.now(),
difficulty: 'medium'
});
const trainingPuzzle = gen.generate();
await llmPlayer.playPuzzle(
trainingPuzzle.id,
trainingPuzzle.grid,
trainingPuzzle.solution!
);// Generate matched puzzle pairs for A/B testing
const baseSeed = 1000;
const puzzles = [
generateFromSeed(baseSeed, { difficulty: 'medium' }),
generateFromSeed(baseSeed + 1, { difficulty: 'medium' }),
// ...
];
await llmBenchmark.run(puzzles);// Generated puzzles can be saved as static JSON files
const puzzle = generateFromSeed(12345, { difficulty: 'hard' });
await savePuzzleToFile('puzzles/generated-hard-12345.json', puzzle);
// Can be loaded like any other puzzle
const loaded = await loadPuzzleFromFile('puzzles/generated-hard-12345.json');
expect(loaded.seed).toBe(12345); // Seed preserved- ✅ Seeded generation produces identical puzzles for same seed
- ✅ All grid sizes (4, 9, 16, 25) generate valid puzzles
- ✅ All difficulty levels map to appropriate clue counts
- ✅ 100% of generated puzzles have unique solutions
- ✅ Batch generation supports sequential and random seeds
- ✅ CLI commands work as documented
- ✅ TUI integration complete and functional
- ✅ 9×9 generation < 100ms average
- ✅ Batch of 100 puzzles < 10 seconds
- ✅ No memory leaks in long-running batch jobs
- ✅ Uniqueness validation < 200ms per puzzle
- ✅ 90%+ test coverage
- ✅ TypeScript strict mode compliance
- ✅ Zero linter errors or warnings
- ✅ JSDoc documentation complete
- ✅ Integration tests pass with LLM player
Test 1: Seed Reproducibility
const puzzle1 = generateFromSeed(777, { difficulty: 'easy' });
const puzzle2 = generateFromSeed(777, { difficulty: 'easy' });
expect(puzzle1.grid).toEqual(puzzle2.grid);Test 2: Grid Size Variety
const sizes: (4 | 9 | 16 | 25)[] = [4, 9, 16, 25];
for (const size of sizes) {
const puzzle = new PuzzleGenerator({ size, seed: 123 }).generate();
expect(puzzle.grid.length).toBe(size);
expect(validateUniqueness(puzzle.grid).isUnique).toBe(true);
}Test 3: Difficulty Accuracy
const difficulties: DifficultyLevel[] = ['easy', 'medium', 'hard', 'expert'];
for (const difficulty of difficulties) {
const puzzle = new PuzzleGenerator({ difficulty, seed: 456 }).generate();
const estimated = estimateGeneratedDifficulty(puzzle.grid, puzzle.size);
expect(estimated).toBe(difficulty);
}Test 4: Batch Generation
const batch = await generateBatch({
count: 50,
seedStart: 1000,
seedMode: 'sequential',
difficulty: 'medium'
});
expect(batch.puzzles.length).toBe(50);
expect(batch.puzzles[0].seed).toBe(1000);
expect(batch.puzzles[49].seed).toBe(1049);
// All unique
const uniqueGrids = new Set(batch.puzzles.map(p => JSON.stringify(p.grid)));
expect(uniqueGrids.size).toBe(50);Files Affected:
src/engine/SudokuGenerator.ts- Will be deprecatedsrc/cli/commands/*.ts- May use generated puzzlessrc/llm/LLMSudokuPlayer.ts- Can use generated puzzles
Migration Strategy:
- Keep old
SudokuGeneratorfor backward compatibility - Mark as
@deprecatedwith migration guide - New code should use
PuzzleGeneratorwith seeds - Static JSON puzzles continue to work unchanged
None - This is a pure addition. All existing functionality remains intact.
- Pattern-Based Generation: Generate puzzles with specific strategy requirements
- Minimal Clue Puzzles: Find minimum clues while maintaining uniqueness
- Custom Constraints: Support variant Sudoku rules (Killer, Thermo, etc.)
- Puzzle Grading: Machine learning-based difficulty prediction
- Solution Path Analysis: Track which strategies are required
- Parallel Batch Generation: Multi-threaded generation for large batches
- Generator Pool: Reuse generator instances to avoid initialization overhead
- Caching: Cache recently generated puzzles by seed
- Incremental Validation: Early termination when multiple solutions detected
class SeededRandom {
private state: number;
constructor(seed: number) {
this.state = seed >>> 0; // Ensure 32-bit unsigned
}
next(): number {
let t = this.state += 0x6D2B79F5;
t = Math.imul(t ^ (t >>> 15), t | 1);
t ^= t + Math.imul(t ^ (t >>> 7), t | 61);
return ((t ^ (t >>> 14)) >>> 0) / 4294967296;
}
nextInt(min: number, max: number): number {
return Math.floor(this.next() * (max - min + 1)) + min;
}
shuffle<T>(array: T[]): T[] {
const result = [...array];
for (let i = result.length - 1; i > 0; i--) {
const j = this.nextInt(0, i);
[result[i], result[j]] = [result[j], result[i]];
}
return result;
}
}| Size | Box Size | Value Range | Typical Clues (Medium) | Generation Time |
|---|---|---|---|---|
| 4×4 | 2×2 | 1-4 | 6-8 | < 10ms |
| 9×9 | 3×3 | 1-9 | 32-35 | < 100ms |
| 16×16 | 4×4 | 1-16 | 80-100 | < 500ms |
| 25×25 | 5×5 | 1-25 | 200-250 | < 2000ms |
# Generate puzzle with specific seed
npm run puzzle:generate -- --seed 42 --difficulty hard
# Generate batch for LLM training
npm run puzzle:batch -- --count 100 --seed-start 1000
# Recreate exact puzzle from seed
npm run puzzle:from-seed 42 --output puzzles/puzzle-42.json
# Use in LLM player
npm run llm:play puzzles/puzzle-42.jsonStatus: ✅ Ready for Implementation Next Steps:
- Implement Phase 1 (Seeded Generator)
- Test with existing LLM player
- Implement remaining phases sequentially
- Update documentation
End of Randomized Puzzle Generation Specification (PG-012)