@logic-pad/core 0.13.3 → 0.14.0

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 (77) hide show
  1. package/assets/logic-core.global.d.ts +57 -2
  2. package/dist/data/config.d.ts +1 -0
  3. package/dist/data/configurable.d.ts +2 -0
  4. package/dist/data/instruction.d.ts +1 -0
  5. package/dist/data/instruction.js +3 -0
  6. package/dist/data/puzzle.js +3 -1
  7. package/dist/data/rules/banPatternRule.d.ts +1 -0
  8. package/dist/data/rules/banPatternRule.js +10 -0
  9. package/dist/data/rules/cellCountPerZoneRule.d.ts +2 -0
  10. package/dist/data/rules/cellCountPerZoneRule.js +9 -0
  11. package/dist/data/rules/cellCountRule.d.ts +1 -0
  12. package/dist/data/rules/cellCountRule.js +6 -0
  13. package/dist/data/rules/completePatternRule.d.ts +2 -0
  14. package/dist/data/rules/completePatternRule.js +9 -0
  15. package/dist/data/rules/connectAllRule.d.ts +1 -0
  16. package/dist/data/rules/connectAllRule.js +6 -0
  17. package/dist/data/rules/containsShapeRule.d.ts +1 -0
  18. package/dist/data/rules/containsShapeRule.js +10 -0
  19. package/dist/data/rules/customRule.d.ts +2 -0
  20. package/dist/data/rules/customRule.js +11 -0
  21. package/dist/data/rules/foresightRule.d.ts +2 -0
  22. package/dist/data/rules/foresightRule.js +13 -0
  23. package/dist/data/rules/lyingSymbolRule.d.ts +1 -0
  24. package/dist/data/rules/lyingSymbolRule.js +19 -0
  25. package/dist/data/rules/musicControlLine.d.ts +4 -0
  26. package/dist/data/rules/musicControlLine.js +29 -0
  27. package/dist/data/rules/musicGridRule.d.ts +2 -0
  28. package/dist/data/rules/musicGridRule.js +11 -0
  29. package/dist/data/rules/mysteryRule.d.ts +2 -0
  30. package/dist/data/rules/mysteryRule.js +11 -0
  31. package/dist/data/rules/offByXRule.d.ts +1 -0
  32. package/dist/data/rules/offByXRule.js +6 -0
  33. package/dist/data/rules/perfectionRule.d.ts +2 -0
  34. package/dist/data/rules/perfectionRule.js +9 -0
  35. package/dist/data/rules/regionAreaRule.d.ts +1 -0
  36. package/dist/data/rules/regionAreaRule.js +6 -0
  37. package/dist/data/rules/sameShapeRule.d.ts +1 -0
  38. package/dist/data/rules/sameShapeRule.js +6 -0
  39. package/dist/data/rules/symbolsPerRegionRule.d.ts +1 -0
  40. package/dist/data/rules/symbolsPerRegionRule.js +6 -0
  41. package/dist/data/rules/undercluedRule.d.ts +2 -0
  42. package/dist/data/rules/undercluedRule.js +9 -0
  43. package/dist/data/rules/uniqueShapeRule.d.ts +1 -0
  44. package/dist/data/rules/uniqueShapeRule.js +6 -0
  45. package/dist/data/rules/wrapAroundRule.d.ts +2 -0
  46. package/dist/data/rules/wrapAroundRule.js +9 -0
  47. package/dist/data/serializer/compressor/checksumCompressor.js +1 -1
  48. package/dist/data/serializer/serializer_checksum.d.ts +3 -0
  49. package/dist/data/serializer/serializer_checksum.js +10 -1
  50. package/dist/data/shapes.js +6 -0
  51. package/dist/data/symbols/areaNumberSymbol.d.ts +1 -0
  52. package/dist/data/symbols/areaNumberSymbol.js +6 -0
  53. package/dist/data/symbols/customIconSymbol.d.ts +2 -0
  54. package/dist/data/symbols/customIconSymbol.js +13 -0
  55. package/dist/data/symbols/customTextSymbol.d.ts +2 -0
  56. package/dist/data/symbols/customTextSymbol.js +13 -0
  57. package/dist/data/symbols/dartSymbol.d.ts +1 -0
  58. package/dist/data/symbols/dartSymbol.js +6 -0
  59. package/dist/data/symbols/directionLinkerSymbol.d.ts +1 -5
  60. package/dist/data/symbols/directionLinkerSymbol.js +0 -3
  61. package/dist/data/symbols/focusSymbol.d.ts +1 -0
  62. package/dist/data/symbols/focusSymbol.js +6 -0
  63. package/dist/data/symbols/galaxySymbol.d.ts +1 -0
  64. package/dist/data/symbols/galaxySymbol.js +6 -0
  65. package/dist/data/symbols/hiddenSymbol.d.ts +2 -0
  66. package/dist/data/symbols/hiddenSymbol.js +10 -0
  67. package/dist/data/symbols/letterSymbol.d.ts +1 -0
  68. package/dist/data/symbols/letterSymbol.js +7 -0
  69. package/dist/data/symbols/lotusSymbol.d.ts +1 -0
  70. package/dist/data/symbols/lotusSymbol.js +6 -0
  71. package/dist/data/symbols/minesweeperSymbol.d.ts +1 -0
  72. package/dist/data/symbols/minesweeperSymbol.js +6 -0
  73. package/dist/data/symbols/myopiaSymbol.d.ts +1 -0
  74. package/dist/data/symbols/myopiaSymbol.js +5 -0
  75. package/dist/data/symbols/viewpointSymbol.d.ts +1 -0
  76. package/dist/data/symbols/viewpointSymbol.js +6 -0
  77. package/package.json +2 -2
@@ -344,6 +344,8 @@ declare global {
344
344
  get value(): T;
345
345
  }
346
346
  export declare abstract class Configurable {
347
+ abstract get title(): string;
348
+ abstract get configExplanation(): string;
347
349
  get configs(): readonly AnyConfig[] | null;
348
350
  abstract copyWith(props: Record<string, unknown>): this;
349
351
  /**
@@ -357,6 +359,7 @@ declare global {
357
359
  export declare abstract class Instruction extends Configurable {
358
360
  abstract get id(): string;
359
361
  abstract get explanation(): string;
362
+ get configExplanation(): string;
360
363
  abstract createExampleGrid(): GridData;
361
364
  /**
362
365
  * Indicates that validation by logic is not available and the solution must be used for validation
@@ -492,6 +495,9 @@ declare global {
492
495
  * Ranges from 0 to 1
493
496
  */
494
497
  readonly velocity: number | null;
498
+ readonly title = 'Music Grid - Row';
499
+ readonly configExplanation =
500
+ 'Configure the playback settings from this tile onwards.';
495
501
  private static readonly CONFIGS;
496
502
  constructor(
497
503
  /**
@@ -520,6 +526,9 @@ declare global {
520
526
  readonly pedal: boolean | null;
521
527
  readonly checkpoint: boolean;
522
528
  readonly rows: readonly Row[];
529
+ readonly title = 'Music Grid - Control Line';
530
+ readonly configExplanation =
531
+ 'Configure the playback settings from this point onwards.';
523
532
  private static readonly CONFIGS;
524
533
  /**
525
534
  * Configure playback settings, taking effect at the given column (inclusive)
@@ -565,6 +574,8 @@ declare global {
565
574
  readonly controlLines: readonly ControlLine[];
566
575
  readonly track: GridData | null;
567
576
  readonly normalizeVelocity: boolean;
577
+ readonly title = 'Music Grid';
578
+ get configExplanation(): string;
568
579
  private static readonly EXAMPLE_GRID;
569
580
  private static readonly CONFIGS;
570
581
  private static readonly SEARCH_VARIANTS;
@@ -621,6 +632,8 @@ declare global {
621
632
  ): ControlLine[];
622
633
  }
623
634
  export declare class CompletePatternRule extends Rule {
635
+ readonly title = 'Complete The Pattern';
636
+ get configExplanation(): string;
624
637
  private static readonly EXAMPLE_GRID;
625
638
  private static readonly SEARCH_VARIANTS;
626
639
  /**
@@ -639,6 +652,8 @@ declare global {
639
652
  get isSingleton(): boolean;
640
653
  }
641
654
  export declare class UndercluedRule extends Rule {
655
+ readonly title = 'Underclued';
656
+ get configExplanation(): string;
642
657
  private static readonly EXAMPLE_GRID;
643
658
  private static readonly SEARCH_VARIANTS;
644
659
  /**
@@ -665,6 +680,8 @@ declare global {
665
680
  export declare class WrapAroundRule extends Rule implements GetTileHandler {
666
681
  readonly horizontal: Wrapping;
667
682
  readonly vertical: Wrapping;
683
+ readonly title = 'Wrap Around';
684
+ get configExplanation(): string;
668
685
  private static readonly EXAMPLE_GRID_NONE;
669
686
  private static readonly EXAMPLE_GRID_HORIZONTAL;
670
687
  private static readonly EXAMPLE_GRID_VERTICAL;
@@ -1225,6 +1242,7 @@ declare global {
1225
1242
  readonly type: ConfigType;
1226
1243
  readonly field: string;
1227
1244
  readonly description: string;
1245
+ readonly explanation?: string;
1228
1246
  readonly default: T;
1229
1247
  readonly configurable: boolean;
1230
1248
  }
@@ -1495,6 +1513,7 @@ declare global {
1495
1513
  tileMapper?: (tile: TileData) => TileData
1496
1514
  ): GridData;
1497
1515
  export declare class BanPatternRule extends Rule {
1516
+ readonly title = 'Ban Pattern';
1498
1517
  private static readonly EXAMPLE_GRID;
1499
1518
  private static readonly CONFIGS;
1500
1519
  private static readonly SEARCH_VARIANTS;
@@ -1517,6 +1536,8 @@ declare global {
1517
1536
  }
1518
1537
  export declare class CellCountPerZoneRule extends Rule {
1519
1538
  readonly color: Color;
1539
+ readonly title = 'Equal Count Per Zone';
1540
+ get configExplanation(): string;
1520
1541
  private static readonly CONFIGS;
1521
1542
  private static readonly EXAMPLE_GRID_LIGHT;
1522
1543
  private static readonly EXAMPLE_GRID_DARK;
@@ -1540,6 +1561,7 @@ declare global {
1540
1561
  export declare class CellCountRule extends Rule {
1541
1562
  readonly color: Color;
1542
1563
  readonly count: number;
1564
+ readonly title = 'Total Count';
1543
1565
  private static readonly CONFIGS;
1544
1566
  private static readonly EXAMPLE_GRID_LIGHT;
1545
1567
  private static readonly EXAMPLE_GRID_DARK;
@@ -1563,6 +1585,7 @@ declare global {
1563
1585
  }
1564
1586
  export declare class ConnectAllRule extends Rule {
1565
1587
  readonly color: Color;
1588
+ readonly title = 'Connect All';
1566
1589
  private static readonly CONFIGS;
1567
1590
  private static readonly EXAMPLE_GRID_LIGHT;
1568
1591
  private static readonly EXAMPLE_GRID_DARK;
@@ -1600,6 +1623,7 @@ declare global {
1600
1623
  withColor(color: Color): this;
1601
1624
  }
1602
1625
  export declare class ContainsShapeRule extends RegionShapeRule {
1626
+ readonly title = 'Areas Contain Pattern';
1603
1627
  private static readonly EXAMPLE_GRID_LIGHT;
1604
1628
  private static readonly EXAMPLE_GRID_DARK;
1605
1629
  private static readonly CONFIGS;
@@ -1625,6 +1649,8 @@ declare global {
1625
1649
  export declare class CustomRule extends Rule {
1626
1650
  readonly description: string;
1627
1651
  readonly grid: GridData;
1652
+ readonly title = 'Custom Rule';
1653
+ get configExplanation(): string;
1628
1654
  private static readonly EXAMPLE_GRID;
1629
1655
  static readonly configs: readonly AnyConfig[];
1630
1656
  private static readonly SEARCH_VARIANTS;
@@ -1657,6 +1683,8 @@ declare global {
1657
1683
  readonly regenInterval: number;
1658
1684
  readonly startFull: boolean;
1659
1685
  readonly solvePath: Position$1[];
1686
+ readonly title = 'Foresight';
1687
+ get configExplanation(): string;
1660
1688
  private static readonly EXAMPLE_GRID;
1661
1689
  private static readonly CONFIGS;
1662
1690
  private static readonly SEARCH_VARIANTS;
@@ -1697,6 +1725,7 @@ declare global {
1697
1725
  implements FinalValidationHandler
1698
1726
  {
1699
1727
  readonly count: number;
1728
+ readonly title = 'Lying Symbols';
1700
1729
  private static readonly EXAMPLE_GRID;
1701
1730
  private static readonly CONFIGS;
1702
1731
  private static readonly SEARCH_VARIANTS;
@@ -1727,6 +1756,8 @@ declare global {
1727
1756
  {
1728
1757
  readonly solution: GridData;
1729
1758
  readonly visible: boolean;
1759
+ readonly title = 'Alternate Solution';
1760
+ get configExplanation(): string;
1730
1761
  private static readonly EXAMPLE_GRID;
1731
1762
  private static readonly CONFIGS;
1732
1763
  private static readonly SEARCH_VARIANTS;
@@ -1770,6 +1801,7 @@ declare global {
1770
1801
  implements SymbolValidationHandler
1771
1802
  {
1772
1803
  readonly number: number;
1804
+ readonly title = 'Off By X';
1773
1805
  private static readonly CONFIGS;
1774
1806
  private static readonly EXAMPLE_GRID;
1775
1807
  private static readonly SEARCH_VARIANTS;
@@ -1799,6 +1831,8 @@ declare global {
1799
1831
  implements SetGridHandler, FinalValidationHandler
1800
1832
  {
1801
1833
  readonly editor: boolean;
1834
+ readonly title = 'Perfection';
1835
+ get configExplanation(): string;
1802
1836
  private static readonly EXAMPLE_GRID;
1803
1837
  private static readonly SEARCH_VARIANTS;
1804
1838
  /**
@@ -1842,6 +1876,7 @@ declare global {
1842
1876
  export declare class RegionAreaRule extends Rule {
1843
1877
  readonly color: Color;
1844
1878
  readonly size: number;
1879
+ readonly title = 'Region Area Size';
1845
1880
  private static readonly CONFIGS;
1846
1881
  private static readonly EXAMPLE_GRID_DARK;
1847
1882
  private static readonly EXAMPLE_GRID_LIGHT;
@@ -1865,6 +1900,7 @@ declare global {
1865
1900
  withSize(size: number): this;
1866
1901
  }
1867
1902
  export declare class SameShapeRule extends RegionShapeRule {
1903
+ readonly title = 'Same Shape Areas';
1868
1904
  private static readonly CONFIGS;
1869
1905
  private static readonly EXAMPLE_GRID_LIGHT;
1870
1906
  private static readonly EXAMPLE_GRID_DARK;
@@ -1887,6 +1923,7 @@ declare global {
1887
1923
  readonly color: Color;
1888
1924
  readonly count: number;
1889
1925
  readonly comparison: Comparison;
1926
+ readonly title = 'Symbols Per Area';
1890
1927
  private static readonly SYMBOL_POSITIONS;
1891
1928
  private static readonly CONFIGS;
1892
1929
  private static readonly EXAMPLE_GRIDS;
@@ -1920,6 +1957,7 @@ declare global {
1920
1957
  private static countAllSymbolsOfPosition;
1921
1958
  }
1922
1959
  export declare class UniqueShapeRule extends RegionShapeRule {
1960
+ readonly title = 'Unique Shape Areas';
1923
1961
  private static readonly CONFIGS;
1924
1962
  private static readonly EXAMPLE_GRID_LIGHT;
1925
1963
  private static readonly EXAMPLE_GRID_DARK;
@@ -2101,8 +2139,11 @@ declare global {
2101
2139
  parseRules(_input: string): Rule[];
2102
2140
  stringifySymbols(symbols: ReadonlyMap<string, readonly Symbol$1[]>): string;
2103
2141
  parseSymbols(_input: string): Map<string, Symbol$1[]>;
2142
+ stringifyGrid(grid: GridData): string;
2104
2143
  parseGrid(_input: string): GridData;
2144
+ stringifyGridWithSolution(puzzle: PuzzleData): string;
2105
2145
  parseGridWithSolution(_input: string): PuzzleData;
2146
+ stringifyPuzzle(puzzle: Puzzle): string;
2106
2147
  parsePuzzle(_input: string): Puzzle;
2107
2148
  }
2108
2149
  /**
@@ -2338,6 +2379,7 @@ declare global {
2338
2379
  withNumber(number: number): this;
2339
2380
  }
2340
2381
  export declare class AreaNumberSymbol extends NumberSymbol {
2382
+ readonly title = 'Area Number';
2341
2383
  private static readonly CONFIGS;
2342
2384
  private static readonly EXAMPLE_GRID;
2343
2385
  /**
@@ -2378,6 +2420,7 @@ declare global {
2378
2420
  }
2379
2421
  export declare class DartSymbol extends NumberSymbol {
2380
2422
  readonly orientation: Orientation;
2423
+ readonly title = 'Dart';
2381
2424
  private static readonly CONFIGS;
2382
2425
  private static readonly EXAMPLE_GRID;
2383
2426
  /**
@@ -2418,7 +2461,7 @@ declare global {
2418
2461
  private buildCheckAndRating;
2419
2462
  }
2420
2463
  export type DirectionLinkerMap = Record<Direction, Direction>;
2421
- export declare class DirectionLinkerSymbol extends Symbol$1 {
2464
+ export declare abstract class DirectionLinkerSymbol extends Symbol$1 {
2422
2465
  readonly x: number;
2423
2466
  readonly y: number;
2424
2467
  private static readonly CONFIGS;
@@ -2439,7 +2482,6 @@ declare global {
2439
2482
  createExampleGrid(): GridData;
2440
2483
  private deltaCoordinate;
2441
2484
  validateSymbol(grid: GridData): State;
2442
- copyWith({ x, y }: { x?: number; y?: number }): this;
2443
2485
  private getInitialCheckedCouples;
2444
2486
  }
2445
2487
  export declare abstract class DirectionLinkerBTModule extends BTModule {
@@ -2455,6 +2497,7 @@ declare global {
2455
2497
  ): Position$1 | null;
2456
2498
  }
2457
2499
  export declare class FocusSymbol extends NumberSymbol {
2500
+ readonly title = 'Focus Number';
2458
2501
  private static readonly CONFIGS;
2459
2502
  private static readonly EXAMPLE_GRID;
2460
2503
  /**
@@ -2494,6 +2537,7 @@ declare global {
2494
2537
  export declare class GalaxySymbol extends DirectionLinkerSymbol {
2495
2538
  readonly x: number;
2496
2539
  readonly y: number;
2540
+ readonly title = 'Galaxy';
2497
2541
  private static readonly linkedDirections;
2498
2542
  /**
2499
2543
  * **Galaxies are centers of rotational symmetry**
@@ -2522,6 +2566,7 @@ declare global {
2522
2566
  readonly x: number;
2523
2567
  readonly y: number;
2524
2568
  readonly letter: string;
2569
+ readonly title = 'Letter';
2525
2570
  private static readonly CONFIGS;
2526
2571
  private static readonly EXAMPLE_GRID;
2527
2572
  /**
@@ -2559,6 +2604,7 @@ declare global {
2559
2604
  readonly x: number;
2560
2605
  readonly y: number;
2561
2606
  readonly orientation: Orientation;
2607
+ readonly title = 'Lotus';
2562
2608
  private static readonly linkedDirectionsFromOrientation;
2563
2609
  /**
2564
2610
  * **Areas containing this symbol must be symmetrical**
@@ -2595,6 +2641,7 @@ declare global {
2595
2641
  checkGlobal(grid: BTGridData): false | CheckResult;
2596
2642
  }
2597
2643
  export declare class MinesweeperSymbol extends NumberSymbol {
2644
+ readonly title = 'Minesweeper Number';
2598
2645
  private static readonly CONFIGS;
2599
2646
  private static readonly EXAMPLE_GRID;
2600
2647
  /**
@@ -2643,6 +2690,7 @@ declare global {
2643
2690
  export declare class MyopiaSymbol extends MultiEntrySymbol {
2644
2691
  readonly diagonals: boolean;
2645
2692
  readonly directions: OrientationToggle;
2693
+ get title(): 'Framed Myopia Arrow' | 'Myopia Arrow';
2646
2694
  private static readonly CONFIGS;
2647
2695
  private static readonly EXAMPLE_GRID;
2648
2696
  private static readonly EXAMPLE_DIAGONAL_GRID;
@@ -2685,6 +2733,7 @@ declare global {
2685
2733
  checkGlobal(grid: BTGridData): CheckResult | false;
2686
2734
  }
2687
2735
  export declare class ViewpointSymbol extends NumberSymbol {
2736
+ readonly title = 'Viewpoint Number';
2688
2737
  private static readonly CONFIGS;
2689
2738
  private static readonly EXAMPLE_GRID;
2690
2739
  /**
@@ -2856,6 +2905,8 @@ declare global {
2856
2905
  export declare class CustomIconSymbol extends CustomSymbol {
2857
2906
  readonly icon: string;
2858
2907
  readonly rotation: number;
2908
+ readonly title = 'Custom Icon Symbol';
2909
+ get configExplanation(): string;
2859
2910
  private static readonly EXAMPLE_GRID;
2860
2911
  private static readonly CONFIGS;
2861
2912
  /**
@@ -2899,6 +2950,8 @@ declare global {
2899
2950
  export declare class CustomTextSymbol extends CustomSymbol {
2900
2951
  readonly text: string;
2901
2952
  readonly rotation: number;
2953
+ readonly title = 'Custom Text Symbol';
2954
+ get configExplanation(): string;
2902
2955
  private static readonly EXAMPLE_GRID;
2903
2956
  private static readonly CONFIGS;
2904
2957
  /**
@@ -2946,6 +2999,8 @@ declare global {
2946
2999
  readonly x: number;
2947
3000
  readonly y: number;
2948
3001
  readonly revealLocation: boolean;
3002
+ readonly title = 'Hidden Symbol Marker';
3003
+ get configExplanation(): string;
2949
3004
  private static readonly CONFIGS;
2950
3005
  private static readonly EXAMPLE_GRID;
2951
3006
  /**
@@ -26,6 +26,7 @@ export interface Config<T> {
26
26
  readonly type: ConfigType;
27
27
  readonly field: string;
28
28
  readonly description: string;
29
+ readonly explanation?: string;
29
30
  readonly default: T;
30
31
  readonly configurable: boolean;
31
32
  }
@@ -1,5 +1,7 @@
1
1
  import { AnyConfig } from './config.js';
2
2
  export default abstract class Configurable {
3
+ abstract get title(): string;
4
+ abstract get configExplanation(): string;
3
5
  get configs(): readonly AnyConfig[] | null;
4
6
  abstract copyWith(props: Record<string, unknown>): this;
5
7
  /**
@@ -4,6 +4,7 @@ import { Mode } from './primitives.js';
4
4
  export default abstract class Instruction extends Configurable {
5
5
  abstract get id(): string;
6
6
  abstract get explanation(): string;
7
+ get configExplanation(): string;
7
8
  abstract createExampleGrid(): GridData;
8
9
  /**
9
10
  * Indicates that validation by logic is not available and the solution must be used for validation
@@ -1,5 +1,8 @@
1
1
  import Configurable from './configurable.js';
2
2
  export default class Instruction extends Configurable {
3
+ get configExplanation() {
4
+ return this.explanation;
5
+ }
3
6
  /**
4
7
  * Indicates that validation by logic is not available and the solution must be used for validation
5
8
  */
@@ -77,7 +77,9 @@ export function validatePuzzleChecklist(metadata, gridWithSolution, state) {
77
77
  });
78
78
  checklist.items.push({
79
79
  id: 'solutionIsNotEmpty',
80
- success: gridWithSolution.tiles.some(row => row.some(tile => !tile.fixed && tile.color !== Color.Gray)),
80
+ success: gridWithSolution.musicGrid.value
81
+ ? gridWithSolution.tiles.some(row => row.some(tile => !tile.fixed && tile.color === Color.Dark))
82
+ : gridWithSolution.tiles.some(row => row.some(tile => !tile.fixed && tile.color !== Color.Gray)),
81
83
  mandatory: true,
82
84
  });
83
85
  }
@@ -4,6 +4,7 @@ import { RuleState } from '../primitives.js';
4
4
  import { Shape } from '../shapes.js';
5
5
  import Rule, { SearchVariant } from './rule.js';
6
6
  export default class BanPatternRule extends Rule {
7
+ readonly title = "Ban Pattern";
7
8
  private static readonly EXAMPLE_GRID;
8
9
  private static readonly CONFIGS;
9
10
  private static readonly SEARCH_VARIANTS;
@@ -12,6 +12,12 @@ class BanPatternRule extends Rule {
12
12
  */
13
13
  constructor(pattern) {
14
14
  super();
15
+ Object.defineProperty(this, "title", {
16
+ enumerable: true,
17
+ configurable: true,
18
+ writable: true,
19
+ value: 'Ban Pattern'
20
+ });
15
21
  Object.defineProperty(this, "pattern", {
16
22
  enumerable: true,
17
23
  configurable: true,
@@ -51,6 +57,9 @@ class BanPatternRule extends Rule {
51
57
  });
52
58
  const width = maxX - minX + 1;
53
59
  const height = maxY - minY + 1;
60
+ if (!Number.isFinite(width) || !Number.isFinite(height)) {
61
+ return GridData.create(0, 0);
62
+ }
54
63
  const tiles = array(width, height, (x, y) => {
55
64
  const tile = this.pattern.getTile(x + minX, y + minY);
56
65
  if (!tile.exists || tile.color !== Color.Gray)
@@ -130,6 +139,7 @@ Object.defineProperty(BanPatternRule, "CONFIGS", {
130
139
  resizable: true,
131
140
  field: 'pattern',
132
141
  description: 'Pattern',
142
+ explanation: 'The pattern to be banned. Can be a mix of dark and light tiles.',
133
143
  configurable: true,
134
144
  },
135
145
  ])
@@ -4,6 +4,8 @@ import { Color, RuleState } from '../primitives.js';
4
4
  import Rule, { SearchVariant } from './rule.js';
5
5
  export default class CellCountPerZoneRule extends Rule {
6
6
  readonly color: Color;
7
+ readonly title = "Equal Count Per Zone";
8
+ get configExplanation(): string;
7
9
  private static readonly CONFIGS;
8
10
  private static readonly EXAMPLE_GRID_LIGHT;
9
11
  private static readonly EXAMPLE_GRID_DARK;
@@ -5,6 +5,9 @@ import GridZones from '../gridZones.js';
5
5
  import { Color, State } from '../primitives.js';
6
6
  import Rule from './rule.js';
7
7
  class CellCountPerZoneRule extends Rule {
8
+ get configExplanation() {
9
+ return 'Use the zone tool to define areas on the grid.';
10
+ }
8
11
  /**
9
12
  * **Zones of the same size have the same number of &lt;color&gt; cells.**
10
13
  *
@@ -18,6 +21,12 @@ class CellCountPerZoneRule extends Rule {
18
21
  writable: true,
19
22
  value: color
20
23
  });
24
+ Object.defineProperty(this, "title", {
25
+ enumerable: true,
26
+ configurable: true,
27
+ writable: true,
28
+ value: 'Equal Count Per Zone'
29
+ });
21
30
  this.color = color;
22
31
  }
23
32
  get id() {
@@ -5,6 +5,7 @@ import Rule, { SearchVariant } from './rule.js';
5
5
  export default class CellCountRule extends Rule {
6
6
  readonly color: Color;
7
7
  readonly count: number;
8
+ readonly title = "Total Count";
8
9
  private static readonly CONFIGS;
9
10
  private static readonly EXAMPLE_GRID_LIGHT;
10
11
  private static readonly EXAMPLE_GRID_DARK;
@@ -24,6 +24,12 @@ class CellCountRule extends Rule {
24
24
  writable: true,
25
25
  value: count
26
26
  });
27
+ Object.defineProperty(this, "title", {
28
+ enumerable: true,
29
+ configurable: true,
30
+ writable: true,
31
+ value: 'Total Count'
32
+ });
27
33
  this.color = color;
28
34
  this.count = count;
29
35
  }
@@ -2,6 +2,8 @@ import GridData from '../grid.js';
2
2
  import { RuleState } from '../primitives.js';
3
3
  import Rule, { SearchVariant } from './rule.js';
4
4
  export default class CompletePatternRule extends Rule {
5
+ readonly title = "Complete The Pattern";
6
+ get configExplanation(): string;
5
7
  private static readonly EXAMPLE_GRID;
6
8
  private static readonly SEARCH_VARIANTS;
7
9
  /**
@@ -2,6 +2,9 @@ import GridData from '../grid.js';
2
2
  import { MajorRule, State } from '../primitives.js';
3
3
  import Rule from './rule.js';
4
4
  class CompletePatternRule extends Rule {
5
+ get configExplanation() {
6
+ return 'Complete the grid by pattern recognition. Your provided solution may override auto-validation.';
7
+ }
5
8
  /**
6
9
  * **Complete the pattern**
7
10
  *
@@ -9,6 +12,12 @@ class CompletePatternRule extends Rule {
9
12
  */
10
13
  constructor() {
11
14
  super();
15
+ Object.defineProperty(this, "title", {
16
+ enumerable: true,
17
+ configurable: true,
18
+ writable: true,
19
+ value: 'Complete The Pattern'
20
+ });
12
21
  }
13
22
  get id() {
14
23
  return MajorRule.CompletePattern;
@@ -4,6 +4,7 @@ import { Color, RuleState } from '../primitives.js';
4
4
  import Rule, { SearchVariant } from './rule.js';
5
5
  export default class ConnectAllRule extends Rule {
6
6
  readonly color: Color;
7
+ readonly title = "Connect All";
7
8
  private static readonly CONFIGS;
8
9
  private static readonly EXAMPLE_GRID_LIGHT;
9
10
  private static readonly EXAMPLE_GRID_DARK;
@@ -17,6 +17,12 @@ class ConnectAllRule extends Rule {
17
17
  writable: true,
18
18
  value: color
19
19
  });
20
+ Object.defineProperty(this, "title", {
21
+ enumerable: true,
22
+ configurable: true,
23
+ writable: true,
24
+ value: 'Connect All'
25
+ });
20
26
  this.color = color;
21
27
  }
22
28
  get id() {
@@ -5,6 +5,7 @@ import { Shape } from '../shapes.js';
5
5
  import RegionShapeRule from './regionShapeRule.js';
6
6
  import { SearchVariant } from './rule.js';
7
7
  export default class ContainsShapeRule extends RegionShapeRule {
8
+ readonly title = "Areas Contain Pattern";
8
9
  private static readonly EXAMPLE_GRID_LIGHT;
9
10
  private static readonly EXAMPLE_GRID_DARK;
10
11
  private static readonly CONFIGS;
@@ -13,6 +13,12 @@ class ContainsShapeRule extends RegionShapeRule {
13
13
  */
14
14
  constructor(color, pattern) {
15
15
  super(color);
16
+ Object.defineProperty(this, "title", {
17
+ enumerable: true,
18
+ configurable: true,
19
+ writable: true,
20
+ value: 'Areas Contain Pattern'
21
+ });
16
22
  Object.defineProperty(this, "pattern", {
17
23
  enumerable: true,
18
24
  configurable: true,
@@ -52,6 +58,9 @@ class ContainsShapeRule extends RegionShapeRule {
52
58
  });
53
59
  const width = maxX - minX + 1;
54
60
  const height = maxY - minY + 1;
61
+ if (!Number.isFinite(width) || !Number.isFinite(height)) {
62
+ return GridData.create(0, 0);
63
+ }
55
64
  const tiles = array(width, height, (x, y) => {
56
65
  const tile = this.pattern.getTile(x + minX, y + minY);
57
66
  if (!tile.exists || tile.color !== Color.Gray)
@@ -134,6 +143,7 @@ Object.defineProperty(ContainsShapeRule, "CONFIGS", {
134
143
  resizable: true,
135
144
  field: 'pattern',
136
145
  description: 'Pattern',
146
+ explanation: 'The pattern to be contained. Must only include tiles of the selected color.',
137
147
  configurable: true,
138
148
  },
139
149
  ])
@@ -5,6 +5,8 @@ import Rule, { SearchVariant } from './rule.js';
5
5
  export default class CustomRule extends Rule {
6
6
  readonly description: string;
7
7
  readonly grid: GridData;
8
+ readonly title = "Custom Rule";
9
+ get configExplanation(): string;
8
10
  private static readonly EXAMPLE_GRID;
9
11
  static readonly configs: readonly AnyConfig[];
10
12
  private static readonly SEARCH_VARIANTS;
@@ -3,6 +3,9 @@ import GridData from '../grid.js';
3
3
  import { State } from '../primitives.js';
4
4
  import Rule from './rule.js';
5
5
  class CustomRule extends Rule {
6
+ get configExplanation() {
7
+ return 'A customizable rule. Your provided solution may override auto-validation.';
8
+ }
6
9
  /**
7
10
  * A custom rule with a description and thumbnail grid.
8
11
  *
@@ -25,6 +28,12 @@ class CustomRule extends Rule {
25
28
  writable: true,
26
29
  value: grid
27
30
  });
31
+ Object.defineProperty(this, "title", {
32
+ enumerable: true,
33
+ configurable: true,
34
+ writable: true,
35
+ value: 'Custom Rule'
36
+ });
28
37
  this.description = description;
29
38
  this.grid = grid;
30
39
  }
@@ -69,6 +78,7 @@ Object.defineProperty(CustomRule, "configs", {
69
78
  default: 'A *custom* rule',
70
79
  field: 'description',
71
80
  description: 'Description',
81
+ explanation: 'A short descriptive text. Use *asterisks* to highlight keywords.',
72
82
  configurable: true,
73
83
  },
74
84
  {
@@ -76,6 +86,7 @@ Object.defineProperty(CustomRule, "configs", {
76
86
  default: CustomRule.EXAMPLE_GRID,
77
87
  field: 'grid',
78
88
  description: 'Thumbnail Grid',
89
+ explanation: 'An example grid showing the rule.',
79
90
  configurable: true,
80
91
  },
81
92
  ])
@@ -7,6 +7,8 @@ export default class ForesightRule extends Rule {
7
7
  readonly regenInterval: number;
8
8
  readonly startFull: boolean;
9
9
  readonly solvePath: Position[];
10
+ readonly title = "Foresight";
11
+ get configExplanation(): string;
10
12
  private static readonly EXAMPLE_GRID;
11
13
  private static readonly CONFIGS;
12
14
  private static readonly SEARCH_VARIANTS;
@@ -4,6 +4,9 @@ import { State, Mode } from '../primitives.js';
4
4
  import CustomIconSymbol from '../symbols/customIconSymbol.js';
5
5
  import Rule from './rule.js';
6
6
  class ForesightRule extends Rule {
7
+ get configExplanation() {
8
+ return 'Provide automatic hints to the player.';
9
+ }
7
10
  /**
8
11
  * **Foresight: Show hints**
9
12
  */
@@ -33,6 +36,12 @@ class ForesightRule extends Rule {
33
36
  writable: true,
34
37
  value: solvePath
35
38
  });
39
+ Object.defineProperty(this, "title", {
40
+ enumerable: true,
41
+ configurable: true,
42
+ writable: true,
43
+ value: 'Foresight'
44
+ });
36
45
  this.count = count;
37
46
  this.regenInterval = regenInterval;
38
47
  this.startFull = startFull;
@@ -93,6 +102,7 @@ Object.defineProperty(ForesightRule, "CONFIGS", {
93
102
  min: 1,
94
103
  field: 'count',
95
104
  description: 'Foresight count',
105
+ explanation: 'Maximum number of foresight charges that can be stored.',
96
106
  configurable: true,
97
107
  },
98
108
  {
@@ -101,6 +111,7 @@ Object.defineProperty(ForesightRule, "CONFIGS", {
101
111
  min: 1,
102
112
  field: 'regenInterval',
103
113
  description: 'Regen Interval (seconds)',
114
+ explanation: 'Time taken for one foresight charge to regenerate.',
104
115
  configurable: true,
105
116
  },
106
117
  {
@@ -108,6 +119,7 @@ Object.defineProperty(ForesightRule, "CONFIGS", {
108
119
  default: false,
109
120
  field: 'startFull',
110
121
  description: 'Start with full foresight',
122
+ explanation: 'Whether to start with all foresight charges available.',
111
123
  configurable: true,
112
124
  },
113
125
  {
@@ -115,6 +127,7 @@ Object.defineProperty(ForesightRule, "CONFIGS", {
115
127
  default: [],
116
128
  field: 'solvePath',
117
129
  description: 'Intended solve path',
130
+ explanation: 'A logical solve path of the puzzle. Foresight will hint at the location of the next tile if this is available.',
118
131
  configurable: true,
119
132
  },
120
133
  ])