@fgv/ts-sudoku-lib 5.0.1-0 → 5.0.1-2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (82) hide show
  1. package/debug_killer.js +50 -0
  2. package/debug_test.js +88 -0
  3. package/dist/ts-sudoku-lib.d.ts +1505 -42
  4. package/lib/index.d.ts +3 -2
  5. package/lib/index.js +5 -3
  6. package/lib/packlets/collections/collections.d.ts +15 -8
  7. package/lib/packlets/collections/collections.js +41 -11
  8. package/lib/packlets/collections/data/puzzles.json +28 -33
  9. package/lib/packlets/common/common.d.ts +15 -0
  10. package/lib/packlets/common/common.js +25 -0
  11. package/lib/packlets/common/converters.d.ts +0 -6
  12. package/lib/packlets/common/converters.js +17 -22
  13. package/lib/packlets/common/ids.d.ts +8 -1
  14. package/lib/packlets/common/ids.js +83 -10
  15. package/lib/packlets/common/index.d.ts +3 -2
  16. package/lib/packlets/common/index.js +5 -2
  17. package/lib/packlets/common/logging.d.ts +7 -0
  18. package/lib/packlets/common/logging.js +35 -0
  19. package/lib/packlets/common/puzzle.d.ts +23 -13
  20. package/lib/packlets/common/puzzle.js +51 -25
  21. package/lib/packlets/common/puzzleDefinitions.d.ts +127 -0
  22. package/lib/packlets/common/puzzleDefinitions.js +251 -0
  23. package/lib/packlets/common/puzzleSession.d.ts +8 -0
  24. package/lib/packlets/common/puzzleSession.js +12 -0
  25. package/lib/packlets/common/puzzleState.js +3 -0
  26. package/lib/packlets/files/converters.d.ts +27 -0
  27. package/lib/packlets/files/converters.js +71 -0
  28. package/lib/packlets/{file/converters.d.ts → files/filesystem.d.ts} +3 -8
  29. package/lib/packlets/{file/converters.js → files/filesystem.js} +5 -14
  30. package/lib/packlets/files/index.d.ts +5 -0
  31. package/lib/packlets/{file → files}/index.js +3 -1
  32. package/lib/packlets/files/model.d.ts +32 -0
  33. package/lib/packlets/hints/baseHintProvider.d.ts +103 -0
  34. package/lib/packlets/hints/baseHintProvider.js +203 -0
  35. package/lib/packlets/hints/explanations.d.ts +105 -0
  36. package/lib/packlets/hints/explanations.js +276 -0
  37. package/lib/packlets/hints/hiddenSingles.d.ts +81 -0
  38. package/lib/packlets/hints/hiddenSingles.js +237 -0
  39. package/lib/packlets/hints/hintRegistry.d.ts +95 -0
  40. package/lib/packlets/hints/hintRegistry.js +226 -0
  41. package/lib/packlets/hints/hints.d.ts +144 -0
  42. package/lib/packlets/hints/hints.js +316 -0
  43. package/lib/packlets/hints/index.d.ts +10 -0
  44. package/lib/packlets/hints/index.js +55 -0
  45. package/lib/packlets/hints/interfaces.d.ts +121 -0
  46. package/lib/packlets/{file/model.js → hints/interfaces.js} +1 -1
  47. package/lib/packlets/hints/nakedSingles.d.ts +57 -0
  48. package/lib/packlets/hints/nakedSingles.js +202 -0
  49. package/lib/packlets/hints/puzzleSessionHints.d.ts +306 -0
  50. package/lib/packlets/hints/puzzleSessionHints.js +499 -0
  51. package/lib/packlets/hints/types.d.ts +102 -0
  52. package/lib/packlets/hints/types.js +46 -0
  53. package/lib/packlets/puzzles/anyPuzzle.d.ts +3 -3
  54. package/lib/packlets/puzzles/anyPuzzle.js +1 -1
  55. package/lib/packlets/puzzles/index.d.ts +4 -2
  56. package/lib/packlets/puzzles/index.js +20 -3
  57. package/lib/packlets/puzzles/internal/combinationCache.d.ts +29 -0
  58. package/lib/packlets/puzzles/internal/combinationCache.js +79 -0
  59. package/lib/packlets/puzzles/internal/combinationGenerator.d.ts +34 -0
  60. package/lib/packlets/puzzles/internal/combinationGenerator.js +146 -0
  61. package/lib/packlets/puzzles/internal/possibilityAnalyzer.d.ts +25 -0
  62. package/lib/packlets/puzzles/internal/possibilityAnalyzer.js +125 -0
  63. package/lib/packlets/puzzles/killerCombinations.d.ts +90 -0
  64. package/lib/packlets/puzzles/killerCombinations.js +226 -0
  65. package/lib/packlets/puzzles/killerCombinationsTypes.d.ts +17 -0
  66. package/lib/packlets/puzzles/killerCombinationsTypes.js +26 -0
  67. package/lib/packlets/puzzles/killerSudokuPuzzle.d.ts +2 -2
  68. package/lib/packlets/puzzles/killerSudokuPuzzle.js +15 -11
  69. package/lib/packlets/puzzles/sudokuPuzzle.d.ts +2 -2
  70. package/lib/packlets/puzzles/sudokuXPuzzle.d.ts +2 -2
  71. package/lib/packlets/puzzles/sudokuXPuzzle.js +8 -4
  72. package/package.json +5 -5
  73. package/sample-12x12-puzzle.js +72 -0
  74. package/sample-4x4-puzzles.js +68 -0
  75. package/sample-6x6-puzzle.js +61 -0
  76. package/temp_12x12_cells.txt +12 -0
  77. package/temp_correct.txt +12 -0
  78. package/test-grid-sizes.js +132 -0
  79. package/lib/packlets/common/model.d.ts +0 -15
  80. package/lib/packlets/file/index.d.ts +0 -4
  81. package/lib/packlets/file/model.d.ts +0 -9
  82. /package/lib/packlets/{common → files}/model.js +0 -0
@@ -1,5 +1,7 @@
1
1
  import { Brand } from '@fgv/ts-utils';
2
2
  import { Converter } from '@fgv/ts-utils';
3
+ import { FileTree } from '@fgv/ts-json-base';
4
+ import { Logging } from '@fgv/ts-utils';
3
5
  import { Result } from '@fgv/ts-utils';
4
6
 
5
7
  /**
@@ -9,11 +11,99 @@ import { Result } from '@fgv/ts-utils';
9
11
  export declare const allPuzzleTypes: PuzzleType[];
10
12
 
11
13
  /**
12
- * Static class to instantiate any puzzle from a {@link PuzzleDescription | puzzle description}.
14
+ * Static class to instantiate any puzzle from a {@link IPuzzleDefinition | puzzle definition}.
13
15
  * @internal
14
16
  */
15
17
  declare class AnyPuzzle {
16
- static create(puzzle: IPuzzleDescription): Result<Puzzle>;
18
+ static create(puzzle: IPuzzleDefinition): Result<Puzzle>;
19
+ }
20
+
21
+ /**
22
+ * Abstract base class providing common functionality for hint providers.
23
+ * @public
24
+ */
25
+ declare abstract class BaseHintProvider implements IHintProvider {
26
+ readonly techniqueId: TechniqueId;
27
+ readonly techniqueName: string;
28
+ readonly difficulty: DifficultyLevel;
29
+ readonly priority: number;
30
+ protected readonly defaultConfidence: ConfidenceLevel;
31
+ protected constructor(config: IBaseHintProviderConfig);
32
+ /**
33
+ * Abstract method to be implemented by concrete providers.
34
+ * Determines if this provider can potentially generate hints for the given puzzle.
35
+ */
36
+ abstract canProvideHints(puzzle: Puzzle, state: PuzzleState): boolean;
37
+ /**
38
+ * Abstract method to be implemented by concrete providers.
39
+ * Generates all possible hints using this technique for the given puzzle.
40
+ */
41
+ abstract generateHints(puzzle: Puzzle, state: PuzzleState, options?: IHintGenerationOptions): Result<readonly IHint[]>;
42
+ /**
43
+ * Utility method to create a hint with consistent structure.
44
+ * @param cellActions - The actions to be performed on cells
45
+ * @param relevantCells - The cells relevant to understanding the hint
46
+ * @param explanations - The explanations for the hint
47
+ * @param confidence - The confidence level for this hint
48
+ * @returns A complete hint object
49
+ */
50
+ protected createHint(cellActions: readonly ICellAction[], relevantCells: IRelevantCells, explanations: readonly IHintExplanation[], confidence?: ConfidenceLevel): IHint;
51
+ /**
52
+ * Utility method to create cell actions.
53
+ * @param cellId - The ID of the cell to act upon
54
+ * @param action - The type of action to perform
55
+ * @param value - Optional value for set-value actions
56
+ * @param reason - Optional reason for the action
57
+ * @returns A cell action object
58
+ */
59
+ protected createCellAction(cellId: CellId, action: ICellAction['action'], value?: number, reason?: string): ICellAction;
60
+ /**
61
+ * Utility method to create relevant cells grouping.
62
+ * @param primary - Primary cells that are the focus of the hint
63
+ * @param secondary - Secondary cells that provide context
64
+ * @param affected - Cells that will be affected by applying the hint
65
+ * @returns A relevant cells object
66
+ */
67
+ protected createRelevantCells(primary: readonly CellId[], secondary?: readonly CellId[], affected?: readonly CellId[]): IRelevantCells;
68
+ /**
69
+ * Utility method to create hint explanations.
70
+ * @param level - The level of detail for the explanation
71
+ * @param title - The title of the explanation
72
+ * @param description - The main description
73
+ * @param steps - Optional step-by-step instructions
74
+ * @param tips - Optional tips for understanding the technique
75
+ * @returns A hint explanation object
76
+ */
77
+ protected createExplanation(level: ExplanationLevel, title: string, description: string, steps?: readonly string[], tips?: readonly string[]): IHintExplanation;
78
+ /**
79
+ * Filters hints based on generation options.
80
+ * @param hints - The hints to filter
81
+ * @param options - The filtering options
82
+ * @returns Filtered array of hints
83
+ */
84
+ protected filterHints(hints: readonly IHint[], options?: IHintGenerationOptions): readonly IHint[];
85
+ /**
86
+ * Validates generation options for consistency.
87
+ * @param options - The options to validate
88
+ * @returns Result indicating validation success or failure
89
+ */
90
+ protected validateOptions(options?: IHintGenerationOptions): Result<void>;
91
+ /**
92
+ * Gets all empty cells in the puzzle.
93
+ * @param puzzle - The puzzle structure
94
+ * @param state - The puzzle state to analyze
95
+ * @returns Array of cell IDs that are empty
96
+ */
97
+ protected getEmptyCells(puzzle: Puzzle, state: PuzzleState): CellId[];
98
+ /**
99
+ * Gets the possible candidate values for a specific cell using cage-based constraints.
100
+ * This implementation works with any puzzle variant by checking all applicable cages.
101
+ * @param cellId - The cell to analyze
102
+ * @param puzzle - The puzzle structure containing constraints
103
+ * @param state - The current puzzle state
104
+ * @returns Array of possible values for the cell
105
+ */
106
+ protected getCandidates(cellId: CellId, puzzle: Puzzle, state: PuzzleState): number[];
17
107
  }
18
108
 
19
109
  /**
@@ -73,6 +163,12 @@ export declare class Cell implements ICellInit, ICell {
73
163
  toString(state?: PuzzleState): string;
74
164
  }
75
165
 
166
+ /**
167
+ * The type of action that should be taken on a cell as part of a hint.
168
+ * @public
169
+ */
170
+ declare type CellAction = 'set-value' | 'eliminate-candidate' | 'add-candidate' | 'highlight';
171
+
76
172
  /**
77
173
  * Nominal identifier for a single {@Link ICell | cell} in a {@link PuzzleSession | puzzle}.
78
174
  * @public
@@ -85,30 +181,540 @@ export declare type CellId = Brand<string, 'CellId'>;
85
181
  */
86
182
  declare const cellId: Converter<CellId>;
87
183
 
184
+ /**
185
+ * Confidence level for a generated hint, ranging from 1 (low) to 5 (high).
186
+ * @public
187
+ */
188
+ declare type ConfidenceLevel = Brand<1 | 2 | 3 | 4 | 5, 'ConfidenceLevel'>;
189
+
190
+ /**
191
+ * Standard confidence levels as branded types.
192
+ * @public
193
+ */
194
+ declare const ConfidenceLevels: {
195
+ readonly LOW: ConfidenceLevel;
196
+ readonly MEDIUM_LOW: ConfidenceLevel;
197
+ readonly MEDIUM: ConfidenceLevel;
198
+ readonly MEDIUM_HIGH: ConfidenceLevel;
199
+ readonly HIGH: ConfidenceLevel;
200
+ };
201
+
88
202
  declare namespace Converters {
89
203
  export {
90
204
  cageId,
91
205
  cellId,
92
- puzzleType,
93
- puzzleDescription
206
+ puzzleType
94
207
  }
95
208
  }
96
209
  export { Converters }
97
210
 
98
211
  declare namespace Converters_2 {
99
212
  export {
100
- loadJsonPuzzlesFileSync,
213
+ loadPuzzlesFile,
214
+ puzzleFileDimensions,
215
+ puzzleFileData,
101
216
  puzzlesFile
102
217
  }
103
218
  }
104
219
 
105
- declare namespace File_2 {
220
+ /**
221
+ * Default hint applicator that converts hints to cell state updates.
222
+ * @public
223
+ */
224
+ declare class DefaultHintApplicator implements IHintApplicator {
225
+ private readonly _log;
226
+ /**
227
+ * Creates a new {@link Hints.DefaultHintApplicator | DefaultHintApplicator}.
228
+ * @param logger - Optional logger for diagnostic output
229
+ */
230
+ constructor(logger?: Logging.LogReporter<unknown>);
231
+ /**
232
+ * Validates that a hint can be safely applied to the given state.
233
+ * @param hint - The hint to validate
234
+ * @param puzzle - The puzzle structure containing constraints
235
+ * @param state - The current puzzle state
236
+ * @returns Result indicating validation success or failure with details
237
+ */
238
+ canApplyHint(hint: IHint, puzzle: Puzzle, state: PuzzleState): Result<void>;
239
+ /**
240
+ * Applies a hint to the puzzle state, generating the necessary cell updates.
241
+ * @param hint - The hint to apply
242
+ * @param puzzle - The puzzle structure containing constraints
243
+ * @param state - The current puzzle state
244
+ * @returns Result containing the cell state updates needed to apply the hint
245
+ */
246
+ applyHint(hint: IHint, puzzle: Puzzle, state: PuzzleState): Result<readonly ICellState[]>;
247
+ }
248
+
249
+ /**
250
+ * Default no-op logger for use when diagnostic logging is not needed.
251
+ * @public
252
+ */
253
+ export declare const DefaultSudokuLogger: Logging.LogReporter<unknown>;
254
+
255
+ /**
256
+ * Standard difficulty classifications for Sudoku techniques.
257
+ * @public
258
+ */
259
+ declare type DifficultyLevel = 'beginner' | 'intermediate' | 'advanced' | 'expert';
260
+
261
+ /**
262
+ * Educational content manager for Sudoku solving techniques.
263
+ * @public
264
+ */
265
+ declare class EducationalContent {
266
+ private static readonly _techniqueIntroductions;
267
+ private static readonly _techniqueRelationships;
268
+ /**
269
+ * Gets an introduction to a specific technique.
270
+ * @param techniqueId - The technique to introduce
271
+ * @returns Result containing the introduction text
272
+ */
273
+ static getTechniqueIntroduction(techniqueId: TechniqueId): Result<string>;
274
+ /**
275
+ * Gets relationship information for a technique.
276
+ * @param techniqueId - The technique to get relationships for
277
+ * @returns Result containing the relationship information
278
+ */
279
+ static getTechniqueRelationships(techniqueId: TechniqueId): Result<readonly string[]>;
280
+ /**
281
+ * Gets a complete educational overview for a technique.
282
+ * @param techniqueId - The technique to describe
283
+ * @returns Result containing the complete overview
284
+ */
285
+ static getTechniqueOverview(techniqueId: TechniqueId): Result<string>;
286
+ /**
287
+ * Gets general Sudoku solving advice.
288
+ * @returns Array of general solving tips
289
+ */
290
+ static getGeneralSolvingTips(): readonly string[];
291
+ /**
292
+ * Gets difficulty progression advice.
293
+ * @returns Advice for progressing through difficulty levels
294
+ */
295
+ static getDifficultyProgression(): readonly string[];
296
+ /**
297
+ * Creates a complete educational guide for beginners.
298
+ * @returns Comprehensive beginner guide
299
+ */
300
+ static createBeginnerGuide(): string;
301
+ }
302
+
303
+ /**
304
+ * Utility class for formatting and displaying hint explanations.
305
+ * @public
306
+ */
307
+ declare class ExplanationFormatter {
308
+ /**
309
+ * Formats a hint explanation as a readable string.
310
+ * @param explanation - The explanation to format
311
+ * @param includeSteps - Whether to include step-by-step instructions
312
+ * @param includeTips - Whether to include tips
313
+ * @returns Formatted explanation string
314
+ */
315
+ static formatExplanation(explanation: IHintExplanation, includeSteps?: boolean, includeTips?: boolean): string;
316
+ /**
317
+ * Formats all explanations for a hint as a structured string.
318
+ * @param explanations - The explanations to format
319
+ * @returns Formatted explanations string
320
+ */
321
+ static formatAllExplanations(explanations: readonly IHintExplanation[]): string;
322
+ /**
323
+ * Creates a summary of available explanation levels.
324
+ * @param explanations - The explanations to summarize
325
+ * @returns Summary string
326
+ */
327
+ static createLevelSummary(explanations: readonly IHintExplanation[]): string;
328
+ }
329
+
330
+ /**
331
+ * The level of detail for hint explanations.
332
+ * @public
333
+ */
334
+ declare type ExplanationLevel = 'brief' | 'detailed' | 'educational';
335
+
336
+ /**
337
+ * Registry for managing hint explanation providers.
338
+ * @public
339
+ */
340
+ declare class ExplanationRegistry {
341
+ private readonly _providers;
342
+ /**
343
+ * Creates a new ExplanationRegistry instance.
344
+ */
345
+ constructor();
346
+ /**
347
+ * Registers a new explanation provider.
348
+ * @param provider - The provider to register
349
+ * @returns Result indicating success or failure of registration
350
+ */
351
+ registerProvider(provider: IHintExplanationProvider): Result<void>;
352
+ /**
353
+ * Gets explanations for a specific hint.
354
+ * @param hint - The hint to explain
355
+ * @param puzzle - The puzzle structure containing constraints
356
+ * @param state - The puzzle state context
357
+ * @returns Result containing the explanations
358
+ */
359
+ getExplanations(hint: IHint, puzzle: Puzzle, state: PuzzleState): Result<readonly IHintExplanation[]>;
360
+ /**
361
+ * Gets a specific explanation at the requested level.
362
+ * @param hint - The hint to explain
363
+ * @param level - The desired explanation level
364
+ * @param state - The puzzle state context
365
+ * @returns Result containing the explanation at the specified level
366
+ */
367
+ getExplanationAtLevel(hint: IHint, level: ExplanationLevel, puzzle: Puzzle, state: PuzzleState): Result<IHintExplanation>;
368
+ }
369
+
370
+ declare namespace Files {
106
371
  export {
107
372
  Converters_2 as Converters,
108
- Model
373
+ Model,
374
+ FileSystem_2 as FileSystem
375
+ }
376
+ }
377
+ export { Files }
378
+
379
+ declare namespace FileSystem_2 {
380
+ export {
381
+ loadJsonPuzzlesFileSync
109
382
  }
110
383
  }
111
- export { File_2 as File }
384
+
385
+ /**
386
+ * The minimum and maximum possible values for a {@link ICage | cage}, by cage size in
387
+ * {@link ICell | cells}.
388
+ * @public
389
+ */
390
+ /**
391
+ * Calculate the minimum and maximum possible totals for a cage of given size
392
+ * @param cageSize - Number of cells in the cage
393
+ * @param maxValue - Maximum value allowed in a cell (e.g., 9 for 9x9, 16 for 16x16)
394
+ * @returns Object with min and max possible totals
395
+ * @public
396
+ */
397
+ export declare function getCageTotalBounds(cageSize: number, maxValue: number): {
398
+ min: number;
399
+ max: number;
400
+ };
401
+
402
+ /**
403
+ * Hint provider for the Hidden Singles technique.
404
+ *
405
+ * A Hidden Single occurs when a value can only be placed in one cell within
406
+ * a row, column, or 3x3 box, even though that cell may have multiple candidates.
407
+ *
408
+ * @public
409
+ */
410
+ declare class HiddenSinglesProvider extends BaseHintProvider {
411
+ /**
412
+ * Creates a new HiddenSinglesProvider instance.
413
+ */
414
+ constructor();
415
+ /**
416
+ * Determines if this provider can potentially generate hints for the given puzzle.
417
+ * @param puzzle - The puzzle structure containing constraints
418
+ * @param state - The current puzzle state
419
+ * @returns true if there are empty cells that might have hidden singles
420
+ */
421
+ canProvideHints(puzzle: Puzzle, state: PuzzleState): boolean;
422
+ /**
423
+ * Generates all hidden single hints for the given puzzle.
424
+ * @param puzzle - The puzzle structure containing constraints
425
+ * @param state - The current puzzle state
426
+ * @param options - Optional generation options
427
+ * @returns Result containing array of hidden single hints
428
+ */
429
+ generateHints(puzzle: Puzzle, state: PuzzleState, options?: IHintGenerationOptions): Result<readonly IHint[]>;
430
+ /**
431
+ * Finds all hidden singles in the puzzle using cage-based analysis.
432
+ * @param puzzle - The puzzle structure containing constraints
433
+ * @param state - The current puzzle state
434
+ * @returns Array of hidden single information
435
+ */
436
+ private _findAllHiddenSingles;
437
+ /**
438
+ * Finds hidden singles in a specific cage using dynamic value analysis.
439
+ * @param cage - The cage to analyze
440
+ * @param puzzle - The puzzle structure containing constraints
441
+ * @param state - The current puzzle state
442
+ * @returns Array of hidden singles in this cage
443
+ */
444
+ private _findHiddenSinglesInCage;
445
+ /**
446
+ * Gets a display-friendly index for a cage.
447
+ * @param cage - The cage to get index for
448
+ * @returns Display index for the cage
449
+ */
450
+ private _getCageDisplayIndex;
451
+ /**
452
+ * Removes duplicate hidden singles (same cell and value).
453
+ * @param hiddenSingles - Array of potentially duplicate hidden singles
454
+ * @returns Array with duplicates removed
455
+ */
456
+ private _removeDuplicateHiddenSingles;
457
+ /**
458
+ * Creates a hint for a specific hidden single.
459
+ * @param hiddenSingle - The hidden single information
460
+ * @param puzzle - The puzzle structure containing constraints
461
+ * @param state - The current puzzle state
462
+ * @returns A complete hint for this hidden single
463
+ */
464
+ private _createHiddenSingleHint;
465
+ /**
466
+ * Gets a human-readable name for a unit.
467
+ * @param unitType - The type of unit
468
+ * @param unitIndex - The index of the unit
469
+ * @returns Human-readable unit name
470
+ */
471
+ private _getUnitName;
472
+ /**
473
+ * Static factory method to create a new HiddenSinglesProvider.
474
+ * @returns Result containing the new provider
475
+ */
476
+ static create(): Result<HiddenSinglesProvider>;
477
+ }
478
+
479
+ /**
480
+ * Implementation of the hint registry that manages and coordinates multiple hint providers.
481
+ * @public
482
+ */
483
+ declare class HintRegistry implements IHintRegistry {
484
+ private readonly _providers;
485
+ /**
486
+ * Creates a new HintRegistry instance.
487
+ */
488
+ constructor();
489
+ /**
490
+ * Creates a new HintRegistry with the specified providers pre-registered.
491
+ * @param providers - The providers to register
492
+ * @returns Result containing the new registry or failure if registration fails
493
+ */
494
+ static create(providers?: readonly IHintProvider[]): Result<HintRegistry>;
495
+ /**
496
+ * Registers a new hint provider.
497
+ * @param provider - The provider to register
498
+ * @returns Result indicating success or failure of registration
499
+ */
500
+ registerProvider(provider: IHintProvider): Result<void>;
501
+ /**
502
+ * Unregisters a hint provider.
503
+ * @param techniqueId - The ID of the technique to unregister
504
+ * @returns Result indicating success or failure of unregistration
505
+ */
506
+ unregisterProvider(techniqueId: TechniqueId): Result<void>;
507
+ /**
508
+ * Gets a specific provider by technique ID.
509
+ * @param techniqueId - The ID of the technique
510
+ * @returns Result containing the provider, or failure if not found
511
+ */
512
+ getProvider(techniqueId: TechniqueId): Result<IHintProvider>;
513
+ /**
514
+ * Gets all registered providers, optionally filtered by criteria.
515
+ * @param options - Optional filtering options
516
+ * @returns Array of providers matching the criteria
517
+ */
518
+ getProviders(options?: IHintGenerationOptions): readonly IHintProvider[];
519
+ /**
520
+ * Generates hints using all applicable providers.
521
+ * @param puzzle - The puzzle structure containing constraints
522
+ * @param state - The current puzzle state
523
+ * @param options - Optional generation options
524
+ * @returns Result containing array of hints from all providers
525
+ */
526
+ generateAllHints(puzzle: Puzzle, state: PuzzleState, options?: IHintGenerationOptions): Result<readonly IHint[]>;
527
+ /**
528
+ * Gets the best available hint based on difficulty and confidence.
529
+ * @param puzzle - The puzzle structure containing constraints
530
+ * @param state - The current puzzle state
531
+ * @param options - Optional generation options
532
+ * @returns Result containing the best hint, or failure if no hints available
533
+ */
534
+ getBestHint(puzzle: Puzzle, state: PuzzleState, options?: IHintGenerationOptions): Result<IHint>;
535
+ /**
536
+ * Gets the number of registered providers.
537
+ * @returns The number of registered providers
538
+ */
539
+ get providerCount(): number;
540
+ /**
541
+ * Gets all registered technique IDs.
542
+ * @returns Array of technique IDs
543
+ */
544
+ getRegisteredTechniques(): readonly TechniqueId[];
545
+ /**
546
+ * Checks if a specific technique is registered.
547
+ * @param techniqueId - The technique ID to check
548
+ * @returns true if the technique is registered
549
+ */
550
+ hasProvider(techniqueId: TechniqueId): boolean;
551
+ /**
552
+ * Clears all registered providers.
553
+ * @returns Result indicating success
554
+ */
555
+ clear(): Result<void>;
556
+ /**
557
+ * Gets providers grouped by difficulty level.
558
+ * @returns Map of difficulty levels to providers
559
+ */
560
+ getProvidersByDifficulty(): Map<DifficultyLevel, readonly IHintProvider[]>;
561
+ /**
562
+ * Applies global filtering options to the collected hints.
563
+ * @param hints - The hints to filter
564
+ * @param options - The filtering options
565
+ * @returns Result containing the filtered hints
566
+ */
567
+ private _applyGlobalFiltering;
568
+ }
569
+
570
+ declare namespace Hints {
571
+ export {
572
+ TechniqueId,
573
+ ConfidenceLevel,
574
+ CellAction,
575
+ ExplanationLevel,
576
+ DifficultyLevel,
577
+ ICellAction,
578
+ IRelevantCells,
579
+ IHintExplanation,
580
+ IHint,
581
+ IHintGenerationOptions,
582
+ TechniqueIds,
583
+ ConfidenceLevels,
584
+ IHintProvider,
585
+ IHintRegistry,
586
+ IHintExplanationProvider,
587
+ IHintApplicator,
588
+ IBaseHintProviderConfig,
589
+ BaseHintProvider,
590
+ HintRegistry,
591
+ NakedSinglesProvider,
592
+ HiddenSinglesProvider,
593
+ ExplanationRegistry,
594
+ ExplanationFormatter,
595
+ EducationalContent,
596
+ IHintSystemConfig,
597
+ DefaultHintApplicator,
598
+ HintSystem,
599
+ IPuzzleSessionHintsConfig,
600
+ PuzzleSessionHints
601
+ }
602
+ }
603
+ export { Hints }
604
+
605
+ /**
606
+ * Main hint system that provides comprehensive hint generation and management.
607
+ * @public
608
+ */
609
+ declare class HintSystem {
610
+ private readonly _registry;
611
+ private readonly _applicator;
612
+ private readonly _config;
613
+ private readonly _log;
614
+ private readonly _logHints;
615
+ /**
616
+ * Creates a new HintSystem instance.
617
+ * @param registry - The hint registry to use
618
+ * @param applicator - The hint applicator to use
619
+ * @param config - Configuration options
620
+ */
621
+ constructor(registry: IHintRegistry, applicator: IHintApplicator, config: IHintSystemConfig);
622
+ /**
623
+ * Creates a new HintSystem with default providers and configuration.
624
+ * @param config - Optional configuration options
625
+ * @returns Result containing the new hint system
626
+ */
627
+ static create(config?: IHintSystemConfig): Result<HintSystem>;
628
+ /**
629
+ * Gets the hint registry.
630
+ * @returns The hint registry
631
+ */
632
+ get registry(): IHintRegistry;
633
+ /**
634
+ * Gets the hint applicator.
635
+ * @returns The hint applicator
636
+ */
637
+ get applicator(): IHintApplicator;
638
+ /**
639
+ * Gets the system configuration.
640
+ * @returns The configuration
641
+ */
642
+ get config(): IHintSystemConfig;
643
+ /**
644
+ * Generates all available hints for the current puzzle state.
645
+ * @param puzzle - The puzzle structure containing constraints
646
+ * @param state - The current puzzle state
647
+ * @param options - Optional generation options
648
+ * @returns Result containing array of hints
649
+ */
650
+ generateHints(puzzle: Puzzle, state: PuzzleState, options?: IHintGenerationOptions): Result<readonly IHint[]>;
651
+ /**
652
+ * Gets the best available hint for the current puzzle state.
653
+ * @param puzzle - The puzzle structure containing constraints
654
+ * @param state - The current puzzle state
655
+ * @param options - Optional generation options
656
+ * @returns Result containing the best hint
657
+ */
658
+ getBestHint(puzzle: Puzzle, state: PuzzleState, options?: IHintGenerationOptions): Result<IHint>;
659
+ /**
660
+ * Applies a hint to generate cell state updates.
661
+ * @param hint - The hint to apply
662
+ * @param puzzle - The puzzle structure containing constraints
663
+ * @param state - The current puzzle state
664
+ * @returns Result containing the cell updates
665
+ */
666
+ applyHint(hint: IHint, puzzle: Puzzle, state: PuzzleState): Result<readonly ICellState[]>;
667
+ /**
668
+ * Validates that a hint can be applied to the current state.
669
+ * @param hint - The hint to validate
670
+ * @param puzzle - The puzzle structure containing constraints
671
+ * @param state - The current puzzle state
672
+ * @returns Result indicating validation success or failure
673
+ */
674
+ validateHint(hint: IHint, puzzle: Puzzle, state: PuzzleState): Result<void>;
675
+ /**
676
+ * Formats a hint explanation for display.
677
+ * @param hint - The hint to format
678
+ * @param level - The explanation level to use (defaults to config default)
679
+ * @returns Formatted explanation string
680
+ */
681
+ formatHintExplanation(hint: IHint, level?: ExplanationLevel): string;
682
+ /**
683
+ * Gets a summary of the hint system capabilities.
684
+ * @returns System capabilities summary
685
+ */
686
+ getSystemSummary(): string;
687
+ /**
688
+ * Checks if the puzzle state has any available hints.
689
+ * @param puzzle - The puzzle structure containing constraints
690
+ * @param state - The current puzzle state
691
+ * @returns Result containing boolean indicating if hints are available
692
+ */
693
+ hasHints(puzzle: Puzzle, state: PuzzleState): Result<boolean>;
694
+ /**
695
+ * Gets statistics about available hints for the current state.
696
+ * @param puzzle - The puzzle structure containing constraints
697
+ * @param state - The current puzzle state
698
+ * @returns Result containing hint statistics
699
+ */
700
+ getHintStatistics(puzzle: Puzzle, state: PuzzleState): Result<{
701
+ totalHints: number;
702
+ hintsByTechnique: Map<string, number>;
703
+ hintsByDifficulty: Map<string, number>;
704
+ }>;
705
+ }
706
+
707
+ /**
708
+ * Configuration for a {@link Hints.BaseHintProvider | BaseHintProvider} instance.
709
+ * @public
710
+ */
711
+ declare interface IBaseHintProviderConfig {
712
+ readonly techniqueId: TechniqueId;
713
+ readonly techniqueName: string;
714
+ readonly difficulty: DifficultyLevel;
715
+ readonly priority: number;
716
+ readonly defaultConfidence?: ConfidenceLevel;
717
+ }
112
718
 
113
719
  /**
114
720
  * Describes the structure of a single cage in a {@link PuzzleSession | puzzle}.
@@ -175,6 +781,17 @@ export declare interface ICell {
175
781
  readonly immutableValue?: number;
176
782
  }
177
783
 
784
+ /**
785
+ * Describes an action to be taken on a specific cell as part of a hint.
786
+ * @public
787
+ */
788
+ declare interface ICellAction {
789
+ readonly cellId: CellId;
790
+ readonly action: CellAction;
791
+ readonly value?: number;
792
+ readonly reason?: string;
793
+ }
794
+
178
795
  /**
179
796
  * The contents of a single {@Link ICell | cell} in a {@link PuzzleSession | puzzle}.
180
797
  * @public
@@ -210,7 +827,8 @@ export declare interface ICellState extends ICellContents {
210
827
  }
211
828
 
212
829
  /**
213
- * @internal
830
+ * Describes a single cell update.
831
+ * @public
214
832
  */
215
833
  export declare interface ICellUpdate {
216
834
  from: ICellState;
@@ -225,22 +843,263 @@ export declare class Ids {
225
843
  static cellId(spec: string | IRowColumn | ICell): Result<CellId>;
226
844
  static rowCageId(row: number): CageId;
227
845
  static columnCageId(col: number): CageId;
228
- static sectionCageId(row: number, col: number): CageId;
846
+ static sectionCageId(row: number, col: number, cageHeight?: number, cageWidth?: number): CageId;
229
847
  static cellIds(firstRow: number, numRows: number, firstCol: number, numCols: number): Result<CellId[]>;
230
848
  }
231
849
 
232
850
  /**
233
- * Description of a single puzzle.
851
+ * A complete hint with all necessary information for display and application.
852
+ * @public
853
+ */
854
+ declare interface IHint {
855
+ readonly techniqueId: TechniqueId;
856
+ readonly techniqueName: string;
857
+ readonly difficulty: DifficultyLevel;
858
+ readonly confidence: ConfidenceLevel;
859
+ readonly cellActions: readonly ICellAction[];
860
+ readonly relevantCells: IRelevantCells;
861
+ readonly explanations: readonly IHintExplanation[];
862
+ readonly priority: number;
863
+ }
864
+
865
+ /**
866
+ * Interface for hint application and validation.
867
+ * @public
868
+ */
869
+ declare interface IHintApplicator {
870
+ /**
871
+ * Validates that a hint can be safely applied to the given state.
872
+ * @param hint - The hint to validate
873
+ * @param puzzle - The puzzle structure containing constraints
874
+ * @param state - The current puzzle state
875
+ * @returns Result indicating validation success or failure with details
876
+ */
877
+ canApplyHint(hint: IHint, puzzle: Puzzle, state: PuzzleState): Result<void>;
878
+ /**
879
+ * Applies a hint to the puzzle state, generating the necessary cell updates.
880
+ * @param hint - The hint to apply
881
+ * @param puzzle - The puzzle structure containing constraints
882
+ * @param state - The current puzzle state
883
+ * @returns Result containing the cell state updates needed to apply the hint
884
+ */
885
+ applyHint(hint: IHint, puzzle: Puzzle, state: PuzzleState): Result<readonly ICellState[]>;
886
+ }
887
+
888
+ /**
889
+ * A hint explanation at a specific level of detail.
890
+ * @public
891
+ */
892
+ declare interface IHintExplanation {
893
+ readonly level: ExplanationLevel;
894
+ readonly title: string;
895
+ readonly description: string;
896
+ readonly steps?: readonly string[];
897
+ readonly tips?: readonly string[];
898
+ }
899
+
900
+ /**
901
+ * Interface for hint explanation generation and formatting.
902
+ * @public
903
+ */
904
+ declare interface IHintExplanationProvider {
905
+ /**
906
+ * Gets the technique ID this explanation provider supports.
907
+ */
908
+ readonly techniqueId: TechniqueId;
909
+ /**
910
+ * Generates explanations for a specific hint.
911
+ * @param hint - The hint to explain
912
+ * @param puzzle - The puzzle structure containing constraints
913
+ * @param state - The puzzle state context
914
+ * @returns Result containing array of explanations at different levels
915
+ */
916
+ generateExplanations(hint: IHint, puzzle: Puzzle, state: PuzzleState): Result<readonly IHintExplanation[]>;
917
+ }
918
+
919
+ /**
920
+ * Configuration options for hint generation.
921
+ * @public
922
+ */
923
+ declare interface IHintGenerationOptions {
924
+ readonly maxHints?: number;
925
+ readonly minConfidence?: ConfidenceLevel;
926
+ readonly preferredDifficulty?: DifficultyLevel;
927
+ readonly enabledTechniques?: readonly TechniqueId[];
928
+ readonly explanationLevel?: ExplanationLevel;
929
+ }
930
+
931
+ /**
932
+ * Interface for classes that can provide hints using a specific solving technique.
933
+ * @public
934
+ */
935
+ declare interface IHintProvider {
936
+ readonly techniqueId: TechniqueId;
937
+ readonly techniqueName: string;
938
+ readonly difficulty: DifficultyLevel;
939
+ readonly priority: number;
940
+ /**
941
+ * Determines if this provider can potentially generate hints for the given puzzle.
942
+ * This should be a fast check to avoid expensive hint generation when not applicable.
943
+ * @param puzzle - The puzzle structure containing constraints
944
+ * @param state - The current puzzle state
945
+ * @returns true if this provider might be able to generate hints
946
+ */
947
+ canProvideHints(puzzle: Puzzle, state: PuzzleState): boolean;
948
+ /**
949
+ * Generates all possible hints using this technique for the given puzzle.
950
+ * @param puzzle - The puzzle structure containing constraints
951
+ * @param state - The current puzzle state
952
+ * @param options - Optional generation options
953
+ * @returns Result containing array of hints, or failure if generation fails
954
+ */
955
+ generateHints(puzzle: Puzzle, state: PuzzleState, options?: IHintGenerationOptions): Result<readonly IHint[]>;
956
+ }
957
+
958
+ /**
959
+ * Interface for managing and coordinating multiple hint providers.
960
+ * @public
961
+ */
962
+ declare interface IHintRegistry {
963
+ /**
964
+ * Registers a new hint provider.
965
+ * @param provider - The provider to register
966
+ * @returns Result indicating success or failure of registration
967
+ */
968
+ registerProvider(provider: IHintProvider): Result<void>;
969
+ /**
970
+ * Unregisters a hint provider.
971
+ * @param techniqueId - The ID of the technique to unregister
972
+ * @returns Result indicating success or failure of unregistration
973
+ */
974
+ unregisterProvider(techniqueId: TechniqueId): Result<void>;
975
+ /**
976
+ * Gets a specific provider by technique ID.
977
+ * @param techniqueId - The ID of the technique
978
+ * @returns Result containing the provider, or failure if not found
979
+ */
980
+ getProvider(techniqueId: TechniqueId): Result<IHintProvider>;
981
+ /**
982
+ * Gets all registered providers, optionally filtered by criteria.
983
+ * @param options - Optional filtering options
984
+ * @returns Array of providers matching the criteria
985
+ */
986
+ getProviders(options?: IHintGenerationOptions): readonly IHintProvider[];
987
+ /**
988
+ * Generates hints using all applicable providers.
989
+ * @param puzzle - The puzzle structure containing constraints
990
+ * @param state - The current puzzle state
991
+ * @param options - Optional generation options
992
+ * @returns Result containing array of hints from all providers
993
+ */
994
+ generateAllHints(puzzle: Puzzle, state: PuzzleState, options?: IHintGenerationOptions): Result<readonly IHint[]>;
995
+ /**
996
+ * Gets the best available hint based on difficulty and confidence.
997
+ * @param puzzle - The puzzle structure containing constraints
998
+ * @param state - The current puzzle state
999
+ * @param options - Optional generation options
1000
+ * @returns Result containing the best hint, or failure if no hints available
1001
+ */
1002
+ getBestHint(puzzle: Puzzle, state: PuzzleState, options?: IHintGenerationOptions): Result<IHint>;
1003
+ /**
1004
+ * Gets all registered technique IDs.
1005
+ * @returns Array of technique IDs
1006
+ */
1007
+ getRegisteredTechniques(): readonly TechniqueId[];
1008
+ }
1009
+
1010
+ /**
1011
+ * Configuration options for the hint system.
1012
+ * @public
1013
+ */
1014
+ declare interface IHintSystemConfig {
1015
+ readonly enableNakedSingles?: boolean;
1016
+ readonly enableHiddenSingles?: boolean;
1017
+ readonly defaultExplanationLevel?: ExplanationLevel;
1018
+ readonly logger?: Logging.LogReporter<unknown>;
1019
+ }
1020
+
1021
+ /**
1022
+ * Constraints that can be applied when generating killer cage combinations.
1023
+ * @public
1024
+ */
1025
+ declare interface IKillerConstraints {
1026
+ /**
1027
+ * Numbers that cannot be present in the combination.
1028
+ * Must be unique values between 1-9.
1029
+ */
1030
+ readonly excludedNumbers?: readonly number[];
1031
+ /**
1032
+ * Numbers that must be present in the combination.
1033
+ * Must be unique values between 1-9.
1034
+ */
1035
+ readonly requiredNumbers?: readonly number[];
1036
+ }
1037
+
1038
+ /**
1039
+ * Complete puzzle definition with derived properties
1040
+ * @public
1041
+ */
1042
+ export declare interface IPuzzleDefinition extends IPuzzleDimensions {
1043
+ readonly id?: string;
1044
+ readonly description: string;
1045
+ readonly type: PuzzleType;
1046
+ readonly level: number;
1047
+ readonly cells: string;
1048
+ readonly totalRows: number;
1049
+ readonly totalColumns: number;
1050
+ readonly maxValue: number;
1051
+ readonly totalCages: number;
1052
+ readonly basicCageTotal: number;
1053
+ readonly cages?: ICage[];
1054
+ }
1055
+
1056
+ /**
1057
+ * Core dimensional configuration for a puzzle grid
1058
+ * @public
1059
+ */
1060
+ export declare interface IPuzzleDimensions {
1061
+ /** Width of each section/cage (e.g., 3 for standard Sudoku) */
1062
+ readonly cageWidthInCells: number;
1063
+ /** Height of each section/cage (e.g., 3 for standard Sudoku) */
1064
+ readonly cageHeightInCells: number;
1065
+ /** Number of cages horizontally (e.g., 3 for standard Sudoku) */
1066
+ readonly boardWidthInCages: number;
1067
+ /** Number of cages vertically (e.g., 3 for standard Sudoku) */
1068
+ readonly boardHeightInCages: number;
1069
+ }
1070
+
1071
+ /**
1072
+ * Input format for puzzle data in JSON files.
1073
+ * Contains only the essential data needed to create an IPuzzleDefinition.
234
1074
  * @public
235
1075
  */
236
- export declare interface IPuzzleDescription {
1076
+ declare interface IPuzzleFileData {
237
1077
  id?: string;
238
1078
  description: string;
239
1079
  type: PuzzleType;
240
1080
  level: number;
241
- rows: number;
242
- cols: number;
243
1081
  cells: string;
1082
+ dimensions: IPuzzleFileDimensions;
1083
+ }
1084
+
1085
+ /**
1086
+ * Dimensional configuration for puzzles
1087
+ * @public
1088
+ */
1089
+ declare interface IPuzzleFileDimensions {
1090
+ cageWidthInCells: number;
1091
+ cageHeightInCells: number;
1092
+ boardWidthInCages: number;
1093
+ boardHeightInCages: number;
1094
+ }
1095
+
1096
+ /**
1097
+ * Configuration options for the PuzzleSessionHints integration.
1098
+ * @public
1099
+ */
1100
+ declare interface IPuzzleSessionHintsConfig extends IHintSystemConfig {
1101
+ readonly cacheTimeoutMs?: number;
1102
+ readonly maxCacheEntries?: number;
244
1103
  }
245
1104
 
246
1105
  /**
@@ -248,7 +1107,7 @@ export declare interface IPuzzleDescription {
248
1107
  * @public
249
1108
  */
250
1109
  declare interface IPuzzlesFile {
251
- puzzles: IPuzzleDescription[];
1110
+ puzzles: IPuzzleFileData[];
252
1111
  }
253
1112
 
254
1113
  declare interface IPuzzleStep {
@@ -256,7 +1115,19 @@ declare interface IPuzzleStep {
256
1115
  }
257
1116
 
258
1117
  /**
259
- * @internal
1118
+ * Interface for puzzle type-specific validation
1119
+ * @public
1120
+ */
1121
+ export declare interface IPuzzleTypeValidator {
1122
+ /**
1123
+ * Validate the cells string for this puzzle type
1124
+ */
1125
+ validateCells(cells: string, dimensions: IPuzzleDimensions): Result<true>;
1126
+ }
1127
+
1128
+ /**
1129
+ * Describes a single puzzle update.
1130
+ * @public
260
1131
  */
261
1132
  export declare interface IPuzzleUpdate {
262
1133
  from: PuzzleState;
@@ -264,6 +1135,16 @@ export declare interface IPuzzleUpdate {
264
1135
  cells: ICellUpdate[];
265
1136
  }
266
1137
 
1138
+ /**
1139
+ * Information about the cells that are relevant to understanding a hint.
1140
+ * @public
1141
+ */
1142
+ declare interface IRelevantCells {
1143
+ readonly primary: readonly CellId[];
1144
+ readonly secondary: readonly CellId[];
1145
+ readonly affected: readonly CellId[];
1146
+ }
1147
+
267
1148
  /**
268
1149
  * The row/column coordinate of a single {@Link ICell | cell} in a {@link PuzzleSession | puzzle}.
269
1150
  * @public
@@ -273,12 +1154,99 @@ export declare interface IRowColumn {
273
1154
  col: number;
274
1155
  }
275
1156
 
1157
+ /**
1158
+ * Helper class providing UI assistance functions for killer sudoku puzzle solving.
1159
+ * Generates possible totals, number combinations with constraints, and cell-specific
1160
+ * possibilities based on current puzzle state.
1161
+ * @public
1162
+ */
1163
+ declare class KillerCombinations {
1164
+ /**
1165
+ * Gets all mathematically possible totals for a given cage size.
1166
+ *
1167
+ * Uses the existing totalsByCageSize constant to determine the valid range
1168
+ * of totals for the specified cage size and returns all integers in that range.
1169
+ *
1170
+ * @param cageSize - The number of cells in the cage (must be 1-9)
1171
+ * @returns Result containing array of possible totals in ascending order
1172
+ *
1173
+ * @example
1174
+ * ```typescript
1175
+ * // Get possible totals for a 3-cell cage
1176
+ * const result = KillerCombinations.getPossibleTotals(3);
1177
+ * if (result.isSuccess()) {
1178
+ * console.log(result.value); // [6, 7, 8, 9, ..., 24]
1179
+ * }
1180
+ * ```
1181
+ */
1182
+ static getPossibleTotals(cageSize: number, maxValue?: number): Result<number[]>;
1183
+ /**
1184
+ * Generates all possible number combinations that sum to the target total.
1185
+ *
1186
+ * Each combination contains unique numbers from 1-9 that sum exactly to the
1187
+ * specified total. Combinations respect both excluded and required number
1188
+ * constraints if provided.
1189
+ *
1190
+ * @param cageSize - The number of cells in the cage (must be 1-9)
1191
+ * @param total - The target sum (must be valid for the cage size)
1192
+ * @param constraints - Optional constraints on included/excluded numbers
1193
+ * @returns Result containing array of combinations, each sorted in ascending order
1194
+ *
1195
+ * @example
1196
+ * ```typescript
1197
+ * // Get all combinations for a 3-cell cage with total 15
1198
+ * const result = KillerCombinations.getCombinations(3, 15);
1199
+ * if (result.isSuccess()) {
1200
+ * console.log(result.value); // [[1,5,9], [1,6,8], [2,4,9], ...]
1201
+ * }
1202
+ *
1203
+ * // With constraints - exclude 1 and 2, require 9
1204
+ * const constrained = KillerCombinations.getCombinations(3, 15, {
1205
+ * excludedNumbers: [1, 2],
1206
+ * requiredNumbers: [9]
1207
+ * });
1208
+ * ```
1209
+ */
1210
+ static getCombinations(cageSize: number, total: number, constraints?: IKillerConstraints, maxValue?: number): Result<number[][]>;
1211
+ /**
1212
+ * Determines possible values for each cell in a killer cage based on current puzzle state.
1213
+ *
1214
+ * Analyzes the current state of the puzzle and cage to determine which values
1215
+ * are possible for each empty cell, considering both killer cage constraints
1216
+ * and standard sudoku constraints (row, column, section uniqueness).
1217
+ *
1218
+ * @param puzzle - The puzzle instance
1219
+ * @param state - Current puzzle state
1220
+ * @param cage - The killer cage to analyze (must be of type 'killer')
1221
+ * @returns Result containing map of CellId to possible number arrays
1222
+ *
1223
+ * @example
1224
+ * ```typescript
1225
+ * const cage = puzzle.getCage(cageId).orThrow();
1226
+ * const possibilities = KillerCombinations.getCellPossibilities(puzzle, state, cage);
1227
+ * if (possibilities.isSuccess()) {
1228
+ * for (const [cellId, values] of possibilities.value) {
1229
+ * console.log(`Cell ${cellId} can have values: ${values.join(', ')}`);
1230
+ * }
1231
+ * }
1232
+ * ```
1233
+ */
1234
+ static getCellPossibilities(puzzle: Puzzle, state: PuzzleState, cage: ICage): Result<Map<CellId, number[]>>;
1235
+ /**
1236
+ * Validate constraint parameters.
1237
+ * @param constraints - Constraints to validate
1238
+ * @param maxValue - Maximum value allowed in cells
1239
+ * @returns Result indicating success or failure with error message
1240
+ */
1241
+ private static _validateConstraints;
1242
+ }
1243
+
276
1244
  /**
277
1245
  * @public
278
1246
  */
279
1247
  declare class KillerSudokuPuzzle extends Puzzle {
280
1248
  private constructor();
281
- static create(desc: IPuzzleDescription): Result<Puzzle>;
1249
+ static create(desc: IPuzzleDefinition): Result<Puzzle>;
282
1250
  private static _getKillerCages;
283
1251
  private static _getCageCells;
284
1252
  private static _getCages;
@@ -287,7 +1255,7 @@ declare class KillerSudokuPuzzle extends Puzzle {
287
1255
 
288
1256
  /**
289
1257
  * Loads an arbitrary JSON file and parses it to return a validated
290
- * {@link File.Model.IPuzzlesFile | IPuzzlesFile}.
1258
+ * {@link Files.Model.IPuzzlesFile | IPuzzlesFile}.
291
1259
  * @param path - String path to the file
292
1260
  * @returns `Success` with the resulting file, or `Failure` with details if an
293
1261
  * error occurs.
@@ -295,12 +1263,76 @@ declare class KillerSudokuPuzzle extends Puzzle {
295
1263
  */
296
1264
  declare function loadJsonPuzzlesFileSync(path: string): Result<IPuzzlesFile>;
297
1265
 
1266
+ /**
1267
+ * Loads a puzzles file from a `IFileTreeFileItem`.
1268
+ * @param file - The `IFileTreeFileItem` to load.
1269
+ * @returns `Success` with the resulting {@link Files.Model.IPuzzlesFile | IPuzzlesFile}, or `Failure` with
1270
+ * details if an error occurs.
1271
+ * @public
1272
+ */
1273
+ declare function loadPuzzlesFile(file: FileTree.IFileTreeFileItem): Result<IPuzzlesFile>;
1274
+
298
1275
  declare namespace Model {
299
1276
  export {
1277
+ IPuzzleFileDimensions,
1278
+ IPuzzleFileData,
300
1279
  IPuzzlesFile
301
1280
  }
302
1281
  }
303
1282
 
1283
+ /**
1284
+ * Hint provider for the Naked Singles technique.
1285
+ *
1286
+ * A Naked Single occurs when a cell has only one possible candidate value
1287
+ * based on the constraints of its row, column, and 3x3 box.
1288
+ *
1289
+ * @public
1290
+ */
1291
+ declare class NakedSinglesProvider extends BaseHintProvider {
1292
+ /**
1293
+ * Creates a new NakedSinglesProvider instance.
1294
+ */
1295
+ constructor();
1296
+ /**
1297
+ * Determines if this provider can potentially generate hints for the given puzzle.
1298
+ * Always returns true since naked singles can potentially exist in any incomplete puzzle.
1299
+ * @param puzzle - The puzzle structure containing constraints
1300
+ * @param state - The current puzzle state
1301
+ * @returns true if there are empty cells that might have naked singles
1302
+ */
1303
+ canProvideHints(puzzle: Puzzle, state: PuzzleState): boolean;
1304
+ /**
1305
+ * Generates all naked single hints for the given puzzle.
1306
+ * @param puzzle - The puzzle structure containing constraints
1307
+ * @param state - The current puzzle state
1308
+ * @param options - Optional generation options
1309
+ * @returns Result containing array of naked single hints
1310
+ */
1311
+ generateHints(puzzle: Puzzle, state: PuzzleState, options?: IHintGenerationOptions): Result<readonly IHint[]>;
1312
+ /**
1313
+ * Creates a hint for a specific naked single.
1314
+ * @param cellId - The cell containing the naked single
1315
+ * @param value - The single possible value for the cell
1316
+ * @param state - The current puzzle state
1317
+ * @returns A complete hint for this naked single
1318
+ */
1319
+ private _createNakedSingleHint;
1320
+ /**
1321
+ * Finds cells in the same row, column, and box that constrain the given cell.
1322
+ * @param cellId - The cell to analyze
1323
+ * @param value - The value that will be placed
1324
+ * @param state - The current puzzle state
1325
+ * @param puzzle - The puzzle for dimensions
1326
+ * @returns Array of cell IDs that are related to this naked single
1327
+ */
1328
+ private _findRelatedCells;
1329
+ /**
1330
+ * Static factory method to create a new NakedSinglesProvider.
1331
+ * @returns Result containing the new provider
1332
+ */
1333
+ static create(): Result<NakedSinglesProvider>;
1334
+ }
1335
+
304
1336
  /**
305
1337
  * Navigation direction within a puzzle.
306
1338
  * @public
@@ -315,38 +1347,49 @@ export declare type NavigationDirection = 'down' | 'left' | 'right' | 'up';
315
1347
  export declare type NavigationWrap = 'none' | 'wrap-around' | 'wrap-next';
316
1348
 
317
1349
  /**
318
- * @internal
1350
+ * Parse a cell ID string back to row/column coordinates
1351
+ * @param cellId - Cell ID string (e.g., "A1", "A01", "AB15")
1352
+ * @returns Row and column indices (0-based) or undefined if invalid
1353
+ * @public
1354
+ */
1355
+ export declare function parseCellId(cellId: string): IRowColumn | undefined;
1356
+
1357
+ /**
1358
+ * Abstract base class for all puzzles.
1359
+ * @public
319
1360
  */
320
1361
  export declare class Puzzle {
321
1362
  readonly id?: string;
322
1363
  readonly description: string;
1364
+ readonly type: string;
323
1365
  readonly initialState: PuzzleState;
1366
+ readonly dimensions: IPuzzleDefinition;
324
1367
  /**
325
- * @internal
1368
+ * @public
326
1369
  */
327
1370
  protected readonly _rows: Map<CageId, Cage>;
328
1371
  /**
329
- * @internal
1372
+ * @public
330
1373
  */
331
1374
  protected readonly _columns: Map<CageId, Cage>;
332
1375
  /**
333
- * @internal
1376
+ * @public
334
1377
  */
335
1378
  protected readonly _sections: Map<CageId, Cage>;
336
1379
  /**
337
- * @internal
1380
+ * @public
338
1381
  */
339
1382
  protected readonly _cages: Map<CageId, Cage>;
340
1383
  /**
341
- * @internal
1384
+ * @public
342
1385
  */
343
1386
  protected readonly _cells: Map<CellId, Cell>;
344
1387
  /**
345
1388
  * Constructs a new puzzle state.
346
- * @param puzzle - {@Link IPuzzleDescription | Puzzle description} from which this puzzle state
1389
+ * @param puzzle - {@Link IPuzzleDefinition | Puzzle definition} from which this puzzle state
347
1390
  * is to be initialized.
348
1391
  */
349
- protected constructor(puzzle: IPuzzleDescription, extraCages?: [CageId, Cage][]);
1392
+ protected constructor(puzzle: IPuzzleDefinition, extraCages?: [CageId, Cage][]);
350
1393
  get numRows(): number;
351
1394
  get numColumns(): number;
352
1395
  get rows(): Cage[];
@@ -357,11 +1400,16 @@ export declare class Puzzle {
357
1400
  /**
358
1401
  * @internal
359
1402
  */
360
- protected static _createRowCages(numRows: number, numCols: number): Result<[CageId, Cage][]>;
1403
+ protected static _createRowCages(numRows: number, numCols: number, basicCageTotal: number): Result<[CageId, Cage][]>;
1404
+ /**
1405
+ * @internal
1406
+ */
1407
+ protected static _createColumnCages(numRows: number, numCols: number, basicCageTotal: number): Result<[CageId, Cage][]>;
361
1408
  /**
1409
+ * Parse alphanumeric cell value (1-9, A-Z for values 10-35)
362
1410
  * @internal
363
1411
  */
364
- protected static _createColumnCages(numRows: number, numCols: number): Result<[CageId, Cage][]>;
1412
+ private _parseAlphanumericValue;
365
1413
  /**
366
1414
  * @internal
367
1415
  */
@@ -399,23 +1447,23 @@ export declare class PuzzleCollection {
399
1447
  /**
400
1448
  * All puzzles in the collection.
401
1449
  */
402
- readonly puzzles: readonly IPuzzleDescription[];
1450
+ readonly puzzles: readonly Files.Model.IPuzzleFileData[];
403
1451
  private readonly _byId;
404
1452
  private constructor();
405
1453
  /**
406
- * Creates a new puzzle from a loaded {@link File.Model.IPuzzlesFile | PuzzlesFile}
407
- * @param from - The {@link File.Model.IPuzzlesFile | puzzles file} to be loaded.
1454
+ * Creates a new puzzle from a loaded {@link Files.Model.IPuzzlesFile | PuzzlesFile}
1455
+ * @param from - The {@link Files.Model.IPuzzlesFile | puzzles file} to be loaded.
408
1456
  * @returns `Success` with the resulting {@link PuzzleCollection | PuzzleCollection}
409
1457
  * or `Failure` with details if an error occurs.
410
1458
  */
411
- static create(from: File_2.Model.IPuzzlesFile): Result<PuzzleCollection>;
1459
+ static create(from: Files.Model.IPuzzlesFile): Result<PuzzleCollection>;
412
1460
  /**
413
1461
  * Creates a new puzzle from a JSON file.
414
1462
  * @param path - path to the JSON file to be loaded.
415
1463
  * @returns `Success` with the resulting {@link PuzzleCollection | PuzzleCollection}
416
1464
  * or `Failure` with details if an error occurs.
417
1465
  */
418
- static load(path: string): Result<PuzzleCollection>;
1466
+ static load(file: FileTree.IFileTreeFileItem): Result<PuzzleCollection>;
419
1467
  /**
420
1468
  * Gets a puzzle by id from this collection.
421
1469
  * @param id - The string ID of the puzzle to be returned.
@@ -423,13 +1471,19 @@ export declare class PuzzleCollection {
423
1471
  * `Failure` with details if an error occurs.
424
1472
  */
425
1473
  getPuzzle(id: string): Result<PuzzleSession>;
1474
+ /**
1475
+ * Converts IPuzzleFileData to IPuzzleDefinition format.
1476
+ * @param fileData - The puzzle file data to convert
1477
+ * @returns Result containing the puzzle definition
1478
+ */
1479
+ private _convertToDefinition;
426
1480
  /**
427
1481
  * Gets a puzzle by id from this collection.
428
1482
  * @param id - The string ID of the puzzle to be returned.
429
1483
  * @returns `Success` with the requested {@link PuzzleSession | puzzle}, or
430
1484
  * `Failure` with details if an error occurs.
431
1485
  */
432
- getDescription(id: string): Result<IPuzzleDescription>;
1486
+ getDescription(id: string): Result<Files.Model.IPuzzleFileData>;
433
1487
  }
434
1488
 
435
1489
  /**
@@ -445,17 +1499,73 @@ export declare class PuzzleCollections {
445
1499
  }
446
1500
 
447
1501
  /**
448
- * Converts an arbitrary object to a {@link IPuzzleDescription | IPuzzleDescription}.
1502
+ * Factory for creating and validating puzzle definitions
1503
+ * @public
1504
+ */
1505
+ export declare class PuzzleDefinitionFactory {
1506
+ /**
1507
+ * Create a puzzle definition from dimensions and options
1508
+ */
1509
+ static create(dimensions: IPuzzleDimensions, options?: Partial<IPuzzleDefinition>): Result<IPuzzleDefinition>;
1510
+ /**
1511
+ * Create killer sudoku puzzle definition with cage constraints
1512
+ */
1513
+ static createKiller(dimensions: IPuzzleDimensions, description: Omit<IPuzzleDefinition, 'cageWidthInCells' | 'cageHeightInCells' | 'boardWidthInCages' | 'boardHeightInCages' | 'totalRows' | 'totalColumns' | 'maxValue' | 'totalCages' | 'basicCageTotal' | 'cages'> & {
1514
+ killerCages: Array<{
1515
+ id: string;
1516
+ cellPositions: Array<{
1517
+ row: number;
1518
+ col: number;
1519
+ }>;
1520
+ sum: number;
1521
+ }>;
1522
+ }): Result<IPuzzleDefinition>;
1523
+ /**
1524
+ * Validate puzzle dimensions
1525
+ */
1526
+ static validate(dimensions: IPuzzleDimensions): Result<true>;
1527
+ /**
1528
+ * Get a standard configuration by name
1529
+ */
1530
+ static getStandardConfig(name: StandardConfigName): IPuzzleDimensions;
1531
+ /**
1532
+ * Get all available standard configurations
1533
+ */
1534
+ static getStandardConfigs(): Record<StandardConfigName, IPuzzleDimensions>;
1535
+ /**
1536
+ * Get validator for a specific puzzle type
1537
+ */
1538
+ static getValidator(puzzleType: PuzzleType): IPuzzleTypeValidator | undefined;
1539
+ /**
1540
+ * Register a custom validator for a puzzle type
1541
+ */
1542
+ static registerValidator(puzzleType: PuzzleType, validator: IPuzzleTypeValidator): void;
1543
+ /**
1544
+ * Calculate the basic cage total (sum of 1 to maxValue)
1545
+ */
1546
+ private static _calculateBasicCageTotal;
1547
+ }
1548
+
1549
+ /**
1550
+ * Converts puzzle file data from JSON format
1551
+ * @public
1552
+ */
1553
+ declare const puzzleFileData: Converter<IPuzzleFileData>;
1554
+
1555
+ /**
1556
+ * Converts puzzle file dimensions from JSON format
449
1557
  * @public
450
1558
  */
451
- declare const puzzleDescription: Converter<IPuzzleDescription>;
1559
+ declare const puzzleFileDimensions: Converter<IPuzzleFileDimensions>;
452
1560
 
453
1561
  declare namespace Puzzles {
454
1562
  export {
455
1563
  AnyPuzzle as Any,
456
1564
  KillerSudokuPuzzle as Killer,
1565
+ KillerCombinations,
457
1566
  SudokuPuzzle as Sudoku,
458
- SudokuXPuzzle as SudokuX
1567
+ SudokuXPuzzle as SudokuX,
1568
+ IKillerConstraints
459
1569
  }
460
1570
  }
461
1571
  export { Puzzles }
@@ -485,6 +1595,10 @@ export declare class PuzzleSession {
485
1595
  * Description of the puzzle being solved.
486
1596
  */
487
1597
  get description(): string;
1598
+ /**
1599
+ * Type of the puzzle being solved.
1600
+ */
1601
+ get type(): string;
488
1602
  /**
489
1603
  * Number of rows in the puzzle being solved.
490
1604
  */
@@ -513,6 +1627,10 @@ export declare class PuzzleSession {
513
1627
  * The cells {@link ICell | cells} in the puzzle being solved.
514
1628
  */
515
1629
  get cells(): ICell[];
1630
+ /**
1631
+ * The puzzle structure for this session.
1632
+ */
1633
+ get puzzle(): Puzzle;
516
1634
  /**
517
1635
  * Index of the next step in this puzzle session.
518
1636
  */
@@ -666,7 +1784,301 @@ export declare class PuzzleSession {
666
1784
  }
667
1785
 
668
1786
  /**
669
- * Converts an arbitrary object to a {@link File.Model.IPuzzlesFile | IPuzzlesFile}.
1787
+ * Wrapper class that integrates hint functionality with PuzzleSession.
1788
+ * Provides hint generation, application, and explanation capabilities while
1789
+ * maintaining integration with existing state management and undo/redo functionality.
1790
+ * @public
1791
+ */
1792
+ declare class PuzzleSessionHints {
1793
+ private readonly _session;
1794
+ private readonly _hintSystem;
1795
+ private readonly _config;
1796
+ private _hintCache;
1797
+ /**
1798
+ * @internal
1799
+ */
1800
+ private constructor();
1801
+ /**
1802
+ * Creates a new PuzzleSessionHints wrapper for an existing PuzzleSession.
1803
+ * @param session - The PuzzleSession to wrap
1804
+ * @param config - Optional configuration for the hint system
1805
+ * @returns Result containing the new PuzzleSessionHints wrapper
1806
+ */
1807
+ static create(session: PuzzleSession, config?: IPuzzleSessionHintsConfig): Result<PuzzleSessionHints>;
1808
+ /**
1809
+ * Gets the wrapped PuzzleSession instance.
1810
+ * @returns The underlying PuzzleSession
1811
+ */
1812
+ get session(): PuzzleSession;
1813
+ /**
1814
+ * Gets the HintSystem instance.
1815
+ * @returns The hint system
1816
+ */
1817
+ get hintSystem(): HintSystem;
1818
+ /**
1819
+ * Gets the configuration.
1820
+ * @returns The configuration
1821
+ */
1822
+ get config(): IPuzzleSessionHintsConfig;
1823
+ /**
1824
+ * Gets the puzzle ID.
1825
+ * @returns The puzzle ID
1826
+ */
1827
+ get id(): string | undefined;
1828
+ /**
1829
+ * Gets the puzzle description.
1830
+ * @returns The puzzle description
1831
+ */
1832
+ get description(): string;
1833
+ /**
1834
+ * Gets the number of rows in the puzzle.
1835
+ * @returns The number of rows
1836
+ */
1837
+ get numRows(): number;
1838
+ /**
1839
+ * Gets the number of columns in the puzzle.
1840
+ * @returns The number of columns
1841
+ */
1842
+ get numColumns(): number;
1843
+ /**
1844
+ * Gets the current puzzle state.
1845
+ * @returns The current state
1846
+ */
1847
+ get state(): PuzzleState;
1848
+ /**
1849
+ * Gets whether undo is possible.
1850
+ * @returns true if undo is possible
1851
+ */
1852
+ get canUndo(): boolean;
1853
+ /**
1854
+ * Gets whether redo is possible.
1855
+ * @returns true if redo is possible
1856
+ */
1857
+ get canRedo(): boolean;
1858
+ /**
1859
+ * Checks if the puzzle is solved.
1860
+ * @returns true if the puzzle is solved
1861
+ */
1862
+ checkIsSolved(): boolean;
1863
+ /**
1864
+ * Checks if the puzzle is valid.
1865
+ * @returns true if the puzzle is valid
1866
+ */
1867
+ checkIsValid(): boolean;
1868
+ /**
1869
+ * Updates a cell value.
1870
+ * @param spec - Cell specification
1871
+ * @param value - New value
1872
+ * @returns Result with this instance
1873
+ */
1874
+ updateCellValue(spec: string | IRowColumn | ICell, value: number | undefined): Result<this>;
1875
+ /**
1876
+ * Updates cell notes.
1877
+ * @param spec - Cell specification
1878
+ * @param notes - New notes
1879
+ * @returns Result with this instance
1880
+ */
1881
+ updateCellNotes(spec: string | IRowColumn | ICell, notes: number[]): Result<this>;
1882
+ /**
1883
+ * Updates multiple cells.
1884
+ * @param updates - Array of cell updates
1885
+ * @returns Result with this instance
1886
+ */
1887
+ updateCells(updates: ICellState[]): Result<this>;
1888
+ /**
1889
+ * Performs an undo operation.
1890
+ * @returns Result with this instance
1891
+ */
1892
+ undo(): Result<this>;
1893
+ /**
1894
+ * Performs a redo operation.
1895
+ * @returns Result with this instance
1896
+ */
1897
+ redo(): Result<this>;
1898
+ /**
1899
+ * Gets the best available hint for the current puzzle state.
1900
+ * @param options - Optional hint generation options
1901
+ * @returns Result containing the best hint
1902
+ */
1903
+ getHint(options?: IHintGenerationOptions): Result<IHint>;
1904
+ /**
1905
+ * Gets all available hints for the current puzzle state.
1906
+ * @param options - Optional hint generation options
1907
+ * @returns Result containing array of hints
1908
+ */
1909
+ getAllHints(options?: IHintGenerationOptions): Result<readonly IHint[]>;
1910
+ /**
1911
+ * Applies a hint to the puzzle, updating the state and adding to undo history.
1912
+ * @param hint - The hint to apply
1913
+ * @returns Result with this instance if successful
1914
+ */
1915
+ applyHint(hint: IHint): Result<this>;
1916
+ /**
1917
+ * Gets hints that specifically affect a given cell.
1918
+ * @param spec - Cell specification (ID, row/column, or cell object)
1919
+ * @param options - Optional hint generation options
1920
+ * @returns Result containing hints affecting the specified cell
1921
+ */
1922
+ getHintsForCell(spec: string | IRowColumn | ICell, options?: IHintGenerationOptions): Result<readonly IHint[]>;
1923
+ /**
1924
+ * Gets a formatted explanation for a hint.
1925
+ * @param hint - The hint to explain
1926
+ * @param level - The explanation level (defaults to configured default)
1927
+ * @returns Formatted explanation string
1928
+ */
1929
+ getExplanation(hint: IHint, level?: ExplanationLevel): string;
1930
+ /**
1931
+ * Validates that a hint can be applied to the current state.
1932
+ * @param hint - The hint to validate
1933
+ * @returns Result indicating validation success or failure
1934
+ */
1935
+ validateHint(hint: IHint): Result<void>;
1936
+ /**
1937
+ * Checks if hints are available for the current state.
1938
+ * @param options - Optional hint generation options
1939
+ * @returns Result containing boolean indicating availability
1940
+ */
1941
+ hasHints(options?: IHintGenerationOptions): Result<boolean>;
1942
+ /**
1943
+ * Gets statistics about available hints.
1944
+ * @param options - Optional hint generation options
1945
+ * @returns Result containing hint statistics
1946
+ */
1947
+ getHintStatistics(options?: IHintGenerationOptions): Result<{
1948
+ totalHints: number;
1949
+ hintsByTechnique: Map<string, number>;
1950
+ hintsByDifficulty: Map<string, number>;
1951
+ }>;
1952
+ /**
1953
+ * Gets a summary of the hint system capabilities.
1954
+ * @returns System capabilities summary
1955
+ */
1956
+ getSystemSummary(): string;
1957
+ /**
1958
+ * Gets the rows.
1959
+ * @returns Array of row cages
1960
+ */
1961
+ get rows(): ICage[];
1962
+ /**
1963
+ * Gets the columns.
1964
+ * @returns Array of column cages
1965
+ */
1966
+ get cols(): ICage[];
1967
+ /**
1968
+ * Gets the sections.
1969
+ * @returns Array of section cages
1970
+ */
1971
+ get sections(): ICage[];
1972
+ /**
1973
+ * Gets all cages.
1974
+ * @returns Array of all cages
1975
+ */
1976
+ get cages(): ICage[];
1977
+ /**
1978
+ * Gets all cells.
1979
+ * @returns Array of all cells
1980
+ */
1981
+ get cells(): ICell[];
1982
+ /**
1983
+ * Gets the next step index.
1984
+ * @returns Next step index
1985
+ */
1986
+ get nextStep(): number;
1987
+ /**
1988
+ * Gets the number of steps.
1989
+ * @returns Number of steps
1990
+ */
1991
+ get numSteps(): number;
1992
+ /**
1993
+ * Gets empty cells.
1994
+ * @returns Array of empty cells
1995
+ */
1996
+ getEmptyCells(): ICell[];
1997
+ /**
1998
+ * Gets invalid cells.
1999
+ * @returns Array of invalid cells
2000
+ */
2001
+ getInvalidCells(): ICell[];
2002
+ /**
2003
+ * Checks if a cell is valid.
2004
+ * @param spec - Cell specification
2005
+ * @returns true if valid
2006
+ */
2007
+ cellIsValid(spec: string | IRowColumn | ICell): boolean;
2008
+ /**
2009
+ * Checks if a cell has a value.
2010
+ * @param spec - Cell specification
2011
+ * @returns true if cell has value
2012
+ */
2013
+ cellHasValue(spec: string | IRowColumn | ICell): boolean;
2014
+ /**
2015
+ * Checks if a value is valid for a cell.
2016
+ * @param spec - Cell specification
2017
+ * @param value - Value to check
2018
+ * @returns true if valid
2019
+ */
2020
+ isValidForCell(spec: string | IRowColumn | ICell, value: number): boolean;
2021
+ /**
2022
+ * Gets a cell neighbor.
2023
+ * @param spec - Cell specification
2024
+ * @param direction - Navigation direction
2025
+ * @param wrap - Wrap behavior
2026
+ * @returns Result containing neighbor cell
2027
+ */
2028
+ getCellNeighbor(spec: string | IRowColumn | ICell, direction: NavigationDirection, wrap: NavigationWrap): Result<ICell>;
2029
+ /**
2030
+ * Gets cell contents.
2031
+ * @param spec - Cell specification
2032
+ * @returns Result containing cell and contents
2033
+ */
2034
+ getCellContents(spec: string | IRowColumn): Result<{
2035
+ cell: ICell;
2036
+ contents: ICellContents;
2037
+ }>;
2038
+ /**
2039
+ * Checks if a cage contains a value.
2040
+ * @param spec - Cage specification
2041
+ * @param value - Value to check
2042
+ * @returns true if cage contains value
2043
+ */
2044
+ cageContainsValue(spec: string | ICage, value: number): boolean;
2045
+ /**
2046
+ * Gets contained values in a cage.
2047
+ * @param spec - Cage specification
2048
+ * @returns Set of contained values
2049
+ */
2050
+ cageContainedValues(spec: string | ICage): Set<number>;
2051
+ /**
2052
+ * Gets string representation of the puzzle.
2053
+ * @returns Array of strings representing puzzle rows
2054
+ */
2055
+ toStrings(): string[];
2056
+ /**
2057
+ * Generates a cache key for the current state and options.
2058
+ * @param options - Hint generation options
2059
+ * @returns Cache key
2060
+ */
2061
+ private _generateCacheKey;
2062
+ /**
2063
+ * Gets cached hints if valid.
2064
+ * @param options - Hint generation options
2065
+ * @returns Cached hints or undefined
2066
+ */
2067
+ private _getCachedHints;
2068
+ /**
2069
+ * Updates the cache with new hints.
2070
+ * @param hints - Generated hints
2071
+ * @param options - Generation options
2072
+ */
2073
+ private _updateCache;
2074
+ /**
2075
+ * Invalidates the current hint cache.
2076
+ */
2077
+ private _invalidateCache;
2078
+ }
2079
+
2080
+ /**
2081
+ * Converts an arbitrary object to a {@link Files.Model.IPuzzlesFile | IPuzzlesFile}.
670
2082
  * @public
671
2083
  */
672
2084
  declare const puzzlesFile: Converter<IPuzzlesFile>;
@@ -733,12 +2145,49 @@ export declare type PuzzleType = 'killer-sudoku' | 'sudoku' | 'sudoku-x';
733
2145
  */
734
2146
  declare const puzzleType: Converter<PuzzleType, ReadonlyArray<PuzzleType>>;
735
2147
 
2148
+ /**
2149
+ * Standard puzzle configurations
2150
+ * @public
2151
+ */
2152
+ export declare const STANDARD_CONFIGS: {
2153
+ readonly puzzle4x4: {
2154
+ readonly cageWidthInCells: 2;
2155
+ readonly cageHeightInCells: 2;
2156
+ readonly boardWidthInCages: 2;
2157
+ readonly boardHeightInCages: 2;
2158
+ };
2159
+ readonly puzzle6x6: {
2160
+ readonly cageWidthInCells: 3;
2161
+ readonly cageHeightInCells: 2;
2162
+ readonly boardWidthInCages: 2;
2163
+ readonly boardHeightInCages: 3;
2164
+ };
2165
+ readonly puzzle9x9: {
2166
+ readonly cageWidthInCells: 3;
2167
+ readonly cageHeightInCells: 3;
2168
+ readonly boardWidthInCages: 3;
2169
+ readonly boardHeightInCages: 3;
2170
+ };
2171
+ readonly puzzle12x12: {
2172
+ readonly cageWidthInCells: 4;
2173
+ readonly cageHeightInCells: 3;
2174
+ readonly boardWidthInCages: 3;
2175
+ readonly boardHeightInCages: 4;
2176
+ };
2177
+ };
2178
+
2179
+ /**
2180
+ * Type for standard configuration names
2181
+ * @public
2182
+ */
2183
+ export declare type StandardConfigName = keyof typeof STANDARD_CONFIGS;
2184
+
736
2185
  /**
737
2186
  * @public
738
2187
  */
739
2188
  declare class SudokuPuzzle extends Puzzle {
740
2189
  private constructor();
741
- static create(puzzle: IPuzzleDescription): Result<Puzzle>;
2190
+ static create(puzzle: IPuzzleDefinition): Result<Puzzle>;
742
2191
  }
743
2192
 
744
2193
  /**
@@ -746,13 +2195,27 @@ declare class SudokuPuzzle extends Puzzle {
746
2195
  */
747
2196
  declare class SudokuXPuzzle extends Puzzle {
748
2197
  private constructor();
749
- static create(puzzle: IPuzzleDescription): Result<Puzzle>;
2198
+ static create(puzzle: IPuzzleDefinition): Result<Puzzle>;
750
2199
  private static _getXCages;
751
2200
  }
752
2201
 
753
2202
  /**
754
- * The minimum and maximum possible values for a {@link ICage | cage}, by cage size in
755
- * {@link ICell | cells}.
2203
+ * Nominal identifier for a hint generation technique.
2204
+ * @public
2205
+ */
2206
+ declare type TechniqueId = Brand<string, 'TechniqueId'>;
2207
+
2208
+ /**
2209
+ * Standard technique identifiers for built-in solving techniques.
2210
+ * @public
2211
+ */
2212
+ declare const TechniqueIds: {
2213
+ readonly NAKED_SINGLES: TechniqueId;
2214
+ readonly HIDDEN_SINGLES: TechniqueId;
2215
+ };
2216
+
2217
+ /**
2218
+ * Legacy array for backward compatibility - supports standard 9x9 Sudoku
756
2219
  * @public
757
2220
  */
758
2221
  export declare const totalsByCageSize: readonly {