@logic-pad/core 0.5.0 → 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 +83 -22
- package/dist/data/grid.d.ts +44 -14
- package/dist/data/grid.js +43 -36
- package/dist/data/rules/banPatternRule.js +1 -1
- package/dist/data/rules/customRule.js +1 -1
- package/dist/data/rules/lyingSymbolRule.d.ts +1 -1
- package/dist/data/rules/lyingSymbolRule.js +38 -13
- package/dist/data/rules/musicGridRule.js +1 -1
- package/dist/data/rules/mysteryRule.js +1 -1
- package/dist/data/rules/regionAreaRule.js +3 -3
- 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/index.d.ts +3 -2
- package/dist/index.js +3 -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
|
@@ -646,6 +646,7 @@ declare global {
|
|
|
646
646
|
readonly underclued: CachedAccess<UndercluedRule | undefined>;
|
|
647
647
|
/**
|
|
648
648
|
* Create a new grid with tiles, connections, symbols and rules.
|
|
649
|
+
*
|
|
649
650
|
* @param width The width of the grid.
|
|
650
651
|
* @param height The height of the grid.
|
|
651
652
|
* @param tiles The tiles of the grid.
|
|
@@ -663,6 +664,38 @@ declare global {
|
|
|
663
664
|
symbols?: ReadonlyMap<string, readonly Symbol$1[]>,
|
|
664
665
|
rules?: readonly Rule[]
|
|
665
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;
|
|
666
699
|
/**
|
|
667
700
|
* Copy the current grid while modifying the provided properties.
|
|
668
701
|
* @param param0 The properties to modify.
|
|
@@ -685,6 +718,30 @@ declare global {
|
|
|
685
718
|
symbols?: ReadonlyMap<string, readonly Symbol$1[]>;
|
|
686
719
|
rules?: readonly Rule[];
|
|
687
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;
|
|
688
745
|
isPositionValid(x: number, y: number): boolean;
|
|
689
746
|
/**
|
|
690
747
|
* Safely get the tile at the given position.
|
|
@@ -695,19 +752,19 @@ declare global {
|
|
|
695
752
|
getTile(x: number, y: number): TileData;
|
|
696
753
|
/**
|
|
697
754
|
* Safely set the tile at the given position.
|
|
698
|
-
* If the position is invalid, the
|
|
755
|
+
* If the position is invalid, the tile array is returned unchanged.
|
|
699
756
|
* If the tile is merged with other tiles, the colors of all connected tiles are changed.
|
|
700
757
|
*
|
|
701
758
|
* @param x The x-coordinate of the tile.
|
|
702
759
|
* @param y The y-coordinate of the tile.
|
|
703
760
|
* @param tile The new tile to set.
|
|
704
|
-
* @returns The new
|
|
761
|
+
* @returns The new tile array with updated tiles.
|
|
705
762
|
*/
|
|
706
763
|
setTile(
|
|
707
764
|
x: number,
|
|
708
765
|
y: number,
|
|
709
766
|
tile: TileData | ((tile: TileData) => TileData)
|
|
710
|
-
):
|
|
767
|
+
): readonly (readonly TileData[])[];
|
|
711
768
|
/**
|
|
712
769
|
* Replace or modify all tiles in the grid.
|
|
713
770
|
*
|
|
@@ -860,17 +917,6 @@ declare global {
|
|
|
860
917
|
* @returns The created tile array.
|
|
861
918
|
*/
|
|
862
919
|
static createTiles(array: string[]): TileData[][];
|
|
863
|
-
/**
|
|
864
|
-
* Create a new GridData object from a string array.
|
|
865
|
-
*
|
|
866
|
-
* - Use `b` for dark cells, `w` for light cells, and `n` for gray cells.
|
|
867
|
-
* - Capitalize the letter to make the tile fixed.
|
|
868
|
-
* - Use `.` to represent empty space.
|
|
869
|
-
*
|
|
870
|
-
* @param array - The string array to create the grid from.
|
|
871
|
-
* @returns The created grid.
|
|
872
|
-
*/
|
|
873
|
-
static create(array: string[]): GridData;
|
|
874
920
|
/**
|
|
875
921
|
* Find a tile in the grid that satisfies the predicate.
|
|
876
922
|
*
|
|
@@ -1539,7 +1585,7 @@ declare global {
|
|
|
1539
1585
|
private static readonly CONFIGS;
|
|
1540
1586
|
private static readonly SEARCH_VARIANTS;
|
|
1541
1587
|
/**
|
|
1542
|
-
* **<count> symbols are lying and
|
|
1588
|
+
* **<count> symbols are lying and are incorrect**
|
|
1543
1589
|
*
|
|
1544
1590
|
* @param count Number of lying symbols
|
|
1545
1591
|
*/
|
|
@@ -1911,6 +1957,9 @@ declare global {
|
|
|
1911
1957
|
stringifyPuzzle(puzzle: Puzzle): string;
|
|
1912
1958
|
parsePuzzle(input: string): Puzzle;
|
|
1913
1959
|
}
|
|
1960
|
+
export interface CancelRef {
|
|
1961
|
+
cancel?: () => void;
|
|
1962
|
+
}
|
|
1914
1963
|
/**
|
|
1915
1964
|
* Base class that all solvers must extend.
|
|
1916
1965
|
*/
|
|
@@ -1940,8 +1989,13 @@ declare global {
|
|
|
1940
1989
|
*
|
|
1941
1990
|
* @param grid The grid to solve. The provided grid is guaranteed to be supported by the solver. Some tiles in the
|
|
1942
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.
|
|
1943
1994
|
*/
|
|
1944
|
-
abstract solve(
|
|
1995
|
+
abstract solve(
|
|
1996
|
+
grid: GridData,
|
|
1997
|
+
cancelRef: CancelRef
|
|
1998
|
+
): AsyncGenerator<GridData | null>;
|
|
1945
1999
|
/**
|
|
1946
2000
|
* Check if the solver supports the current browser environment. This method is called once when the user first clicks
|
|
1947
2001
|
* the "Solve" button, and the result is cached for the duration of the editor session.
|
|
@@ -1972,12 +2026,19 @@ declare global {
|
|
|
1972
2026
|
isGridSupported(grid: GridData): boolean;
|
|
1973
2027
|
}
|
|
1974
2028
|
export declare const allSolvers: Map<string, Solver>;
|
|
1975
|
-
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 {
|
|
1976
2037
|
private static readonly supportedInstrs;
|
|
1977
2038
|
readonly id = 'backtrack';
|
|
1978
2039
|
readonly description =
|
|
1979
2040
|
'Solves puzzles using backtracking with optimizations (blazingly fast). Support most rules and symbols (including underclued).';
|
|
1980
|
-
|
|
2041
|
+
protected createWorker(): Worker;
|
|
1981
2042
|
isInstructionSupported(instructionId: string): boolean;
|
|
1982
2043
|
}
|
|
1983
2044
|
export declare enum BTTile {
|
|
@@ -2448,11 +2509,11 @@ declare global {
|
|
|
2448
2509
|
constructor(instr: ViewpointSymbol);
|
|
2449
2510
|
checkGlobal(grid: BTGridData): CheckResult | false;
|
|
2450
2511
|
}
|
|
2451
|
-
export declare class
|
|
2452
|
-
readonly id = '
|
|
2512
|
+
export declare class UniversalSolver extends EventIteratingSolver {
|
|
2513
|
+
readonly id = 'universal';
|
|
2453
2514
|
readonly description =
|
|
2454
|
-
'
|
|
2455
|
-
|
|
2515
|
+
'A backtracking solver that supports all rules and symbols (including underclued) but is less optimized.';
|
|
2516
|
+
protected createWorker(): Worker;
|
|
2456
2517
|
isInstructionSupported(instructionId: string): boolean;
|
|
2457
2518
|
}
|
|
2458
2519
|
export declare class Z3SolverContext<
|
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))
|
|
@@ -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,
|
|
@@ -9,7 +9,7 @@ export default class LyingSymbolRule extends Rule implements FinalValidationHand
|
|
|
9
9
|
private static readonly CONFIGS;
|
|
10
10
|
private static readonly SEARCH_VARIANTS;
|
|
11
11
|
/**
|
|
12
|
-
* **<count> symbols are lying and
|
|
12
|
+
* **<count> symbols are lying and are incorrect**
|
|
13
13
|
*
|
|
14
14
|
* @param count Number of lying symbols
|
|
15
15
|
*/
|
|
@@ -1,12 +1,15 @@
|
|
|
1
1
|
import { ConfigType } from '../config.js';
|
|
2
2
|
import GridData from '../grid.js';
|
|
3
|
-
import { Color, State } from '../primitives.js';
|
|
3
|
+
import { Color, Orientation, State, } from '../primitives.js';
|
|
4
4
|
import Rule from './rule.js';
|
|
5
|
-
import CustomIconSymbol from '../symbols/customIconSymbol.js';
|
|
6
5
|
import validateGrid from '../validate.js';
|
|
7
6
|
import Symbol from '../symbols/symbol.js';
|
|
7
|
+
import LetterSymbol from '../symbols/letterSymbol.js';
|
|
8
|
+
import GalaxySymbol from '../symbols/galaxySymbol.js';
|
|
9
|
+
import LotusSymbol from '../symbols/lotusSymbol.js';
|
|
10
|
+
import AreaNumberSymbol from '../symbols/areaNumberSymbol.js';
|
|
8
11
|
class IgnoredSymbol extends Symbol {
|
|
9
|
-
constructor(symbol) {
|
|
12
|
+
constructor(symbol, state) {
|
|
10
13
|
super(symbol.x, symbol.y);
|
|
11
14
|
Object.defineProperty(this, "symbol", {
|
|
12
15
|
enumerable: true,
|
|
@@ -14,16 +17,23 @@ class IgnoredSymbol extends Symbol {
|
|
|
14
17
|
writable: true,
|
|
15
18
|
value: symbol
|
|
16
19
|
});
|
|
20
|
+
Object.defineProperty(this, "state", {
|
|
21
|
+
enumerable: true,
|
|
22
|
+
configurable: true,
|
|
23
|
+
writable: true,
|
|
24
|
+
value: state
|
|
25
|
+
});
|
|
17
26
|
this.symbol = symbol;
|
|
27
|
+
this.state = state;
|
|
18
28
|
}
|
|
19
29
|
get id() {
|
|
20
|
-
return this.symbol.id
|
|
30
|
+
return `ignored_${this.symbol.id}`;
|
|
21
31
|
}
|
|
22
32
|
get explanation() {
|
|
23
33
|
return this.symbol.explanation;
|
|
24
34
|
}
|
|
25
35
|
get configs() {
|
|
26
|
-
return
|
|
36
|
+
return [];
|
|
27
37
|
}
|
|
28
38
|
createExampleGrid() {
|
|
29
39
|
return this.symbol.createExampleGrid();
|
|
@@ -38,14 +48,17 @@ class IgnoredSymbol extends Symbol {
|
|
|
38
48
|
return this.symbol.sortOrder;
|
|
39
49
|
}
|
|
40
50
|
validateSymbol(_grid, _solution) {
|
|
41
|
-
return
|
|
51
|
+
return this.state;
|
|
42
52
|
}
|
|
43
|
-
copyWith({ symbol }) {
|
|
44
|
-
return new IgnoredSymbol(symbol ?? this.symbol);
|
|
53
|
+
copyWith({ symbol, state }) {
|
|
54
|
+
return new IgnoredSymbol(symbol ?? this.symbol, state ?? this.state);
|
|
45
55
|
}
|
|
46
56
|
withSymbol(symbol) {
|
|
47
57
|
return this.copyWith({ symbol });
|
|
48
58
|
}
|
|
59
|
+
equals(other) {
|
|
60
|
+
return other === this;
|
|
61
|
+
}
|
|
49
62
|
}
|
|
50
63
|
class IgnoredRule extends Rule {
|
|
51
64
|
constructor(rule, state) {
|
|
@@ -69,11 +82,14 @@ class IgnoredRule extends Rule {
|
|
|
69
82
|
return [];
|
|
70
83
|
}
|
|
71
84
|
get id() {
|
|
72
|
-
return this.rule.id
|
|
85
|
+
return `ignored_${this.rule.id}`;
|
|
73
86
|
}
|
|
74
87
|
get explanation() {
|
|
75
88
|
return this.rule.explanation;
|
|
76
89
|
}
|
|
90
|
+
get configs() {
|
|
91
|
+
return [];
|
|
92
|
+
}
|
|
77
93
|
createExampleGrid() {
|
|
78
94
|
return this.rule.createExampleGrid();
|
|
79
95
|
}
|
|
@@ -95,10 +111,13 @@ class IgnoredRule extends Rule {
|
|
|
95
111
|
copyWith({ rule, state }) {
|
|
96
112
|
return new IgnoredRule(rule ?? this.rule, state ?? this.state);
|
|
97
113
|
}
|
|
114
|
+
equals(other) {
|
|
115
|
+
return other === this;
|
|
116
|
+
}
|
|
98
117
|
}
|
|
99
118
|
class LyingSymbolRule extends Rule {
|
|
100
119
|
/**
|
|
101
|
-
* **<count> symbols are lying and
|
|
120
|
+
* **<count> symbols are lying and are incorrect**
|
|
102
121
|
*
|
|
103
122
|
* @param count Number of lying symbols
|
|
104
123
|
*/
|
|
@@ -116,7 +135,7 @@ class LyingSymbolRule extends Rule {
|
|
|
116
135
|
return `lying_symbols`;
|
|
117
136
|
}
|
|
118
137
|
get explanation() {
|
|
119
|
-
return `${this.count} symbol${this.count <= 1 ? ' is' : 's are'} *lying* and
|
|
138
|
+
return `${this.count} symbol${this.count <= 1 ? ' is' : 's are'} *lying* and ${this.count <= 1 ? 'is' : 'are'} incorrect`;
|
|
120
139
|
}
|
|
121
140
|
get configs() {
|
|
122
141
|
return LyingSymbolRule.CONFIGS;
|
|
@@ -156,7 +175,7 @@ class LyingSymbolRule extends Rule {
|
|
|
156
175
|
newSymbols.set(key, []);
|
|
157
176
|
}
|
|
158
177
|
if (ignoredSymbols.some(([k, i]) => k === key && i === idx)) {
|
|
159
|
-
newSymbols.get(key).push(new IgnoredSymbol(symbol));
|
|
178
|
+
newSymbols.get(key).push(new IgnoredSymbol(symbol, State.Ignored));
|
|
160
179
|
}
|
|
161
180
|
else {
|
|
162
181
|
newSymbols.get(key).push(symbol);
|
|
@@ -183,7 +202,13 @@ Object.defineProperty(LyingSymbolRule, "EXAMPLE_GRID", {
|
|
|
183
202
|
enumerable: true,
|
|
184
203
|
configurable: true,
|
|
185
204
|
writable: true,
|
|
186
|
-
value: Object.freeze(GridData.create(['
|
|
205
|
+
value: Object.freeze(GridData.create(['bbbbw', 'wwbbb', 'bbbbw', 'wbbww']).withSymbols([
|
|
206
|
+
new LetterSymbol(4, 0, 'A'),
|
|
207
|
+
new GalaxySymbol(1, 1),
|
|
208
|
+
new LotusSymbol(2, 2, Orientation.Up),
|
|
209
|
+
new LetterSymbol(0, 3, 'A'),
|
|
210
|
+
new AreaNumberSymbol(4, 3, 1),
|
|
211
|
+
]))
|
|
187
212
|
});
|
|
188
213
|
Object.defineProperty(LyingSymbolRule, "CONFIGS", {
|
|
189
214
|
enumerable: true,
|
|
@@ -200,7 +200,7 @@ Object.defineProperty(MusicGridRule, "CONFIGS", {
|
|
|
200
200
|
{
|
|
201
201
|
type: ConfigType.NullableGrid,
|
|
202
202
|
default: null,
|
|
203
|
-
nonNullDefault:
|
|
203
|
+
nonNullDefault: GridData.create(5, 4).addRule(new MusicGridRule([new ControlLine(0, 120, false, false, DEFAULT_SCALLE)], null)),
|
|
204
204
|
field: 'track',
|
|
205
205
|
description: 'Track',
|
|
206
206
|
configurable: true,
|
|
@@ -121,7 +121,7 @@ class MysteryRule extends Rule {
|
|
|
121
121
|
return tile.withColor(solutionTile.color);
|
|
122
122
|
})
|
|
123
123
|
: solution.tiles;
|
|
124
|
-
return
|
|
124
|
+
return GridData.create(baseGrid?.width ?? solution.width, baseGrid?.height ?? solution.height, tiles);
|
|
125
125
|
}
|
|
126
126
|
}
|
|
127
127
|
Object.defineProperty(MysteryRule, "EXAMPLE_GRID", {
|
|
@@ -62,7 +62,7 @@ class RegionAreaRule extends Rule {
|
|
|
62
62
|
? Color.Dark
|
|
63
63
|
: Color.Light);
|
|
64
64
|
});
|
|
65
|
-
return
|
|
65
|
+
return GridData.create(5, 4, tiles);
|
|
66
66
|
}
|
|
67
67
|
}
|
|
68
68
|
get searchVariants() {
|
|
@@ -157,13 +157,13 @@ Object.defineProperty(RegionAreaRule, "EXAMPLE_GRID_LIGHT", {
|
|
|
157
157
|
enumerable: true,
|
|
158
158
|
configurable: true,
|
|
159
159
|
writable: true,
|
|
160
|
-
value: Object.freeze(RegionAreaRule.EXAMPLE_GRID_DARK.map(grid =>
|
|
160
|
+
value: Object.freeze(RegionAreaRule.EXAMPLE_GRID_DARK.map(grid => GridData.create(grid.width, grid.height, grid.tiles.map(row => row.map(tile => tile.withColor(tile.color === Color.Dark ? Color.Light : Color.Dark))))))
|
|
161
161
|
});
|
|
162
162
|
Object.defineProperty(RegionAreaRule, "EXAMPLE_GRID_GRAY", {
|
|
163
163
|
enumerable: true,
|
|
164
164
|
configurable: true,
|
|
165
165
|
writable: true,
|
|
166
|
-
value: Object.freeze(RegionAreaRule.EXAMPLE_GRID_DARK.map(grid =>
|
|
166
|
+
value: Object.freeze(RegionAreaRule.EXAMPLE_GRID_DARK.map(grid => GridData.create(grid.width, grid.height, grid.tiles.map((row, y) => row.map((tile, x) => tile.withColor(tile.color === Color.Dark
|
|
167
167
|
? Color.Gray
|
|
168
168
|
: x % 2 !== y % 2
|
|
169
169
|
? Color.Dark
|
|
@@ -422,7 +422,7 @@ export default class SerializerV0 extends SerializerBase {
|
|
|
422
422
|
throw new Error(`Invalid data: ${d}`);
|
|
423
423
|
}
|
|
424
424
|
}
|
|
425
|
-
return
|
|
425
|
+
return GridData.create(width ?? tiles?.[0].length ?? 0, height ?? tiles?.length ?? 0, tiles, connections, zones, symbols, rules);
|
|
426
426
|
}
|
|
427
427
|
stringifyPuzzle(puzzle) {
|
|
428
428
|
let grid = puzzle.grid;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import
|
|
1
|
+
import UniversalSolver from './universal/universalSolver.js';
|
|
2
2
|
import BacktrackSolver from './backtrack/backtrackSolver.js';
|
|
3
3
|
import Z3Solver from './z3/z3Solver.js';
|
|
4
4
|
const allSolvers = new Map();
|
|
@@ -6,6 +6,6 @@ function register(prototype) {
|
|
|
6
6
|
allSolvers.set(prototype.id, prototype);
|
|
7
7
|
}
|
|
8
8
|
register(new BacktrackSolver());
|
|
9
|
-
register(new
|
|
9
|
+
register(new UniversalSolver());
|
|
10
10
|
register(new Z3Solver());
|
|
11
11
|
export { allSolvers };
|
|
@@ -1,9 +1,8 @@
|
|
|
1
|
-
import
|
|
2
|
-
|
|
3
|
-
export default class BacktrackSolver extends Solver {
|
|
1
|
+
import EventIteratingSolver from '../eventIteratingSolver.js';
|
|
2
|
+
export default class BacktrackSolver extends EventIteratingSolver {
|
|
4
3
|
private static readonly supportedInstrs;
|
|
5
4
|
readonly id = "backtrack";
|
|
6
5
|
readonly description = "Solves puzzles using backtracking with optimizations (blazingly fast). Support most rules and symbols (including underclued).";
|
|
7
|
-
|
|
6
|
+
protected createWorker(): Worker;
|
|
8
7
|
isInstructionSupported(instructionId: string): boolean;
|
|
9
8
|
}
|