@logic-pad/core 0.4.6 → 0.6.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.
- package/assets/logic-core.global.d.ts +134 -25
- package/dist/data/grid.d.ts +44 -14
- package/dist/data/grid.js +43 -36
- package/dist/data/primitives.d.ts +19 -1
- package/dist/data/primitives.js +20 -0
- package/dist/data/rules/banPatternRule.js +1 -1
- package/dist/data/rules/customRule.js +1 -1
- package/dist/data/rules/lyingSymbolRule.d.ts +30 -0
- package/dist/data/rules/lyingSymbolRule.js +239 -0
- package/dist/data/rules/musicGridRule.js +1 -1
- package/dist/data/rules/mysteryRule.js +2 -2
- package/dist/data/rules/offByXRule.d.ts +1 -1
- package/dist/data/rules/offByXRule.js +7 -3
- package/dist/data/rules/regionAreaRule.js +3 -3
- package/dist/data/rules/rules.gen.d.ts +1 -0
- package/dist/data/rules/rules.gen.js +1 -0
- package/dist/data/serializer/serializer_v0.js +1 -1
- package/dist/data/solver/allSolvers.js +2 -2
- package/dist/data/solver/backtrack/backtrackSolver.d.ts +3 -4
- package/dist/data/solver/backtrack/backtrackSolver.js +4 -30
- package/dist/data/solver/backtrack/backtrackWorker.d.ts +1 -2
- package/dist/data/solver/backtrack/backtrackWorker.js +12 -8
- package/dist/data/solver/eventIteratingSolver.d.ts +6 -0
- package/dist/data/solver/eventIteratingSolver.js +33 -0
- package/dist/data/solver/solver.d.ts +6 -1
- package/dist/data/solver/solver.js +2 -1
- package/dist/data/solver/universal/universalSolver.d.ts +7 -0
- package/dist/data/solver/universal/universalSolver.js +30 -0
- package/dist/data/solver/universal/universalWorker.d.ts +1 -0
- package/dist/data/solver/universal/universalWorker.js +119 -0
- package/dist/data/symbols/customIconSymbol.js +2 -2
- package/dist/data/symbols/customTextSymbol.js +2 -2
- package/dist/data/validate.d.ts +1 -1
- package/dist/data/validate.js +3 -3
- package/dist/index.d.ts +4 -2
- package/dist/index.js +4 -2
- package/package.json +1 -1
- package/dist/data/solver/underclued/undercluedSolver.d.ts +0 -8
- package/dist/data/solver/underclued/undercluedSolver.js +0 -55
- package/dist/data/solver/underclued/undercluedWorker.d.ts +0 -2
- package/dist/data/solver/underclued/undercluedWorker.js +0 -135
|
@@ -31,9 +31,25 @@ declare global {
|
|
|
31
31
|
Underclued = 'underclued',
|
|
32
32
|
}
|
|
33
33
|
export declare enum State {
|
|
34
|
+
/**
|
|
35
|
+
* Describes the violation of a rule.
|
|
36
|
+
*/
|
|
34
37
|
Error = 'error',
|
|
38
|
+
/**
|
|
39
|
+
* Describes that a rule is satisfied and complete in the current grid.
|
|
40
|
+
*/
|
|
35
41
|
Satisfied = 'satisfied',
|
|
42
|
+
/**
|
|
43
|
+
* Describes that a rule is not violated, but is not yet complete in the current grid.
|
|
44
|
+
*/
|
|
36
45
|
Incomplete = 'incomplete',
|
|
46
|
+
/**
|
|
47
|
+
* Describes that a rule is violated but ignored due to the effect of another rule.
|
|
48
|
+
*/
|
|
49
|
+
Ignored = 'ignored',
|
|
50
|
+
}
|
|
51
|
+
export declare namespace State {
|
|
52
|
+
function isSatisfied(state: State): boolean;
|
|
37
53
|
}
|
|
38
54
|
export type RuleState =
|
|
39
55
|
| {
|
|
@@ -45,6 +61,9 @@ declare global {
|
|
|
45
61
|
}
|
|
46
62
|
| {
|
|
47
63
|
readonly state: State.Incomplete;
|
|
64
|
+
}
|
|
65
|
+
| {
|
|
66
|
+
readonly state: State.Ignored;
|
|
48
67
|
};
|
|
49
68
|
export interface GridState {
|
|
50
69
|
final: State;
|
|
@@ -627,6 +646,7 @@ declare global {
|
|
|
627
646
|
readonly underclued: CachedAccess<UndercluedRule | undefined>;
|
|
628
647
|
/**
|
|
629
648
|
* Create a new grid with tiles, connections, symbols and rules.
|
|
649
|
+
*
|
|
630
650
|
* @param width The width of the grid.
|
|
631
651
|
* @param height The height of the grid.
|
|
632
652
|
* @param tiles The tiles of the grid.
|
|
@@ -644,6 +664,38 @@ declare global {
|
|
|
644
664
|
symbols?: ReadonlyMap<string, readonly Symbol$1[]>,
|
|
645
665
|
rules?: readonly Rule[]
|
|
646
666
|
);
|
|
667
|
+
/**
|
|
668
|
+
* Create a new GridData object from a string array.
|
|
669
|
+
*
|
|
670
|
+
* - Use `b` for dark cells, `w` for light cells, and `n` for gray cells.
|
|
671
|
+
* - Capitalize the letter to make the tile fixed.
|
|
672
|
+
* - Use `.` to represent empty space.
|
|
673
|
+
*
|
|
674
|
+
* @param array - The string array to create the grid from.
|
|
675
|
+
* @returns The created grid.
|
|
676
|
+
*/
|
|
677
|
+
static create(array: string[]): GridData;
|
|
678
|
+
/**
|
|
679
|
+
* Create a new grid with tiles, connections, symbols and rules. Sanitize the provided list of symbols and rules,
|
|
680
|
+
* and trigger grid change events.
|
|
681
|
+
*
|
|
682
|
+
* @param width The width of the grid.
|
|
683
|
+
* @param height The height of the grid.
|
|
684
|
+
* @param tiles The tiles of the grid.
|
|
685
|
+
* @param connections The connections of the grid, which determines which tiles are merged.
|
|
686
|
+
* @param zones The zones of the grid.
|
|
687
|
+
* @param symbols The symbols in the grid.
|
|
688
|
+
* @param rules The rules of the grid.
|
|
689
|
+
*/
|
|
690
|
+
static create(
|
|
691
|
+
width: number,
|
|
692
|
+
height: number,
|
|
693
|
+
tiles?: readonly (readonly TileData[])[],
|
|
694
|
+
connections?: GridConnections,
|
|
695
|
+
zones?: GridZones,
|
|
696
|
+
symbols?: ReadonlyMap<string, readonly Symbol$1[]>,
|
|
697
|
+
rules?: readonly Rule[]
|
|
698
|
+
): GridData;
|
|
647
699
|
/**
|
|
648
700
|
* Copy the current grid while modifying the provided properties.
|
|
649
701
|
* @param param0 The properties to modify.
|
|
@@ -666,6 +718,30 @@ declare global {
|
|
|
666
718
|
symbols?: ReadonlyMap<string, readonly Symbol$1[]>;
|
|
667
719
|
rules?: readonly Rule[];
|
|
668
720
|
}): GridData;
|
|
721
|
+
/**
|
|
722
|
+
* Copy the current grid while modifying the provided properties.
|
|
723
|
+
* Skip sanitization and event triggering for performance.
|
|
724
|
+
*
|
|
725
|
+
* @param param0 The properties to modify.
|
|
726
|
+
* @returns The new grid with the modified properties.
|
|
727
|
+
*/
|
|
728
|
+
fastCopyWith({
|
|
729
|
+
width,
|
|
730
|
+
height,
|
|
731
|
+
tiles,
|
|
732
|
+
connections,
|
|
733
|
+
zones,
|
|
734
|
+
symbols,
|
|
735
|
+
rules,
|
|
736
|
+
}: {
|
|
737
|
+
width?: number;
|
|
738
|
+
height?: number;
|
|
739
|
+
tiles?: readonly (readonly TileData[])[];
|
|
740
|
+
connections?: GridConnections;
|
|
741
|
+
zones?: GridZones;
|
|
742
|
+
symbols?: ReadonlyMap<string, readonly Symbol$1[]>;
|
|
743
|
+
rules?: readonly Rule[];
|
|
744
|
+
}): GridData;
|
|
669
745
|
isPositionValid(x: number, y: number): boolean;
|
|
670
746
|
/**
|
|
671
747
|
* Safely get the tile at the given position.
|
|
@@ -676,19 +752,19 @@ declare global {
|
|
|
676
752
|
getTile(x: number, y: number): TileData;
|
|
677
753
|
/**
|
|
678
754
|
* Safely set the tile at the given position.
|
|
679
|
-
* If the position is invalid, the
|
|
755
|
+
* If the position is invalid, the tile array is returned unchanged.
|
|
680
756
|
* If the tile is merged with other tiles, the colors of all connected tiles are changed.
|
|
681
757
|
*
|
|
682
758
|
* @param x The x-coordinate of the tile.
|
|
683
759
|
* @param y The y-coordinate of the tile.
|
|
684
760
|
* @param tile The new tile to set.
|
|
685
|
-
* @returns The new
|
|
761
|
+
* @returns The new tile array with updated tiles.
|
|
686
762
|
*/
|
|
687
763
|
setTile(
|
|
688
764
|
x: number,
|
|
689
765
|
y: number,
|
|
690
766
|
tile: TileData | ((tile: TileData) => TileData)
|
|
691
|
-
):
|
|
767
|
+
): readonly (readonly TileData[])[];
|
|
692
768
|
/**
|
|
693
769
|
* Replace or modify all tiles in the grid.
|
|
694
770
|
*
|
|
@@ -841,17 +917,6 @@ declare global {
|
|
|
841
917
|
* @returns The created tile array.
|
|
842
918
|
*/
|
|
843
919
|
static createTiles(array: string[]): TileData[][];
|
|
844
|
-
/**
|
|
845
|
-
* Create a new GridData object from a string array.
|
|
846
|
-
*
|
|
847
|
-
* - Use `b` for dark cells, `w` for light cells, and `n` for gray cells.
|
|
848
|
-
* - Capitalize the letter to make the tile fixed.
|
|
849
|
-
* - Use `.` to represent empty space.
|
|
850
|
-
*
|
|
851
|
-
* @param array - The string array to create the grid from.
|
|
852
|
-
* @returns The created grid.
|
|
853
|
-
*/
|
|
854
|
-
static create(array: string[]): GridData;
|
|
855
920
|
/**
|
|
856
921
|
* Find a tile in the grid that satisfies the predicate.
|
|
857
922
|
*
|
|
@@ -1511,6 +1576,35 @@ declare global {
|
|
|
1511
1576
|
}): this;
|
|
1512
1577
|
}
|
|
1513
1578
|
export declare const allRules: Map<string, Rule>;
|
|
1579
|
+
export declare class LyingSymbolRule
|
|
1580
|
+
extends Rule
|
|
1581
|
+
implements FinalValidationHandler
|
|
1582
|
+
{
|
|
1583
|
+
readonly count: number;
|
|
1584
|
+
private static readonly EXAMPLE_GRID;
|
|
1585
|
+
private static readonly CONFIGS;
|
|
1586
|
+
private static readonly SEARCH_VARIANTS;
|
|
1587
|
+
/**
|
|
1588
|
+
* **<count> symbols are lying and are incorrect**
|
|
1589
|
+
*
|
|
1590
|
+
* @param count Number of lying symbols
|
|
1591
|
+
*/
|
|
1592
|
+
constructor(count: number);
|
|
1593
|
+
get id(): string;
|
|
1594
|
+
get explanation(): string;
|
|
1595
|
+
get configs(): readonly AnyConfig[] | null;
|
|
1596
|
+
createExampleGrid(): GridData;
|
|
1597
|
+
get searchVariants(): SearchVariant[];
|
|
1598
|
+
validateGrid(_: GridData): RuleState;
|
|
1599
|
+
get isSingleton(): boolean;
|
|
1600
|
+
onFinalValidation(
|
|
1601
|
+
grid: GridData,
|
|
1602
|
+
solution: GridData | null,
|
|
1603
|
+
state: GridState
|
|
1604
|
+
): GridState;
|
|
1605
|
+
copyWith({ count }: { count?: number }): this;
|
|
1606
|
+
withCount(count: number): this;
|
|
1607
|
+
}
|
|
1514
1608
|
export declare class MysteryRule
|
|
1515
1609
|
extends Rule
|
|
1516
1610
|
implements FinalValidationHandler, GridChangeHandler, GridResizeHandler
|
|
@@ -1574,7 +1668,7 @@ declare global {
|
|
|
1574
1668
|
get configs(): readonly AnyConfig[] | null;
|
|
1575
1669
|
createExampleGrid(): GridData;
|
|
1576
1670
|
get searchVariants(): SearchVariant[];
|
|
1577
|
-
validateGrid(
|
|
1671
|
+
validateGrid(grid: GridData): RuleState;
|
|
1578
1672
|
onSymbolValidation(
|
|
1579
1673
|
grid: GridData,
|
|
1580
1674
|
symbol: Symbol$1,
|
|
@@ -1863,6 +1957,9 @@ declare global {
|
|
|
1863
1957
|
stringifyPuzzle(puzzle: Puzzle): string;
|
|
1864
1958
|
parsePuzzle(input: string): Puzzle;
|
|
1865
1959
|
}
|
|
1960
|
+
export interface CancelRef {
|
|
1961
|
+
cancel?: () => void;
|
|
1962
|
+
}
|
|
1866
1963
|
/**
|
|
1867
1964
|
* Base class that all solvers must extend.
|
|
1868
1965
|
*/
|
|
@@ -1892,8 +1989,13 @@ declare global {
|
|
|
1892
1989
|
*
|
|
1893
1990
|
* @param grid The grid to solve. The provided grid is guaranteed to be supported by the solver. Some tiles in the
|
|
1894
1991
|
* grid may already be filled by the user. It is up to the solver to decide whether to respect these tiles or not.
|
|
1992
|
+
* @param cancelRef A reference to a function that can be called to cancel the solver. If cancellation is supported,
|
|
1993
|
+
* the solver can assign a function to `cancelRef.cancel` that will stop the solver when called.
|
|
1895
1994
|
*/
|
|
1896
|
-
abstract solve(
|
|
1995
|
+
abstract solve(
|
|
1996
|
+
grid: GridData,
|
|
1997
|
+
cancelRef: CancelRef
|
|
1998
|
+
): AsyncGenerator<GridData | null>;
|
|
1897
1999
|
/**
|
|
1898
2000
|
* Check if the solver supports the current browser environment. This method is called once when the user first clicks
|
|
1899
2001
|
* the "Solve" button, and the result is cached for the duration of the editor session.
|
|
@@ -1924,12 +2026,19 @@ declare global {
|
|
|
1924
2026
|
isGridSupported(grid: GridData): boolean;
|
|
1925
2027
|
}
|
|
1926
2028
|
export declare const allSolvers: Map<string, Solver>;
|
|
1927
|
-
export declare class
|
|
2029
|
+
export declare abstract class EventIteratingSolver extends Solver {
|
|
2030
|
+
protected abstract createWorker(): Worker;
|
|
2031
|
+
solve(
|
|
2032
|
+
grid: GridData,
|
|
2033
|
+
cancelRef: CancelRef
|
|
2034
|
+
): AsyncGenerator<GridData | null>;
|
|
2035
|
+
}
|
|
2036
|
+
export declare class BacktrackSolver extends EventIteratingSolver {
|
|
1928
2037
|
private static readonly supportedInstrs;
|
|
1929
2038
|
readonly id = 'backtrack';
|
|
1930
2039
|
readonly description =
|
|
1931
2040
|
'Solves puzzles using backtracking with optimizations (blazingly fast). Support most rules and symbols (including underclued).';
|
|
1932
|
-
|
|
2041
|
+
protected createWorker(): Worker;
|
|
1933
2042
|
isInstructionSupported(instructionId: string): boolean;
|
|
1934
2043
|
}
|
|
1935
2044
|
export declare enum BTTile {
|
|
@@ -2400,11 +2509,11 @@ declare global {
|
|
|
2400
2509
|
constructor(instr: ViewpointSymbol);
|
|
2401
2510
|
checkGlobal(grid: BTGridData): CheckResult | false;
|
|
2402
2511
|
}
|
|
2403
|
-
export declare class
|
|
2404
|
-
readonly id = '
|
|
2512
|
+
export declare class UniversalSolver extends EventIteratingSolver {
|
|
2513
|
+
readonly id = 'universal';
|
|
2405
2514
|
readonly description =
|
|
2406
|
-
'
|
|
2407
|
-
|
|
2515
|
+
'A backtracking solver that supports all rules and symbols (including underclued) but is less optimized.';
|
|
2516
|
+
protected createWorker(): Worker;
|
|
2408
2517
|
isInstructionSupported(instructionId: string): boolean;
|
|
2409
2518
|
}
|
|
2410
2519
|
export declare class Z3SolverContext<
|
|
@@ -2648,10 +2757,10 @@ declare global {
|
|
|
2648
2757
|
}
|
|
2649
2758
|
export declare const allSymbols: Map<string, Symbol$1>;
|
|
2650
2759
|
export declare function aggregateState(
|
|
2651
|
-
rules: RuleState[],
|
|
2760
|
+
rules: readonly RuleState[],
|
|
2652
2761
|
grid: GridData,
|
|
2653
|
-
symbols:
|
|
2654
|
-
): State;
|
|
2762
|
+
symbols: ReadonlyMap<string, State[]>
|
|
2763
|
+
): State.Error | State.Satisfied | State.Incomplete;
|
|
2655
2764
|
export declare function applyFinalOverrides(
|
|
2656
2765
|
grid: GridData,
|
|
2657
2766
|
solution: GridData | null,
|
package/dist/data/grid.d.ts
CHANGED
|
@@ -22,6 +22,7 @@ export default class GridData {
|
|
|
22
22
|
readonly underclued: CachedAccess<UndercluedRule | undefined>;
|
|
23
23
|
/**
|
|
24
24
|
* Create a new grid with tiles, connections, symbols and rules.
|
|
25
|
+
*
|
|
25
26
|
* @param width The width of the grid.
|
|
26
27
|
* @param height The height of the grid.
|
|
27
28
|
* @param tiles The tiles of the grid.
|
|
@@ -31,6 +32,30 @@ export default class GridData {
|
|
|
31
32
|
* @param rules The rules of the grid.
|
|
32
33
|
*/
|
|
33
34
|
constructor(width: number, height: number, tiles?: readonly (readonly TileData[])[], connections?: GridConnections, zones?: GridZones, symbols?: ReadonlyMap<string, readonly Symbol[]>, rules?: readonly Rule[]);
|
|
35
|
+
/**
|
|
36
|
+
* Create a new GridData object from a string array.
|
|
37
|
+
*
|
|
38
|
+
* - Use `b` for dark cells, `w` for light cells, and `n` for gray cells.
|
|
39
|
+
* - Capitalize the letter to make the tile fixed.
|
|
40
|
+
* - Use `.` to represent empty space.
|
|
41
|
+
*
|
|
42
|
+
* @param array - The string array to create the grid from.
|
|
43
|
+
* @returns The created grid.
|
|
44
|
+
*/
|
|
45
|
+
static create(array: string[]): GridData;
|
|
46
|
+
/**
|
|
47
|
+
* Create a new grid with tiles, connections, symbols and rules. Sanitize the provided list of symbols and rules,
|
|
48
|
+
* and trigger grid change events.
|
|
49
|
+
*
|
|
50
|
+
* @param width The width of the grid.
|
|
51
|
+
* @param height The height of the grid.
|
|
52
|
+
* @param tiles The tiles of the grid.
|
|
53
|
+
* @param connections The connections of the grid, which determines which tiles are merged.
|
|
54
|
+
* @param zones The zones of the grid.
|
|
55
|
+
* @param symbols The symbols in the grid.
|
|
56
|
+
* @param rules The rules of the grid.
|
|
57
|
+
*/
|
|
58
|
+
static create(width: number, height: number, tiles?: readonly (readonly TileData[])[], connections?: GridConnections, zones?: GridZones, symbols?: ReadonlyMap<string, readonly Symbol[]>, rules?: readonly Rule[]): GridData;
|
|
34
59
|
/**
|
|
35
60
|
* Copy the current grid while modifying the provided properties.
|
|
36
61
|
* @param param0 The properties to modify.
|
|
@@ -45,6 +70,22 @@ export default class GridData {
|
|
|
45
70
|
symbols?: ReadonlyMap<string, readonly Symbol[]>;
|
|
46
71
|
rules?: readonly Rule[];
|
|
47
72
|
}): GridData;
|
|
73
|
+
/**
|
|
74
|
+
* Copy the current grid while modifying the provided properties.
|
|
75
|
+
* Skip sanitization and event triggering for performance.
|
|
76
|
+
*
|
|
77
|
+
* @param param0 The properties to modify.
|
|
78
|
+
* @returns The new grid with the modified properties.
|
|
79
|
+
*/
|
|
80
|
+
fastCopyWith({ width, height, tiles, connections, zones, symbols, rules, }: {
|
|
81
|
+
width?: number;
|
|
82
|
+
height?: number;
|
|
83
|
+
tiles?: readonly (readonly TileData[])[];
|
|
84
|
+
connections?: GridConnections;
|
|
85
|
+
zones?: GridZones;
|
|
86
|
+
symbols?: ReadonlyMap<string, readonly Symbol[]>;
|
|
87
|
+
rules?: readonly Rule[];
|
|
88
|
+
}): GridData;
|
|
48
89
|
isPositionValid(x: number, y: number): boolean;
|
|
49
90
|
/**
|
|
50
91
|
* Safely get the tile at the given position.
|
|
@@ -55,15 +96,15 @@ export default class GridData {
|
|
|
55
96
|
getTile(x: number, y: number): TileData;
|
|
56
97
|
/**
|
|
57
98
|
* Safely set the tile at the given position.
|
|
58
|
-
* If the position is invalid, the
|
|
99
|
+
* If the position is invalid, the tile array is returned unchanged.
|
|
59
100
|
* If the tile is merged with other tiles, the colors of all connected tiles are changed.
|
|
60
101
|
*
|
|
61
102
|
* @param x The x-coordinate of the tile.
|
|
62
103
|
* @param y The y-coordinate of the tile.
|
|
63
104
|
* @param tile The new tile to set.
|
|
64
|
-
* @returns The new
|
|
105
|
+
* @returns The new tile array with updated tiles.
|
|
65
106
|
*/
|
|
66
|
-
setTile(x: number, y: number, tile: TileData | ((tile: TileData) => TileData)):
|
|
107
|
+
setTile(x: number, y: number, tile: TileData | ((tile: TileData) => TileData)): readonly (readonly TileData[])[];
|
|
67
108
|
/**
|
|
68
109
|
* Replace or modify all tiles in the grid.
|
|
69
110
|
*
|
|
@@ -199,17 +240,6 @@ export default class GridData {
|
|
|
199
240
|
* @returns The created tile array.
|
|
200
241
|
*/
|
|
201
242
|
static createTiles(array: string[]): TileData[][];
|
|
202
|
-
/**
|
|
203
|
-
* Create a new GridData object from a string array.
|
|
204
|
-
*
|
|
205
|
-
* - Use `b` for dark cells, `w` for light cells, and `n` for gray cells.
|
|
206
|
-
* - Capitalize the letter to make the tile fixed.
|
|
207
|
-
* - Use `.` to represent empty space.
|
|
208
|
-
*
|
|
209
|
-
* @param array - The string array to create the grid from.
|
|
210
|
-
* @returns The created grid.
|
|
211
|
-
*/
|
|
212
|
-
static create(array: string[]): GridData;
|
|
213
243
|
/**
|
|
214
244
|
* Find a tile in the grid that satisfies the predicate.
|
|
215
245
|
*
|
package/dist/data/grid.js
CHANGED
|
@@ -16,6 +16,7 @@ export default class GridData {
|
|
|
16
16
|
/* eslint-enable @typescript-eslint/no-unsafe-enum-comparison */
|
|
17
17
|
/**
|
|
18
18
|
* Create a new grid with tiles, connections, symbols and rules.
|
|
19
|
+
*
|
|
19
20
|
* @param width The width of the grid.
|
|
20
21
|
* @param height The height of the grid.
|
|
21
22
|
* @param tiles The tiles of the grid.
|
|
@@ -92,25 +93,35 @@ export default class GridData {
|
|
|
92
93
|
this.tiles = tiles ?? array(width, height, () => TileData.empty());
|
|
93
94
|
this.connections = connections ?? new GridConnections();
|
|
94
95
|
this.zones = zones ?? new GridZones();
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
96
|
+
this.symbols = symbols ?? new Map();
|
|
97
|
+
this.rules = rules ?? [];
|
|
98
|
+
}
|
|
99
|
+
static create(arrayOrWidth, height, tiles, connections, zones, symbols, rules) {
|
|
100
|
+
if (typeof arrayOrWidth === 'number') {
|
|
101
|
+
const newSymbols = symbols
|
|
102
|
+
? GridData.deduplicateSymbols(symbols)
|
|
103
|
+
: new Map();
|
|
104
|
+
// do not deduplicate all rules because it makes for bad editor experience
|
|
105
|
+
const newRules = rules ? GridData.deduplicateSingletonRules(rules) : [];
|
|
106
|
+
const newGrid = new GridData(arrayOrWidth, height, tiles, connections, zones, newSymbols, newRules);
|
|
107
|
+
newSymbols.forEach(list => {
|
|
108
|
+
list.forEach((sym, i) => {
|
|
109
|
+
if (handlesGridChange(sym)) {
|
|
110
|
+
list[i] = sym.onGridChange(newGrid);
|
|
111
|
+
}
|
|
112
|
+
});
|
|
113
|
+
});
|
|
114
|
+
newRules.forEach((rule, i) => {
|
|
115
|
+
if (handlesGridChange(rule)) {
|
|
116
|
+
newRules[i] = rule.onGridChange(newGrid);
|
|
106
117
|
}
|
|
107
118
|
});
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
}
|
|
119
|
+
return newGrid;
|
|
120
|
+
}
|
|
121
|
+
else {
|
|
122
|
+
const tiles = GridData.createTiles(arrayOrWidth);
|
|
123
|
+
return GridData.create(tiles[0]?.length ?? 0, tiles.length, tiles);
|
|
124
|
+
}
|
|
114
125
|
}
|
|
115
126
|
/**
|
|
116
127
|
* Copy the current grid while modifying the provided properties.
|
|
@@ -118,6 +129,16 @@ export default class GridData {
|
|
|
118
129
|
* @returns The new grid with the modified properties.
|
|
119
130
|
*/
|
|
120
131
|
copyWith({ width, height, tiles, connections, zones, symbols, rules, }) {
|
|
132
|
+
return GridData.create(width ?? this.width, height ?? this.height, tiles ?? this.tiles, connections ?? this.connections, zones ?? this.zones, symbols ?? this.symbols, rules ?? this.rules);
|
|
133
|
+
}
|
|
134
|
+
/**
|
|
135
|
+
* Copy the current grid while modifying the provided properties.
|
|
136
|
+
* Skip sanitization and event triggering for performance.
|
|
137
|
+
*
|
|
138
|
+
* @param param0 The properties to modify.
|
|
139
|
+
* @returns The new grid with the modified properties.
|
|
140
|
+
*/
|
|
141
|
+
fastCopyWith({ width, height, tiles, connections, zones, symbols, rules, }) {
|
|
121
142
|
return new GridData(width ?? this.width, height ?? this.height, tiles ?? this.tiles, connections ?? this.connections, zones ?? this.zones, symbols ?? this.symbols, rules ?? this.rules);
|
|
122
143
|
}
|
|
123
144
|
isPositionValid(x, y) {
|
|
@@ -136,17 +157,17 @@ export default class GridData {
|
|
|
136
157
|
}
|
|
137
158
|
/**
|
|
138
159
|
* Safely set the tile at the given position.
|
|
139
|
-
* If the position is invalid, the
|
|
160
|
+
* If the position is invalid, the tile array is returned unchanged.
|
|
140
161
|
* If the tile is merged with other tiles, the colors of all connected tiles are changed.
|
|
141
162
|
*
|
|
142
163
|
* @param x The x-coordinate of the tile.
|
|
143
164
|
* @param y The y-coordinate of the tile.
|
|
144
165
|
* @param tile The new tile to set.
|
|
145
|
-
* @returns The new
|
|
166
|
+
* @returns The new tile array with updated tiles.
|
|
146
167
|
*/
|
|
147
168
|
setTile(x, y, tile) {
|
|
148
169
|
if (x < 0 || x >= this.width || y < 0 || y >= this.height) {
|
|
149
|
-
return this;
|
|
170
|
+
return this.tiles;
|
|
150
171
|
}
|
|
151
172
|
const changing = this.connections.getConnectedTiles({ x, y });
|
|
152
173
|
const tiles = this.tiles.map(row => [...row]);
|
|
@@ -155,7 +176,7 @@ export default class GridData {
|
|
|
155
176
|
tiles[y][x] = tiles[y][x].withColor(newTile.color);
|
|
156
177
|
});
|
|
157
178
|
tiles[y][x] = newTile;
|
|
158
|
-
return
|
|
179
|
+
return tiles;
|
|
159
180
|
}
|
|
160
181
|
/**
|
|
161
182
|
* Replace or modify all tiles in the grid.
|
|
@@ -542,20 +563,6 @@ export default class GridData {
|
|
|
542
563
|
return TileData.create(row.charAt(x));
|
|
543
564
|
}));
|
|
544
565
|
}
|
|
545
|
-
/**
|
|
546
|
-
* Create a new GridData object from a string array.
|
|
547
|
-
*
|
|
548
|
-
* - Use `b` for dark cells, `w` for light cells, and `n` for gray cells.
|
|
549
|
-
* - Capitalize the letter to make the tile fixed.
|
|
550
|
-
* - Use `.` to represent empty space.
|
|
551
|
-
*
|
|
552
|
-
* @param array - The string array to create the grid from.
|
|
553
|
-
* @returns The created grid.
|
|
554
|
-
*/
|
|
555
|
-
static create(array) {
|
|
556
|
-
const tiles = GridData.createTiles(array);
|
|
557
|
-
return new GridData(tiles[0]?.length ?? 0, tiles.length, tiles);
|
|
558
|
-
}
|
|
559
566
|
/**
|
|
560
567
|
* Find a tile in the grid that satisfies the predicate.
|
|
561
568
|
*
|
|
@@ -795,7 +802,7 @@ export default class GridData {
|
|
|
795
802
|
if (newSymbolList.length > 0)
|
|
796
803
|
symbols.set(id, newSymbolList);
|
|
797
804
|
}
|
|
798
|
-
return
|
|
805
|
+
return GridData.create(width, height, newTiles, connections, zones, symbols, this.rules);
|
|
799
806
|
}
|
|
800
807
|
pasteTiles(origin, grid) {
|
|
801
808
|
if (!(grid instanceof GridData))
|
|
@@ -17,9 +17,25 @@ export declare enum MajorRule {
|
|
|
17
17
|
Underclued = "underclued"
|
|
18
18
|
}
|
|
19
19
|
export declare enum State {
|
|
20
|
+
/**
|
|
21
|
+
* Describes the violation of a rule.
|
|
22
|
+
*/
|
|
20
23
|
Error = "error",
|
|
24
|
+
/**
|
|
25
|
+
* Describes that a rule is satisfied and complete in the current grid.
|
|
26
|
+
*/
|
|
21
27
|
Satisfied = "satisfied",
|
|
22
|
-
|
|
28
|
+
/**
|
|
29
|
+
* Describes that a rule is not violated, but is not yet complete in the current grid.
|
|
30
|
+
*/
|
|
31
|
+
Incomplete = "incomplete",
|
|
32
|
+
/**
|
|
33
|
+
* Describes that a rule is violated but ignored due to the effect of another rule.
|
|
34
|
+
*/
|
|
35
|
+
Ignored = "ignored"
|
|
36
|
+
}
|
|
37
|
+
export declare namespace State {
|
|
38
|
+
function isSatisfied(state: State): boolean;
|
|
23
39
|
}
|
|
24
40
|
export type RuleState = {
|
|
25
41
|
readonly state: State.Error;
|
|
@@ -28,6 +44,8 @@ export type RuleState = {
|
|
|
28
44
|
readonly state: State.Satisfied;
|
|
29
45
|
} | {
|
|
30
46
|
readonly state: State.Incomplete;
|
|
47
|
+
} | {
|
|
48
|
+
readonly state: State.Ignored;
|
|
31
49
|
};
|
|
32
50
|
export interface GridState {
|
|
33
51
|
final: State;
|
package/dist/data/primitives.js
CHANGED
|
@@ -9,9 +9,29 @@ export var MajorRule;
|
|
|
9
9
|
})(MajorRule || (MajorRule = {}));
|
|
10
10
|
export var State;
|
|
11
11
|
(function (State) {
|
|
12
|
+
/**
|
|
13
|
+
* Describes the violation of a rule.
|
|
14
|
+
*/
|
|
12
15
|
State["Error"] = "error";
|
|
16
|
+
/**
|
|
17
|
+
* Describes that a rule is satisfied and complete in the current grid.
|
|
18
|
+
*/
|
|
13
19
|
State["Satisfied"] = "satisfied";
|
|
20
|
+
/**
|
|
21
|
+
* Describes that a rule is not violated, but is not yet complete in the current grid.
|
|
22
|
+
*/
|
|
14
23
|
State["Incomplete"] = "incomplete";
|
|
24
|
+
/**
|
|
25
|
+
* Describes that a rule is violated but ignored due to the effect of another rule.
|
|
26
|
+
*/
|
|
27
|
+
State["Ignored"] = "ignored";
|
|
28
|
+
})(State || (State = {}));
|
|
29
|
+
// eslint-disable-next-line @typescript-eslint/no-namespace
|
|
30
|
+
(function (State) {
|
|
31
|
+
function isSatisfied(state) {
|
|
32
|
+
return state === State.Satisfied || state === State.Ignored;
|
|
33
|
+
}
|
|
34
|
+
State.isSatisfied = isSatisfied;
|
|
15
35
|
})(State || (State = {}));
|
|
16
36
|
export var Color;
|
|
17
37
|
(function (Color) {
|
|
@@ -64,7 +64,7 @@ class BanPatternRule extends Rule {
|
|
|
64
64
|
return tile;
|
|
65
65
|
return tile.withExists(false);
|
|
66
66
|
});
|
|
67
|
-
return
|
|
67
|
+
return GridData.create(width, height, tiles);
|
|
68
68
|
}
|
|
69
69
|
get searchVariants() {
|
|
70
70
|
return BanPatternRule.SEARCH_VARIANTS;
|
|
@@ -57,7 +57,7 @@ Object.defineProperty(CustomRule, "EXAMPLE_GRID", {
|
|
|
57
57
|
enumerable: true,
|
|
58
58
|
configurable: true,
|
|
59
59
|
writable: true,
|
|
60
|
-
value: Object.freeze(
|
|
60
|
+
value: Object.freeze(GridData.create(5, 4))
|
|
61
61
|
});
|
|
62
62
|
Object.defineProperty(CustomRule, "configs", {
|
|
63
63
|
enumerable: true,
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { AnyConfig } from '../config.js';
|
|
2
|
+
import { FinalValidationHandler } from '../events/onFinalValidation.js';
|
|
3
|
+
import GridData from '../grid.js';
|
|
4
|
+
import { GridState, RuleState } from '../primitives.js';
|
|
5
|
+
import Rule, { SearchVariant } from './rule.js';
|
|
6
|
+
export default class LyingSymbolRule extends Rule implements FinalValidationHandler {
|
|
7
|
+
readonly count: number;
|
|
8
|
+
private static readonly EXAMPLE_GRID;
|
|
9
|
+
private static readonly CONFIGS;
|
|
10
|
+
private static readonly SEARCH_VARIANTS;
|
|
11
|
+
/**
|
|
12
|
+
* **<count> symbols are lying and are incorrect**
|
|
13
|
+
*
|
|
14
|
+
* @param count Number of lying symbols
|
|
15
|
+
*/
|
|
16
|
+
constructor(count: number);
|
|
17
|
+
get id(): string;
|
|
18
|
+
get explanation(): string;
|
|
19
|
+
get configs(): readonly AnyConfig[] | null;
|
|
20
|
+
createExampleGrid(): GridData;
|
|
21
|
+
get searchVariants(): SearchVariant[];
|
|
22
|
+
validateGrid(_: GridData): RuleState;
|
|
23
|
+
get isSingleton(): boolean;
|
|
24
|
+
onFinalValidation(grid: GridData, solution: GridData | null, state: GridState): GridState;
|
|
25
|
+
copyWith({ count }: {
|
|
26
|
+
count?: number;
|
|
27
|
+
}): this;
|
|
28
|
+
withCount(count: number): this;
|
|
29
|
+
}
|
|
30
|
+
export declare const instance: LyingSymbolRule;
|