@logic-pad/core 0.7.0 → 0.9.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 +57 -11
- package/dist/data/grid.js +1 -0
- package/dist/data/primitives.d.ts +2 -1
- package/dist/data/primitives.js +2 -0
- package/dist/data/rules/banPatternRule.js +8 -0
- package/dist/data/rules/musicGridRule.d.ts +1 -1
- package/dist/data/rules/musicGridRule.js +2 -7
- package/dist/data/rules/wrapAroundRule.d.ts +0 -2
- package/dist/data/rules/wrapAroundRule.js +124 -58
- package/dist/data/solver/backtrack/backtrackSolver.d.ts +1 -0
- package/dist/data/solver/backtrack/backtrackSolver.js +8 -0
- package/dist/data/solver/backtrack/backtrackWorker.js +11 -0
- package/dist/data/solver/backtrack/symbols/focus.d.ts +9 -0
- package/dist/data/solver/backtrack/symbols/focus.js +59 -0
- package/dist/data/solver/eventIteratingSolver.d.ts +3 -2
- package/dist/data/solver/eventIteratingSolver.js +13 -2
- package/dist/data/solver/solver.d.ts +11 -6
- package/dist/data/solver/universal/universalSolver.d.ts +1 -0
- package/dist/data/solver/universal/universalSolver.js +6 -0
- package/dist/data/solver/universal/universalWorker.js +5 -0
- package/dist/data/solver/z3/z3Solver.d.ts +2 -0
- package/dist/data/solver/z3/z3Solver.js +12 -0
- package/dist/data/symbols/directionLinkerSymbol.js +22 -13
- package/dist/data/symbols/focusSymbol.d.ts +30 -0
- package/dist/data/symbols/focusSymbol.js +110 -0
- package/dist/data/symbols/minesweeperSymbol.d.ts +1 -1
- package/dist/data/symbols/minesweeperSymbol.js +9 -2
- package/dist/data/symbols/symbols.gen.d.ts +1 -0
- package/dist/data/symbols/symbols.gen.js +1 -0
- package/dist/data/symbols/viewpointSymbol.js +9 -11
- package/dist/index.d.ts +3 -1
- package/dist/index.js +3 -1
- package/package.json +1 -1
|
@@ -86,6 +86,7 @@ declare global {
|
|
|
86
86
|
None = 'none',
|
|
87
87
|
Wrap = 'wrap',
|
|
88
88
|
WrapReverse = 'wrap-reverse',
|
|
89
|
+
ReflectReverse = 'reflect-reverse',
|
|
89
90
|
}
|
|
90
91
|
export declare const WRAPPINGS: readonly Wrapping[];
|
|
91
92
|
export declare enum Direction {
|
|
@@ -567,7 +568,7 @@ declare global {
|
|
|
567
568
|
get configs(): readonly AnyConfig[] | null;
|
|
568
569
|
createExampleGrid(): GridData;
|
|
569
570
|
get searchVariants(): SearchVariant[];
|
|
570
|
-
validateGrid(
|
|
571
|
+
validateGrid(_grid: GridData): RuleState;
|
|
571
572
|
onSetGrid(
|
|
572
573
|
_oldGrid: GridData,
|
|
573
574
|
newGrid: GridData,
|
|
@@ -650,9 +651,7 @@ declare global {
|
|
|
650
651
|
readonly vertical: Wrapping;
|
|
651
652
|
private static readonly EXAMPLE_GRID_NONE;
|
|
652
653
|
private static readonly EXAMPLE_GRID_HORIZONTAL;
|
|
653
|
-
private static readonly EXAMPLE_GRID_HORIZONTAL_REVERSE;
|
|
654
654
|
private static readonly EXAMPLE_GRID_VERTICAL;
|
|
655
|
-
private static readonly EXAMPLE_GRID_VERTICAL_REVERSE;
|
|
656
655
|
private static readonly SEARCH_VARIANTS;
|
|
657
656
|
private static readonly CONFIGS;
|
|
658
657
|
/**
|
|
@@ -2034,9 +2033,6 @@ declare global {
|
|
|
2034
2033
|
stringifyPuzzle(puzzle: Puzzle): string;
|
|
2035
2034
|
parsePuzzle(input: string): Puzzle;
|
|
2036
2035
|
}
|
|
2037
|
-
export interface CancelRef {
|
|
2038
|
-
cancel?: () => void;
|
|
2039
|
-
}
|
|
2040
2036
|
/**
|
|
2041
2037
|
* Base class that all solvers must extend.
|
|
2042
2038
|
*/
|
|
@@ -2047,10 +2043,18 @@ declare global {
|
|
|
2047
2043
|
* This is also displayed to the user when selecting a solver.
|
|
2048
2044
|
*/
|
|
2049
2045
|
abstract get id(): string;
|
|
2046
|
+
/**
|
|
2047
|
+
* The author(s) of the solver.
|
|
2048
|
+
*/
|
|
2049
|
+
abstract get author(): string;
|
|
2050
2050
|
/**
|
|
2051
2051
|
* A short paragraph describing when the user should use this solver.
|
|
2052
2052
|
*/
|
|
2053
2053
|
abstract get description(): string;
|
|
2054
|
+
/**
|
|
2055
|
+
* Whether the solver supports cancellation. If `true`, the solver must respond to the abort signal if it is provided.
|
|
2056
|
+
*/
|
|
2057
|
+
abstract get supportsCancellation(): boolean;
|
|
2054
2058
|
/**
|
|
2055
2059
|
* Solve the given grid. The implementation should delegate long-running tasks to a worker thread and yield solutions
|
|
2056
2060
|
* asynchronously.
|
|
@@ -2066,12 +2070,12 @@ declare global {
|
|
|
2066
2070
|
*
|
|
2067
2071
|
* @param grid The grid to solve. The provided grid is guaranteed to be supported by the solver. Some tiles in the
|
|
2068
2072
|
* grid may already be filled by the user. It is up to the solver to decide whether to respect these tiles or not.
|
|
2069
|
-
* @param
|
|
2070
|
-
*
|
|
2073
|
+
* @param abortSignal An optional signal that the solver should subscribe to in order to cancel the operation. If the
|
|
2074
|
+
* solver does not support cancellation, it should ignore this parameter.
|
|
2071
2075
|
*/
|
|
2072
2076
|
abstract solve(
|
|
2073
2077
|
grid: GridData,
|
|
2074
|
-
|
|
2078
|
+
abortSignal?: AbortSignal
|
|
2075
2079
|
): AsyncGenerator<GridData | null>;
|
|
2076
2080
|
/**
|
|
2077
2081
|
* Check if the solver supports the current browser environment. This method is called once when the user first clicks
|
|
@@ -2104,15 +2108,17 @@ declare global {
|
|
|
2104
2108
|
}
|
|
2105
2109
|
export declare const allSolvers: Map<string, Solver>;
|
|
2106
2110
|
export declare abstract class EventIteratingSolver extends Solver {
|
|
2111
|
+
readonly supportsCancellation = true;
|
|
2107
2112
|
protected abstract createWorker(): Worker;
|
|
2108
2113
|
solve(
|
|
2109
2114
|
grid: GridData,
|
|
2110
|
-
|
|
2115
|
+
abortSignal?: AbortSignal
|
|
2111
2116
|
): AsyncGenerator<GridData | null>;
|
|
2112
2117
|
}
|
|
2113
2118
|
export declare class BacktrackSolver extends EventIteratingSolver {
|
|
2114
2119
|
private static readonly supportedInstrs;
|
|
2115
2120
|
readonly id = 'backtrack';
|
|
2121
|
+
readonly author = 'ALaggyDev';
|
|
2116
2122
|
readonly description =
|
|
2117
2123
|
'Solves puzzles using backtracking with optimizations (blazingly fast). Support most rules and symbols (including underclued).';
|
|
2118
2124
|
protected createWorker(): Worker;
|
|
@@ -2357,6 +2363,43 @@ declare global {
|
|
|
2357
2363
|
y: number
|
|
2358
2364
|
): Position$1 | null;
|
|
2359
2365
|
}
|
|
2366
|
+
export declare class FocusSymbol extends NumberSymbol {
|
|
2367
|
+
private static readonly CONFIGS;
|
|
2368
|
+
private static readonly EXAMPLE_GRID;
|
|
2369
|
+
/**
|
|
2370
|
+
* **Focus Numbers count directly adjacent cells of the same color**
|
|
2371
|
+
* @param x - The x-coordinate of the symbol.
|
|
2372
|
+
* @param y - The y-coordinate of the symbol.
|
|
2373
|
+
* @param number - The focus number.
|
|
2374
|
+
*/
|
|
2375
|
+
constructor(x: number, y: number, number: number);
|
|
2376
|
+
get id(): string;
|
|
2377
|
+
get placementStep(): number;
|
|
2378
|
+
get explanation(): string;
|
|
2379
|
+
get configs(): readonly AnyConfig[] | null;
|
|
2380
|
+
createExampleGrid(): GridData;
|
|
2381
|
+
countTiles(grid: GridData): {
|
|
2382
|
+
completed: number;
|
|
2383
|
+
possible: number;
|
|
2384
|
+
};
|
|
2385
|
+
copyWith({
|
|
2386
|
+
x,
|
|
2387
|
+
y,
|
|
2388
|
+
number,
|
|
2389
|
+
}: {
|
|
2390
|
+
x?: number;
|
|
2391
|
+
y?: number;
|
|
2392
|
+
number?: number;
|
|
2393
|
+
}): this;
|
|
2394
|
+
withNumber(number: number): this;
|
|
2395
|
+
}
|
|
2396
|
+
export declare class FocusBTModule extends BTModule {
|
|
2397
|
+
instr: FocusSymbol;
|
|
2398
|
+
private cachedCheckResult?;
|
|
2399
|
+
constructor(instr: FocusSymbol);
|
|
2400
|
+
checkGlobal(grid: BTGridData): CheckResult | false;
|
|
2401
|
+
private buildCheckAndRating;
|
|
2402
|
+
}
|
|
2360
2403
|
export declare class GalaxySymbol extends DirectionLinkerSymbol {
|
|
2361
2404
|
readonly x: number;
|
|
2362
2405
|
readonly y: number;
|
|
@@ -2464,7 +2507,7 @@ declare global {
|
|
|
2464
2507
|
private static readonly CONFIGS;
|
|
2465
2508
|
private static readonly EXAMPLE_GRID;
|
|
2466
2509
|
/**
|
|
2467
|
-
* **Minesweeper
|
|
2510
|
+
* **Minesweeper Numbers count opposite cells in 8 adjacent spaces**
|
|
2468
2511
|
*
|
|
2469
2512
|
* @param x - The x-coordinate of the symbol.
|
|
2470
2513
|
* @param y - The y-coordinate of the symbol.
|
|
@@ -2588,6 +2631,7 @@ declare global {
|
|
|
2588
2631
|
}
|
|
2589
2632
|
export declare class UniversalSolver extends EventIteratingSolver {
|
|
2590
2633
|
readonly id = 'universal';
|
|
2634
|
+
readonly author = 'romain22222, Lysine';
|
|
2591
2635
|
readonly description =
|
|
2592
2636
|
'A backtracking solver that supports all rules and symbols (including underclued) but is less optimized.';
|
|
2593
2637
|
protected createWorker(): Worker;
|
|
@@ -2678,8 +2722,10 @@ declare global {
|
|
|
2678
2722
|
): import('grilops').Direction;
|
|
2679
2723
|
export declare class Z3Solver extends Solver {
|
|
2680
2724
|
readonly id = 'z3';
|
|
2725
|
+
readonly author = 'Lysine';
|
|
2681
2726
|
readonly description =
|
|
2682
2727
|
'Good for confirming that a solution is unique, especially for larger puzzles. It is otherwise slower than most solvers in small to medium-sized puzzles.';
|
|
2728
|
+
readonly supportsCancellation = false;
|
|
2683
2729
|
isEnvironmentSupported(): Promise<boolean>;
|
|
2684
2730
|
solve(grid: GridData): AsyncGenerator<GridData | null>;
|
|
2685
2731
|
isInstructionSupported(instructionId: string): boolean;
|
package/dist/data/grid.js
CHANGED
|
@@ -204,6 +204,7 @@ export default class GridData {
|
|
|
204
204
|
const tiles = this.tiles.map(row => [...row]);
|
|
205
205
|
const newTile = typeof tile === 'function' ? tile(tiles[y][x]) : tile;
|
|
206
206
|
changing.forEach(({ x, y }) => {
|
|
207
|
+
({ x, y } = this.toArrayCoordinates(x, y));
|
|
207
208
|
tiles[y][x] = tiles[y][x].withColor(newTile.color);
|
|
208
209
|
});
|
|
209
210
|
tiles[y][x] = newTile;
|
|
@@ -67,7 +67,8 @@ export declare const COMPARISONS: readonly Comparison[];
|
|
|
67
67
|
export declare enum Wrapping {
|
|
68
68
|
None = "none",
|
|
69
69
|
Wrap = "wrap",
|
|
70
|
-
WrapReverse = "wrap-reverse"
|
|
70
|
+
WrapReverse = "wrap-reverse",
|
|
71
|
+
ReflectReverse = "reflect-reverse"
|
|
71
72
|
}
|
|
72
73
|
export declare const WRAPPINGS: readonly Wrapping[];
|
|
73
74
|
export declare enum Direction {
|
package/dist/data/primitives.js
CHANGED
|
@@ -56,11 +56,13 @@ export var Wrapping;
|
|
|
56
56
|
Wrapping["None"] = "none";
|
|
57
57
|
Wrapping["Wrap"] = "wrap";
|
|
58
58
|
Wrapping["WrapReverse"] = "wrap-reverse";
|
|
59
|
+
Wrapping["ReflectReverse"] = "reflect-reverse";
|
|
59
60
|
})(Wrapping || (Wrapping = {}));
|
|
60
61
|
export const WRAPPINGS = [
|
|
61
62
|
Wrapping.None,
|
|
62
63
|
Wrapping.Wrap,
|
|
63
64
|
Wrapping.WrapReverse,
|
|
65
|
+
Wrapping.ReflectReverse,
|
|
64
66
|
];
|
|
65
67
|
export var Direction;
|
|
66
68
|
(function (Direction) {
|
|
@@ -74,7 +74,15 @@ class BanPatternRule extends Rule {
|
|
|
74
74
|
for (let y = 0; y <= grid.height - 1; y++) {
|
|
75
75
|
for (let x = 0; x <= grid.width - 1; x++) {
|
|
76
76
|
let match = true;
|
|
77
|
+
const visited = [];
|
|
77
78
|
for (const tile of pattern.elements) {
|
|
79
|
+
const pos = grid.toArrayCoordinates(x + tile.x, y + tile.y);
|
|
80
|
+
if (grid.wrapAround.value && // optimization: not need to check visited if wrapAround is disabled
|
|
81
|
+
visited.some(p => p.x === pos.x && p.y === pos.y)) {
|
|
82
|
+
match = false;
|
|
83
|
+
break;
|
|
84
|
+
}
|
|
85
|
+
visited.push(pos);
|
|
78
86
|
const t = grid.getTile(x + tile.x, y + tile.y);
|
|
79
87
|
if (!t.exists || t.color !== tile.color) {
|
|
80
88
|
match = false;
|
|
@@ -25,7 +25,7 @@ export default class MusicGridRule extends Rule implements GridChangeHandler, Se
|
|
|
25
25
|
get configs(): readonly AnyConfig[] | null;
|
|
26
26
|
createExampleGrid(): GridData;
|
|
27
27
|
get searchVariants(): SearchVariant[];
|
|
28
|
-
validateGrid(
|
|
28
|
+
validateGrid(_grid: GridData): RuleState;
|
|
29
29
|
onSetGrid(_oldGrid: GridData, newGrid: GridData, _solution: GridData | null): GridData;
|
|
30
30
|
onGridChange(newGrid: GridData): this;
|
|
31
31
|
onGridResize(_grid: GridData, mode: 'insert' | 'remove', direction: 'row' | 'column', index: number): this | null;
|
|
@@ -61,13 +61,8 @@ class MusicGridRule extends Rule {
|
|
|
61
61
|
get searchVariants() {
|
|
62
62
|
return MusicGridRule.SEARCH_VARIANTS;
|
|
63
63
|
}
|
|
64
|
-
validateGrid(
|
|
65
|
-
|
|
66
|
-
return { state: State.Incomplete };
|
|
67
|
-
}
|
|
68
|
-
else {
|
|
69
|
-
return { state: State.Satisfied };
|
|
70
|
-
}
|
|
64
|
+
validateGrid(_grid) {
|
|
65
|
+
return { state: State.Incomplete };
|
|
71
66
|
}
|
|
72
67
|
onSetGrid(_oldGrid, newGrid, _solution) {
|
|
73
68
|
if (newGrid.getTileCount(true, undefined, Color.Gray) === 0)
|
|
@@ -8,9 +8,7 @@ export default class WrapAroundRule extends Rule implements GetTileHandler {
|
|
|
8
8
|
readonly vertical: Wrapping;
|
|
9
9
|
private static readonly EXAMPLE_GRID_NONE;
|
|
10
10
|
private static readonly EXAMPLE_GRID_HORIZONTAL;
|
|
11
|
-
private static readonly EXAMPLE_GRID_HORIZONTAL_REVERSE;
|
|
12
11
|
private static readonly EXAMPLE_GRID_VERTICAL;
|
|
13
|
-
private static readonly EXAMPLE_GRID_VERTICAL_REVERSE;
|
|
14
12
|
private static readonly SEARCH_VARIANTS;
|
|
15
13
|
private static readonly CONFIGS;
|
|
16
14
|
/**
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import { ConfigType } from '../config.js';
|
|
2
2
|
import { array } from '../dataHelper.js';
|
|
3
3
|
import GridData from '../grid.js';
|
|
4
|
-
import { Color, MajorRule, State, Wrapping, } from '../primitives.js';
|
|
4
|
+
import { Color, MajorRule, Orientation, State, Wrapping, orientationToggle, } from '../primitives.js';
|
|
5
5
|
import LetterSymbol from '../symbols/letterSymbol.js';
|
|
6
|
+
import MyopiaSymbol from '../symbols/myopiaSymbol.js';
|
|
6
7
|
import Rule from './rule.js';
|
|
7
8
|
class WrapAroundRule extends Rule {
|
|
8
9
|
/**
|
|
@@ -29,19 +30,32 @@ class WrapAroundRule extends Rule {
|
|
|
29
30
|
this.vertical = vertical;
|
|
30
31
|
}
|
|
31
32
|
onGetTile(x, y, grid) {
|
|
33
|
+
if (grid.width === 0 || grid.height === 0) {
|
|
34
|
+
return { x, y };
|
|
35
|
+
}
|
|
32
36
|
if (this.horizontal !== Wrapping.None) {
|
|
33
37
|
const idx = Math.abs(Math.floor(x / grid.width));
|
|
34
38
|
x = ((x % grid.width) + grid.width) % grid.width;
|
|
35
|
-
if (this.horizontal === Wrapping.WrapReverse
|
|
39
|
+
if ((this.horizontal === Wrapping.WrapReverse ||
|
|
40
|
+
this.horizontal === Wrapping.ReflectReverse) &&
|
|
41
|
+
idx % 2 === 1) {
|
|
36
42
|
y = grid.height - 1 - y;
|
|
37
43
|
}
|
|
44
|
+
if (this.horizontal === Wrapping.ReflectReverse && idx % 2 === 1) {
|
|
45
|
+
x = grid.width - 1 - x;
|
|
46
|
+
}
|
|
38
47
|
}
|
|
39
48
|
if (this.vertical !== Wrapping.None) {
|
|
40
49
|
const idx = Math.abs(Math.floor(y / grid.height));
|
|
41
50
|
y = ((y % grid.height) + grid.height) % grid.height;
|
|
42
|
-
if (this.vertical === Wrapping.WrapReverse
|
|
51
|
+
if ((this.vertical === Wrapping.WrapReverse ||
|
|
52
|
+
this.vertical === Wrapping.ReflectReverse) &&
|
|
53
|
+
idx % 2 === 1) {
|
|
43
54
|
x = grid.width - 1 - x;
|
|
44
55
|
}
|
|
56
|
+
if (this.vertical === Wrapping.ReflectReverse && idx % 2 === 1) {
|
|
57
|
+
y = grid.height - 1 - y;
|
|
58
|
+
}
|
|
45
59
|
}
|
|
46
60
|
return { x, y };
|
|
47
61
|
}
|
|
@@ -52,37 +66,48 @@ class WrapAroundRule extends Rule {
|
|
|
52
66
|
if (this.horizontal === Wrapping.None && this.vertical === Wrapping.None) {
|
|
53
67
|
return `No edges are connected.`;
|
|
54
68
|
}
|
|
55
|
-
|
|
56
|
-
|
|
69
|
+
const horizontal = this.horizontal === Wrapping.None
|
|
70
|
+
? null
|
|
71
|
+
: this.horizontal === Wrapping.Wrap ||
|
|
72
|
+
this.horizontal === Wrapping.WrapReverse
|
|
73
|
+
? 'connected'
|
|
74
|
+
: 'reflective';
|
|
75
|
+
const vertical = this.vertical === Wrapping.None
|
|
76
|
+
? null
|
|
77
|
+
: this.vertical === Wrapping.Wrap ||
|
|
78
|
+
this.vertical === Wrapping.WrapReverse
|
|
79
|
+
? 'connected'
|
|
80
|
+
: 'reflective';
|
|
81
|
+
const horizontalReverse = this.horizontal === Wrapping.WrapReverse ||
|
|
82
|
+
this.horizontal === Wrapping.ReflectReverse
|
|
83
|
+
? ' in reverse'
|
|
84
|
+
: '';
|
|
85
|
+
const verticalReverse = this.vertical === Wrapping.WrapReverse ||
|
|
86
|
+
this.vertical === Wrapping.ReflectReverse
|
|
87
|
+
? ' in reverse'
|
|
88
|
+
: '';
|
|
89
|
+
if (this.horizontal === this.vertical) {
|
|
90
|
+
return `All four edges are ${horizontal}${horizontalReverse}.`;
|
|
57
91
|
}
|
|
58
|
-
|
|
59
|
-
return `The
|
|
92
|
+
if (this.horizontal === Wrapping.None) {
|
|
93
|
+
return `The top and bottom edges are ${vertical}${verticalReverse}.`;
|
|
60
94
|
}
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
return `All four edges are connected.`;
|
|
95
|
+
if (this.vertical === Wrapping.None) {
|
|
96
|
+
return `The left and right edges are ${horizontal}${horizontalReverse}.`;
|
|
64
97
|
}
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
return `All four edges are connected in reverse.`;
|
|
98
|
+
if (horizontal === vertical) {
|
|
99
|
+
if (horizontalReverse !== '') {
|
|
100
|
+
return `All four edges are ${horizontal}, with the left and right edges${horizontalReverse}.`;
|
|
101
|
+
}
|
|
102
|
+
else {
|
|
103
|
+
return `All four edges are ${horizontal}, with the top and bottom edges${verticalReverse}.`;
|
|
104
|
+
}
|
|
73
105
|
}
|
|
106
|
+
return `The left and right edges are ${horizontal}${horizontalReverse}. The top and bottom edges are ${vertical}${verticalReverse}.`;
|
|
74
107
|
}
|
|
75
108
|
createExampleGrid() {
|
|
76
|
-
const horizontal = this.horizontal
|
|
77
|
-
|
|
78
|
-
: this.horizontal === Wrapping.WrapReverse
|
|
79
|
-
? WrapAroundRule.EXAMPLE_GRID_HORIZONTAL_REVERSE
|
|
80
|
-
: WrapAroundRule.EXAMPLE_GRID_NONE;
|
|
81
|
-
const vertical = this.vertical === Wrapping.Wrap
|
|
82
|
-
? WrapAroundRule.EXAMPLE_GRID_VERTICAL
|
|
83
|
-
: this.vertical === Wrapping.WrapReverse
|
|
84
|
-
? WrapAroundRule.EXAMPLE_GRID_VERTICAL_REVERSE
|
|
85
|
-
: WrapAroundRule.EXAMPLE_GRID_NONE;
|
|
109
|
+
const horizontal = WrapAroundRule.EXAMPLE_GRID_HORIZONTAL[this.horizontal];
|
|
110
|
+
const vertical = WrapAroundRule.EXAMPLE_GRID_VERTICAL[this.vertical];
|
|
86
111
|
if (horizontal === WrapAroundRule.EXAMPLE_GRID_NONE) {
|
|
87
112
|
return vertical;
|
|
88
113
|
}
|
|
@@ -134,41 +159,79 @@ Object.defineProperty(WrapAroundRule, "EXAMPLE_GRID_HORIZONTAL", {
|
|
|
134
159
|
enumerable: true,
|
|
135
160
|
configurable: true,
|
|
136
161
|
writable: true,
|
|
137
|
-
value: Object.freeze(
|
|
138
|
-
.
|
|
139
|
-
.
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
.
|
|
151
|
-
|
|
162
|
+
value: Object.freeze({
|
|
163
|
+
[Wrapping.None]: WrapAroundRule.EXAMPLE_GRID_NONE,
|
|
164
|
+
[Wrapping.Wrap]: GridData.create([
|
|
165
|
+
'wwwww',
|
|
166
|
+
'bwwwb',
|
|
167
|
+
'wwwww',
|
|
168
|
+
'bwwwb',
|
|
169
|
+
'wwwww',
|
|
170
|
+
])
|
|
171
|
+
.addSymbol(new LetterSymbol(0, 1, 'A'))
|
|
172
|
+
.addSymbol(new LetterSymbol(4, 1, 'A'))
|
|
173
|
+
.addSymbol(new LetterSymbol(0, 3, 'B'))
|
|
174
|
+
.addSymbol(new LetterSymbol(4, 3, 'B')),
|
|
175
|
+
[Wrapping.WrapReverse]: GridData.create([
|
|
176
|
+
'wwwww',
|
|
177
|
+
'bwwwb',
|
|
178
|
+
'wwwww',
|
|
179
|
+
'bwwwb',
|
|
180
|
+
'wwwww',
|
|
181
|
+
])
|
|
182
|
+
.addSymbol(new LetterSymbol(0, 1, 'A'))
|
|
183
|
+
.addSymbol(new LetterSymbol(4, 1, 'B'))
|
|
184
|
+
.addSymbol(new LetterSymbol(0, 3, 'B'))
|
|
185
|
+
.addSymbol(new LetterSymbol(4, 3, 'A')),
|
|
186
|
+
[Wrapping.ReflectReverse]: GridData.create([
|
|
187
|
+
'wwwww',
|
|
188
|
+
'bwwww',
|
|
189
|
+
'wwwww',
|
|
190
|
+
'wwwwb',
|
|
191
|
+
'wwwww',
|
|
192
|
+
])
|
|
193
|
+
.addSymbol(new MyopiaSymbol(0, 3, false, orientationToggle(Orientation.Left)))
|
|
194
|
+
.addSymbol(new MyopiaSymbol(4, 1, false, orientationToggle(Orientation.Right))),
|
|
195
|
+
})
|
|
152
196
|
});
|
|
153
197
|
Object.defineProperty(WrapAroundRule, "EXAMPLE_GRID_VERTICAL", {
|
|
154
198
|
enumerable: true,
|
|
155
199
|
configurable: true,
|
|
156
200
|
writable: true,
|
|
157
|
-
value: Object.freeze(
|
|
158
|
-
.
|
|
159
|
-
.
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
.
|
|
171
|
-
|
|
201
|
+
value: Object.freeze({
|
|
202
|
+
[Wrapping.None]: WrapAroundRule.EXAMPLE_GRID_NONE,
|
|
203
|
+
[Wrapping.Wrap]: GridData.create([
|
|
204
|
+
'wbwbw',
|
|
205
|
+
'wwwww',
|
|
206
|
+
'wwwww',
|
|
207
|
+
'wwwww',
|
|
208
|
+
'wbwbw',
|
|
209
|
+
])
|
|
210
|
+
.addSymbol(new LetterSymbol(1, 0, 'C'))
|
|
211
|
+
.addSymbol(new LetterSymbol(3, 0, 'D'))
|
|
212
|
+
.addSymbol(new LetterSymbol(1, 4, 'C'))
|
|
213
|
+
.addSymbol(new LetterSymbol(3, 4, 'D')),
|
|
214
|
+
[Wrapping.WrapReverse]: GridData.create([
|
|
215
|
+
'wbwbw',
|
|
216
|
+
'wwwww',
|
|
217
|
+
'wwwww',
|
|
218
|
+
'wwwww',
|
|
219
|
+
'wbwbw',
|
|
220
|
+
])
|
|
221
|
+
.addSymbol(new LetterSymbol(1, 0, 'C'))
|
|
222
|
+
.addSymbol(new LetterSymbol(3, 0, 'D'))
|
|
223
|
+
.addSymbol(new LetterSymbol(1, 4, 'D'))
|
|
224
|
+
.addSymbol(new LetterSymbol(3, 4, 'C')),
|
|
225
|
+
[Wrapping.ReflectReverse]: GridData.create([
|
|
226
|
+
'wbwww',
|
|
227
|
+
'wwwww',
|
|
228
|
+
'wwwww',
|
|
229
|
+
'wwwww',
|
|
230
|
+
'wwwbw',
|
|
231
|
+
])
|
|
232
|
+
.addSymbol(new MyopiaSymbol(3, 0, false, orientationToggle(Orientation.Up)))
|
|
233
|
+
.addSymbol(new MyopiaSymbol(1, 4, false, orientationToggle(Orientation.Down))),
|
|
234
|
+
})
|
|
172
235
|
});
|
|
173
236
|
Object.defineProperty(WrapAroundRule, "SEARCH_VARIANTS", {
|
|
174
237
|
enumerable: true,
|
|
@@ -178,6 +241,9 @@ Object.defineProperty(WrapAroundRule, "SEARCH_VARIANTS", {
|
|
|
178
241
|
new WrapAroundRule(Wrapping.Wrap, Wrapping.None).searchVariant(),
|
|
179
242
|
new WrapAroundRule(Wrapping.None, Wrapping.Wrap).searchVariant(),
|
|
180
243
|
new WrapAroundRule(Wrapping.Wrap, Wrapping.Wrap).searchVariant(),
|
|
244
|
+
new WrapAroundRule(Wrapping.ReflectReverse, Wrapping.None).searchVariant(),
|
|
245
|
+
new WrapAroundRule(Wrapping.None, Wrapping.ReflectReverse).searchVariant(),
|
|
246
|
+
new WrapAroundRule(Wrapping.ReflectReverse, Wrapping.ReflectReverse).searchVariant(),
|
|
181
247
|
]
|
|
182
248
|
});
|
|
183
249
|
Object.defineProperty(WrapAroundRule, "CONFIGS", {
|
|
@@ -2,6 +2,7 @@ import EventIteratingSolver from '../eventIteratingSolver.js';
|
|
|
2
2
|
export default class BacktrackSolver extends EventIteratingSolver {
|
|
3
3
|
private static readonly supportedInstrs;
|
|
4
4
|
readonly id = "backtrack";
|
|
5
|
+
readonly author = "ALaggyDev";
|
|
5
6
|
readonly description = "Solves puzzles using backtracking with optimizations (blazingly fast). Support most rules and symbols (including underclued).";
|
|
6
7
|
protected createWorker(): Worker;
|
|
7
8
|
isInstructionSupported(instructionId: string): boolean;
|
|
@@ -11,6 +11,7 @@ import { instance as galaxyInstance } from '../../symbols/galaxySymbol.js';
|
|
|
11
11
|
import { instance as letterInstance } from '../../symbols/letterSymbol.js';
|
|
12
12
|
import { instance as lotusInstance } from '../../symbols/lotusSymbol.js';
|
|
13
13
|
import { instance as minesweeperInstance } from '../../symbols/minesweeperSymbol.js';
|
|
14
|
+
import { instance as focusInstance } from '../../symbols/focusSymbol.js';
|
|
14
15
|
import { instance as myopiaInstance } from '../../symbols/myopiaSymbol.js';
|
|
15
16
|
import { instance as viewpointInstance } from '../../symbols/viewpointSymbol.js';
|
|
16
17
|
import { instance as connectAllInstance } from '../z3/modules/connectAllModule.js';
|
|
@@ -24,6 +25,12 @@ class BacktrackSolver extends EventIteratingSolver {
|
|
|
24
25
|
writable: true,
|
|
25
26
|
value: 'backtrack'
|
|
26
27
|
});
|
|
28
|
+
Object.defineProperty(this, "author", {
|
|
29
|
+
enumerable: true,
|
|
30
|
+
configurable: true,
|
|
31
|
+
writable: true,
|
|
32
|
+
value: 'ALaggyDev'
|
|
33
|
+
});
|
|
27
34
|
Object.defineProperty(this, "description", {
|
|
28
35
|
enumerable: true,
|
|
29
36
|
configurable: true,
|
|
@@ -52,6 +59,7 @@ Object.defineProperty(BacktrackSolver, "supportedInstrs", {
|
|
|
52
59
|
lotusInstance.id,
|
|
53
60
|
myopiaInstance.id,
|
|
54
61
|
minesweeperInstance.id,
|
|
62
|
+
focusInstance.id,
|
|
55
63
|
letterInstance.id,
|
|
56
64
|
undercluedInstance.id,
|
|
57
65
|
connectAllInstance.id,
|
|
@@ -14,6 +14,7 @@ import { instance as galaxyInstance, } from '../../symbols/galaxySymbol.js';
|
|
|
14
14
|
import { instance as letterInstance, } from '../../symbols/letterSymbol.js';
|
|
15
15
|
import { instance as lotusInstance, } from '../../symbols/lotusSymbol.js';
|
|
16
16
|
import { instance as minesweeperInstance, } from '../../symbols/minesweeperSymbol.js';
|
|
17
|
+
import { instance as focusInstance, } from '../../symbols/focusSymbol.js';
|
|
17
18
|
import { instance as myopiaInstance, } from '../../symbols/myopiaSymbol.js';
|
|
18
19
|
import { instance as viewpointInstance, } from '../../symbols/viewpointSymbol.js';
|
|
19
20
|
import { instance as connectAllInstance } from '../z3/modules/connectAllModule.js';
|
|
@@ -33,6 +34,7 @@ import LotusBTModule from './symbols/lotus.js';
|
|
|
33
34
|
import MinesweeperBTModule from './symbols/minesweeper.js';
|
|
34
35
|
import MyopiaBTModule from './symbols/myopia.js';
|
|
35
36
|
import ViewpointBTModule from './symbols/viewpoint.js';
|
|
37
|
+
import FocusBTModule from './symbols/focus.js';
|
|
36
38
|
function translateToBTGridData(grid) {
|
|
37
39
|
const tiles = array(grid.width, grid.height, (x, y) => {
|
|
38
40
|
const tile = grid.getTile(x, y);
|
|
@@ -71,6 +73,9 @@ function translateToBTGridData(grid) {
|
|
|
71
73
|
else if (id === minesweeperInstance.id) {
|
|
72
74
|
module = new MinesweeperBTModule(symbol);
|
|
73
75
|
}
|
|
76
|
+
else if (id === focusInstance.id) {
|
|
77
|
+
module = new FocusBTModule(symbol);
|
|
78
|
+
}
|
|
74
79
|
else if (id === letterInstance.id) {
|
|
75
80
|
continue;
|
|
76
81
|
}
|
|
@@ -289,6 +294,12 @@ onmessage = e => {
|
|
|
289
294
|
let count = 0;
|
|
290
295
|
solve(grid, solution => {
|
|
291
296
|
// if (count === 0) console.timeLog('Solve time', 'First solution');
|
|
297
|
+
if (solution) {
|
|
298
|
+
if (solution.resetTiles().colorEquals(solution)) {
|
|
299
|
+
postMessage(null);
|
|
300
|
+
return false;
|
|
301
|
+
}
|
|
302
|
+
}
|
|
292
303
|
postMessage(Serializer.stringifyGrid(solution));
|
|
293
304
|
count += 1;
|
|
294
305
|
return count < 2;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import FocusSymbol from '../../../symbols/focusSymbol.js';
|
|
2
|
+
import BTModule, { BTGridData, CheckResult } from '../data.js';
|
|
3
|
+
export default class FocusBTModule extends BTModule {
|
|
4
|
+
instr: FocusSymbol;
|
|
5
|
+
private cachedCheckResult?;
|
|
6
|
+
constructor(instr: FocusSymbol);
|
|
7
|
+
checkGlobal(grid: BTGridData): CheckResult | false;
|
|
8
|
+
private buildCheckAndRating;
|
|
9
|
+
}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import BTModule, { BTTile, IntArray2D, createOneTileResult, } from '../data.js';
|
|
2
|
+
export default class FocusBTModule extends BTModule {
|
|
3
|
+
constructor(instr) {
|
|
4
|
+
super();
|
|
5
|
+
Object.defineProperty(this, "instr", {
|
|
6
|
+
enumerable: true,
|
|
7
|
+
configurable: true,
|
|
8
|
+
writable: true,
|
|
9
|
+
value: void 0
|
|
10
|
+
});
|
|
11
|
+
Object.defineProperty(this, "cachedCheckResult", {
|
|
12
|
+
enumerable: true,
|
|
13
|
+
configurable: true,
|
|
14
|
+
writable: true,
|
|
15
|
+
value: void 0
|
|
16
|
+
});
|
|
17
|
+
this.instr = instr;
|
|
18
|
+
}
|
|
19
|
+
checkGlobal(grid) {
|
|
20
|
+
const tile = grid.getTile(this.instr.x, this.instr.y);
|
|
21
|
+
if (tile === BTTile.Empty)
|
|
22
|
+
return createOneTileResult(grid, { x: this.instr.x, y: this.instr.y });
|
|
23
|
+
let gray = 0;
|
|
24
|
+
let same = 0;
|
|
25
|
+
for (let y = this.instr.y - 1; y <= this.instr.y + 1; y++) {
|
|
26
|
+
for (let x = this.instr.x - 1; x <= this.instr.x + 1; x++) {
|
|
27
|
+
if (y !== this.instr.y && x !== this.instr.x)
|
|
28
|
+
continue;
|
|
29
|
+
if (!grid.isInBound(x, y) || (x === this.instr.x && y === this.instr.y))
|
|
30
|
+
continue;
|
|
31
|
+
const checkTile = grid.getTile(x, y);
|
|
32
|
+
if (checkTile === BTTile.Empty)
|
|
33
|
+
gray++;
|
|
34
|
+
else if (checkTile === tile)
|
|
35
|
+
same++;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
if (same > this.instr.number || same + gray < this.instr.number)
|
|
39
|
+
return false;
|
|
40
|
+
if (!this.cachedCheckResult)
|
|
41
|
+
this.cachedCheckResult = this.buildCheckAndRating(grid);
|
|
42
|
+
return this.cachedCheckResult;
|
|
43
|
+
}
|
|
44
|
+
buildCheckAndRating(grid) {
|
|
45
|
+
const tilesNeedCheck = IntArray2D.create(grid.width, grid.height);
|
|
46
|
+
const ratings = [];
|
|
47
|
+
for (let y = this.instr.y - 1; y <= this.instr.y + 1; y++) {
|
|
48
|
+
for (let x = this.instr.x - 1; x <= this.instr.x + 1; x++) {
|
|
49
|
+
if (y !== this.instr.y && x !== this.instr.x)
|
|
50
|
+
continue;
|
|
51
|
+
if (!grid.isInBound(x, y) || (x === this.instr.x && y === this.instr.y))
|
|
52
|
+
continue;
|
|
53
|
+
tilesNeedCheck.set(x, y, 1);
|
|
54
|
+
ratings.push({ pos: { x, y }, score: 1 });
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
return { tilesNeedCheck, ratings };
|
|
58
|
+
}
|
|
59
|
+
}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import GridData from '../grid.js';
|
|
2
|
-
import Solver
|
|
2
|
+
import Solver from './solver.js';
|
|
3
3
|
export default abstract class EventIteratingSolver extends Solver {
|
|
4
|
+
readonly supportsCancellation = true;
|
|
4
5
|
protected abstract createWorker(): Worker;
|
|
5
|
-
solve(grid: GridData,
|
|
6
|
+
solve(grid: GridData, abortSignal?: AbortSignal): AsyncGenerator<GridData | null>;
|
|
6
7
|
}
|
|
@@ -2,9 +2,19 @@ import { Serializer } from '../serializer/allSerializers.js';
|
|
|
2
2
|
import Solver from './solver.js';
|
|
3
3
|
import { EventIterator } from 'event-iterator';
|
|
4
4
|
export default class EventIteratingSolver extends Solver {
|
|
5
|
-
|
|
5
|
+
constructor() {
|
|
6
|
+
super(...arguments);
|
|
7
|
+
Object.defineProperty(this, "supportsCancellation", {
|
|
8
|
+
enumerable: true,
|
|
9
|
+
configurable: true,
|
|
10
|
+
writable: true,
|
|
11
|
+
value: true
|
|
12
|
+
});
|
|
13
|
+
}
|
|
14
|
+
async *solve(grid, abortSignal) {
|
|
6
15
|
const worker = this.createWorker();
|
|
7
|
-
|
|
16
|
+
const terminateHandler = () => worker.terminate();
|
|
17
|
+
abortSignal?.addEventListener('abort', terminateHandler);
|
|
8
18
|
try {
|
|
9
19
|
const iterator = new EventIterator(({ push, stop, fail }) => {
|
|
10
20
|
worker.postMessage(Serializer.stringifyGrid(grid.resetTiles()));
|
|
@@ -28,6 +38,7 @@ export default class EventIteratingSolver extends Solver {
|
|
|
28
38
|
}
|
|
29
39
|
finally {
|
|
30
40
|
worker.terminate();
|
|
41
|
+
abortSignal?.removeEventListener('abort', terminateHandler);
|
|
31
42
|
}
|
|
32
43
|
}
|
|
33
44
|
}
|
|
@@ -1,7 +1,4 @@
|
|
|
1
1
|
import GridData from '../grid.js';
|
|
2
|
-
export interface CancelRef {
|
|
3
|
-
cancel?: () => void;
|
|
4
|
-
}
|
|
5
2
|
/**
|
|
6
3
|
* Base class that all solvers must extend.
|
|
7
4
|
*/
|
|
@@ -12,10 +9,18 @@ export default abstract class Solver {
|
|
|
12
9
|
* This is also displayed to the user when selecting a solver.
|
|
13
10
|
*/
|
|
14
11
|
abstract get id(): string;
|
|
12
|
+
/**
|
|
13
|
+
* The author(s) of the solver.
|
|
14
|
+
*/
|
|
15
|
+
abstract get author(): string;
|
|
15
16
|
/**
|
|
16
17
|
* A short paragraph describing when the user should use this solver.
|
|
17
18
|
*/
|
|
18
19
|
abstract get description(): string;
|
|
20
|
+
/**
|
|
21
|
+
* Whether the solver supports cancellation. If `true`, the solver must respond to the abort signal if it is provided.
|
|
22
|
+
*/
|
|
23
|
+
abstract get supportsCancellation(): boolean;
|
|
19
24
|
/**
|
|
20
25
|
* Solve the given grid. The implementation should delegate long-running tasks to a worker thread and yield solutions
|
|
21
26
|
* asynchronously.
|
|
@@ -31,10 +36,10 @@ export default abstract class Solver {
|
|
|
31
36
|
*
|
|
32
37
|
* @param grid The grid to solve. The provided grid is guaranteed to be supported by the solver. Some tiles in the
|
|
33
38
|
* grid may already be filled by the user. It is up to the solver to decide whether to respect these tiles or not.
|
|
34
|
-
* @param
|
|
35
|
-
*
|
|
39
|
+
* @param abortSignal An optional signal that the solver should subscribe to in order to cancel the operation. If the
|
|
40
|
+
* solver does not support cancellation, it should ignore this parameter.
|
|
36
41
|
*/
|
|
37
|
-
abstract solve(grid: GridData,
|
|
42
|
+
abstract solve(grid: GridData, abortSignal?: AbortSignal): AsyncGenerator<GridData | null>;
|
|
38
43
|
/**
|
|
39
44
|
* Check if the solver supports the current browser environment. This method is called once when the user first clicks
|
|
40
45
|
* the "Solve" button, and the result is cached for the duration of the editor session.
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import EventIteratingSolver from '../eventIteratingSolver.js';
|
|
2
2
|
export default class UniversalSolver extends EventIteratingSolver {
|
|
3
3
|
readonly id = "universal";
|
|
4
|
+
readonly author = "romain22222, Lysine";
|
|
4
5
|
readonly description = "A backtracking solver that supports all rules and symbols (including underclued) but is less optimized.";
|
|
5
6
|
protected createWorker(): Worker;
|
|
6
7
|
isInstructionSupported(instructionId: string): boolean;
|
|
@@ -9,6 +9,12 @@ export default class UniversalSolver extends EventIteratingSolver {
|
|
|
9
9
|
writable: true,
|
|
10
10
|
value: 'universal'
|
|
11
11
|
});
|
|
12
|
+
Object.defineProperty(this, "author", {
|
|
13
|
+
enumerable: true,
|
|
14
|
+
configurable: true,
|
|
15
|
+
writable: true,
|
|
16
|
+
value: 'romain22222, Lysine'
|
|
17
|
+
});
|
|
12
18
|
Object.defineProperty(this, "description", {
|
|
13
19
|
enumerable: true,
|
|
14
20
|
configurable: true,
|
|
@@ -115,6 +115,11 @@ onmessage = e => {
|
|
|
115
115
|
const grid = Serializer.parseGrid(e.data);
|
|
116
116
|
let count = 0;
|
|
117
117
|
solve(grid, solution => {
|
|
118
|
+
if (solution) {
|
|
119
|
+
if (solution.resetTiles().colorEquals(solution)) {
|
|
120
|
+
solution = null;
|
|
121
|
+
}
|
|
122
|
+
}
|
|
118
123
|
postMessage(solution ? Serializer.stringifyGrid(solution) : null);
|
|
119
124
|
count += 1;
|
|
120
125
|
return count < 2;
|
|
@@ -2,7 +2,9 @@ import GridData from '../../grid.js';
|
|
|
2
2
|
import Solver from '../solver.js';
|
|
3
3
|
export default class Z3Solver extends Solver {
|
|
4
4
|
readonly id = "z3";
|
|
5
|
+
readonly author = "Lysine";
|
|
5
6
|
readonly description = "Good for confirming that a solution is unique, especially for larger puzzles. It is otherwise slower than most solvers in small to medium-sized puzzles.";
|
|
7
|
+
readonly supportsCancellation = false;
|
|
6
8
|
isEnvironmentSupported(): Promise<boolean>;
|
|
7
9
|
solve(grid: GridData): AsyncGenerator<GridData | null>;
|
|
8
10
|
isInstructionSupported(instructionId: string): boolean;
|
|
@@ -14,12 +14,24 @@ export default class Z3Solver extends Solver {
|
|
|
14
14
|
writable: true,
|
|
15
15
|
value: 'z3'
|
|
16
16
|
});
|
|
17
|
+
Object.defineProperty(this, "author", {
|
|
18
|
+
enumerable: true,
|
|
19
|
+
configurable: true,
|
|
20
|
+
writable: true,
|
|
21
|
+
value: 'Lysine'
|
|
22
|
+
});
|
|
17
23
|
Object.defineProperty(this, "description", {
|
|
18
24
|
enumerable: true,
|
|
19
25
|
configurable: true,
|
|
20
26
|
writable: true,
|
|
21
27
|
value: 'Good for confirming that a solution is unique, especially for larger puzzles. It is otherwise slower than most solvers in small to medium-sized puzzles.'
|
|
22
28
|
});
|
|
29
|
+
Object.defineProperty(this, "supportsCancellation", {
|
|
30
|
+
enumerable: true,
|
|
31
|
+
configurable: true,
|
|
32
|
+
writable: true,
|
|
33
|
+
value: false
|
|
34
|
+
});
|
|
23
35
|
}
|
|
24
36
|
async isEnvironmentSupported() {
|
|
25
37
|
try {
|
|
@@ -65,8 +65,11 @@ class DirectionLinkerSymbol extends Symbol {
|
|
|
65
65
|
createExampleGrid() {
|
|
66
66
|
return DirectionLinkerSymbol.EXAMPLE_GRID;
|
|
67
67
|
}
|
|
68
|
-
deltaCoordinate(c, direction
|
|
69
|
-
return
|
|
68
|
+
deltaCoordinate(c, direction) {
|
|
69
|
+
return {
|
|
70
|
+
x: c.x + DirectionLinkerSymbol.directionDeltas[direction].dx,
|
|
71
|
+
y: c.y + DirectionLinkerSymbol.directionDeltas[direction].dy,
|
|
72
|
+
};
|
|
70
73
|
}
|
|
71
74
|
validateSymbol(grid) {
|
|
72
75
|
// A turtle is an object which have 2 coordinates
|
|
@@ -112,22 +115,28 @@ class DirectionLinkerSymbol extends Symbol {
|
|
|
112
115
|
const directions = Object.keys(this.linkedDirections);
|
|
113
116
|
for (const direction of directions) {
|
|
114
117
|
const newTurtle = {
|
|
115
|
-
pos1: this.deltaCoordinate(pos1, direction
|
|
116
|
-
pos2: this.deltaCoordinate(pos2, this.linkedDirections[direction]
|
|
118
|
+
pos1: this.deltaCoordinate(pos1, direction),
|
|
119
|
+
pos2: this.deltaCoordinate(pos2, this.linkedDirections[direction]),
|
|
117
120
|
color1: baseColor1,
|
|
118
121
|
color2: baseColor2,
|
|
119
122
|
};
|
|
120
|
-
|
|
121
|
-
pos1.
|
|
122
|
-
pos2.x
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
123
|
+
const newArrTurtle = {
|
|
124
|
+
pos1: grid.toArrayCoordinates(newTurtle.pos1.x, newTurtle.pos1.y),
|
|
125
|
+
pos2: grid.toArrayCoordinates(newTurtle.pos2.x, newTurtle.pos2.y),
|
|
126
|
+
color1: baseColor1,
|
|
127
|
+
color2: baseColor2,
|
|
128
|
+
};
|
|
129
|
+
if (checkedCouples.some(({ pos1, pos2 }) => pos1.x === newArrTurtle.pos1.x &&
|
|
130
|
+
pos1.y === newArrTurtle.pos1.y &&
|
|
131
|
+
pos2.x === newArrTurtle.pos2.x &&
|
|
132
|
+
pos2.y === newArrTurtle.pos2.y) ||
|
|
133
|
+
(pos1.x === newArrTurtle.pos2.x &&
|
|
134
|
+
pos1.y === newArrTurtle.pos2.y &&
|
|
135
|
+
pos2.x === newArrTurtle.pos1.x &&
|
|
136
|
+
pos2.y === newArrTurtle.pos1.y)) {
|
|
128
137
|
continue;
|
|
129
138
|
}
|
|
130
|
-
checkedCouples.push(
|
|
139
|
+
checkedCouples.push(newArrTurtle);
|
|
131
140
|
queue.push(newTurtle);
|
|
132
141
|
}
|
|
133
142
|
}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { AnyConfig } from '../config.js';
|
|
2
|
+
import GridData from '../grid.js';
|
|
3
|
+
import NumberSymbol from './numberSymbol.js';
|
|
4
|
+
export default class FocusSymbol extends NumberSymbol {
|
|
5
|
+
private static readonly CONFIGS;
|
|
6
|
+
private static readonly EXAMPLE_GRID;
|
|
7
|
+
/**
|
|
8
|
+
* **Focus Numbers count directly adjacent cells of the same color**
|
|
9
|
+
* @param x - The x-coordinate of the symbol.
|
|
10
|
+
* @param y - The y-coordinate of the symbol.
|
|
11
|
+
* @param number - The focus number.
|
|
12
|
+
*/
|
|
13
|
+
constructor(x: number, y: number, number: number);
|
|
14
|
+
get id(): string;
|
|
15
|
+
get placementStep(): number;
|
|
16
|
+
get explanation(): string;
|
|
17
|
+
get configs(): readonly AnyConfig[] | null;
|
|
18
|
+
createExampleGrid(): GridData;
|
|
19
|
+
countTiles(grid: GridData): {
|
|
20
|
+
completed: number;
|
|
21
|
+
possible: number;
|
|
22
|
+
};
|
|
23
|
+
copyWith({ x, y, number, }: {
|
|
24
|
+
x?: number;
|
|
25
|
+
y?: number;
|
|
26
|
+
number?: number;
|
|
27
|
+
}): this;
|
|
28
|
+
withNumber(number: number): this;
|
|
29
|
+
}
|
|
30
|
+
export declare const instance: FocusSymbol;
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
import { ConfigType } from '../config.js';
|
|
2
|
+
import GridData from '../grid.js';
|
|
3
|
+
import { Color } from '../primitives.js';
|
|
4
|
+
import NumberSymbol from './numberSymbol.js';
|
|
5
|
+
const OFFSETS = [
|
|
6
|
+
[0, -1],
|
|
7
|
+
[1, 0],
|
|
8
|
+
[0, 1],
|
|
9
|
+
[-1, 0],
|
|
10
|
+
];
|
|
11
|
+
class FocusSymbol extends NumberSymbol {
|
|
12
|
+
/**
|
|
13
|
+
* **Focus Numbers count directly adjacent cells of the same color**
|
|
14
|
+
* @param x - The x-coordinate of the symbol.
|
|
15
|
+
* @param y - The y-coordinate of the symbol.
|
|
16
|
+
* @param number - The focus number.
|
|
17
|
+
*/
|
|
18
|
+
constructor(x, y, number) {
|
|
19
|
+
super(x, y, number);
|
|
20
|
+
}
|
|
21
|
+
get id() {
|
|
22
|
+
return `focus`;
|
|
23
|
+
}
|
|
24
|
+
get placementStep() {
|
|
25
|
+
return 1;
|
|
26
|
+
}
|
|
27
|
+
get explanation() {
|
|
28
|
+
return '*Focus Numbers* count directly adjacent cells of the same color';
|
|
29
|
+
}
|
|
30
|
+
get configs() {
|
|
31
|
+
return FocusSymbol.CONFIGS;
|
|
32
|
+
}
|
|
33
|
+
createExampleGrid() {
|
|
34
|
+
return FocusSymbol.EXAMPLE_GRID;
|
|
35
|
+
}
|
|
36
|
+
countTiles(grid) {
|
|
37
|
+
if (Math.floor(this.x) !== this.x || Math.floor(this.y) !== this.y)
|
|
38
|
+
return { completed: 0, possible: Number.MAX_SAFE_INTEGER };
|
|
39
|
+
const color = grid.getTile(this.x, this.y).color;
|
|
40
|
+
if (color === Color.Gray)
|
|
41
|
+
return { completed: 0, possible: Number.MAX_SAFE_INTEGER };
|
|
42
|
+
let gray = 0;
|
|
43
|
+
let same = 0;
|
|
44
|
+
const visited = [];
|
|
45
|
+
for (const [dx, dy] of OFFSETS) {
|
|
46
|
+
const x = this.x + dx;
|
|
47
|
+
const y = this.y + dy;
|
|
48
|
+
if (grid.wrapAround.value) {
|
|
49
|
+
const pos = grid.toArrayCoordinates(x, y);
|
|
50
|
+
if (visited.some(v => v.x === pos.x && v.y === pos.y))
|
|
51
|
+
continue;
|
|
52
|
+
visited.push(pos);
|
|
53
|
+
}
|
|
54
|
+
const tile = grid.getTile(x, y);
|
|
55
|
+
if (!tile.exists)
|
|
56
|
+
continue;
|
|
57
|
+
if (tile.color === Color.Gray)
|
|
58
|
+
gray++;
|
|
59
|
+
else if (tile.color === color)
|
|
60
|
+
same++;
|
|
61
|
+
}
|
|
62
|
+
return { completed: same, possible: same + gray };
|
|
63
|
+
}
|
|
64
|
+
copyWith({ x, y, number, }) {
|
|
65
|
+
return new FocusSymbol(x ?? this.x, y ?? this.y, number ?? this.number);
|
|
66
|
+
}
|
|
67
|
+
withNumber(number) {
|
|
68
|
+
return this.copyWith({ number });
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
Object.defineProperty(FocusSymbol, "CONFIGS", {
|
|
72
|
+
enumerable: true,
|
|
73
|
+
configurable: true,
|
|
74
|
+
writable: true,
|
|
75
|
+
value: Object.freeze([
|
|
76
|
+
{
|
|
77
|
+
type: ConfigType.Number,
|
|
78
|
+
default: 0,
|
|
79
|
+
field: 'x',
|
|
80
|
+
description: 'X',
|
|
81
|
+
configurable: false,
|
|
82
|
+
},
|
|
83
|
+
{
|
|
84
|
+
type: ConfigType.Number,
|
|
85
|
+
default: 0,
|
|
86
|
+
field: 'y',
|
|
87
|
+
description: 'Y',
|
|
88
|
+
configurable: false,
|
|
89
|
+
},
|
|
90
|
+
{
|
|
91
|
+
type: ConfigType.Number,
|
|
92
|
+
default: 1,
|
|
93
|
+
field: 'number',
|
|
94
|
+
description: 'Number',
|
|
95
|
+
configurable: true,
|
|
96
|
+
},
|
|
97
|
+
])
|
|
98
|
+
});
|
|
99
|
+
Object.defineProperty(FocusSymbol, "EXAMPLE_GRID", {
|
|
100
|
+
enumerable: true,
|
|
101
|
+
configurable: true,
|
|
102
|
+
writable: true,
|
|
103
|
+
value: Object.freeze(GridData.create(['wwwww', 'bbbbw', 'wwbbw', 'wwwww']).withSymbols([
|
|
104
|
+
new FocusSymbol(0, 0, 1),
|
|
105
|
+
new FocusSymbol(4, 1, 2),
|
|
106
|
+
new FocusSymbol(1, 3, 3),
|
|
107
|
+
]))
|
|
108
|
+
});
|
|
109
|
+
export default FocusSymbol;
|
|
110
|
+
export const instance = new FocusSymbol(0, 0, 1);
|
|
@@ -5,7 +5,7 @@ export default class MinesweeperSymbol extends NumberSymbol {
|
|
|
5
5
|
private static readonly CONFIGS;
|
|
6
6
|
private static readonly EXAMPLE_GRID;
|
|
7
7
|
/**
|
|
8
|
-
* **Minesweeper
|
|
8
|
+
* **Minesweeper Numbers count opposite cells in 8 adjacent spaces**
|
|
9
9
|
*
|
|
10
10
|
* @param x - The x-coordinate of the symbol.
|
|
11
11
|
* @param y - The y-coordinate of the symbol.
|
|
@@ -4,7 +4,7 @@ import { Color } from '../primitives.js';
|
|
|
4
4
|
import NumberSymbol from './numberSymbol.js';
|
|
5
5
|
class MinesweeperSymbol extends NumberSymbol {
|
|
6
6
|
/**
|
|
7
|
-
* **Minesweeper
|
|
7
|
+
* **Minesweeper Numbers count opposite cells in 8 adjacent spaces**
|
|
8
8
|
*
|
|
9
9
|
* @param x - The x-coordinate of the symbol.
|
|
10
10
|
* @param y - The y-coordinate of the symbol.
|
|
@@ -20,7 +20,7 @@ class MinesweeperSymbol extends NumberSymbol {
|
|
|
20
20
|
return 1;
|
|
21
21
|
}
|
|
22
22
|
get explanation() {
|
|
23
|
-
return `*Minesweeper
|
|
23
|
+
return `*Minesweeper Numbers* count opposite cells in 8 adjacent spaces`;
|
|
24
24
|
}
|
|
25
25
|
get configs() {
|
|
26
26
|
return MinesweeperSymbol.CONFIGS;
|
|
@@ -36,10 +36,17 @@ class MinesweeperSymbol extends NumberSymbol {
|
|
|
36
36
|
return { completed: 0, possible: Number.MAX_SAFE_INTEGER };
|
|
37
37
|
let gray = 0;
|
|
38
38
|
let opposite = 0;
|
|
39
|
+
const visited = [];
|
|
39
40
|
for (let y = this.y - 1; y <= this.y + 1; y++) {
|
|
40
41
|
for (let x = this.x - 1; x <= this.x + 1; x++) {
|
|
41
42
|
if (x === this.x && y === this.y)
|
|
42
43
|
continue;
|
|
44
|
+
if (grid.wrapAround.value) {
|
|
45
|
+
const pos = grid.toArrayCoordinates(x, y);
|
|
46
|
+
if (visited.some(v => v.x === pos.x && v.y === pos.y))
|
|
47
|
+
continue;
|
|
48
|
+
visited.push(pos);
|
|
49
|
+
}
|
|
43
50
|
const tile = grid.getTile(x, y);
|
|
44
51
|
if (!tile.exists)
|
|
45
52
|
continue;
|
|
@@ -2,6 +2,7 @@ export { instance as AreaNumberSymbol } from './areaNumberSymbol.js';
|
|
|
2
2
|
export { instance as CustomIconSymbol } from './customIconSymbol.js';
|
|
3
3
|
export { instance as CustomTextSymbol } from './customTextSymbol.js';
|
|
4
4
|
export { instance as DartSymbol } from './dartSymbol.js';
|
|
5
|
+
export { instance as FocusSymbol } from './focusSymbol.js';
|
|
5
6
|
export { instance as GalaxySymbol } from './galaxySymbol.js';
|
|
6
7
|
export { instance as HiddenSymbol } from './hiddenSymbol.js';
|
|
7
8
|
export { instance as LetterSymbol } from './letterSymbol.js';
|
|
@@ -6,6 +6,7 @@ export { instance as AreaNumberSymbol } from './areaNumberSymbol.js';
|
|
|
6
6
|
export { instance as CustomIconSymbol } from './customIconSymbol.js';
|
|
7
7
|
export { instance as CustomTextSymbol } from './customTextSymbol.js';
|
|
8
8
|
export { instance as DartSymbol } from './dartSymbol.js';
|
|
9
|
+
export { instance as FocusSymbol } from './focusSymbol.js';
|
|
9
10
|
export { instance as GalaxySymbol } from './galaxySymbol.js';
|
|
10
11
|
export { instance as HiddenSymbol } from './hiddenSymbol.js';
|
|
11
12
|
export { instance as LetterSymbol } from './letterSymbol.js';
|
|
@@ -31,19 +31,17 @@ class ViewpointSymbol extends NumberSymbol {
|
|
|
31
31
|
countForColor(grid, color, pos) {
|
|
32
32
|
let minSize = 1;
|
|
33
33
|
let maxSize = 1;
|
|
34
|
-
const
|
|
34
|
+
const visitedColored = array(grid.width, grid.height, (x, y) => x === pos.x && y === pos.y);
|
|
35
35
|
for (const direction of DIRECTIONS) {
|
|
36
|
-
|
|
37
|
-
|
|
36
|
+
grid.iterateDirection(move(pos, direction), direction, tile => tile.color === color, () => {
|
|
37
|
+
minSize++;
|
|
38
|
+
}, visitedColored);
|
|
39
|
+
}
|
|
40
|
+
const visitedAll = array(grid.width, grid.height, (x, y) => x === pos.x && y === pos.y);
|
|
41
|
+
for (const direction of DIRECTIONS) {
|
|
42
|
+
grid.iterateDirection(move(pos, direction), direction, tile => tile.color === color || tile.color === Color.Gray, () => {
|
|
38
43
|
maxSize++;
|
|
39
|
-
|
|
40
|
-
continuous = false;
|
|
41
|
-
}
|
|
42
|
-
else {
|
|
43
|
-
if (continuous)
|
|
44
|
-
minSize++;
|
|
45
|
-
}
|
|
46
|
-
}, visited);
|
|
44
|
+
}, visitedAll);
|
|
47
45
|
}
|
|
48
46
|
return { completed: minSize, possible: maxSize };
|
|
49
47
|
}
|
package/dist/index.d.ts
CHANGED
|
@@ -60,6 +60,7 @@ import UniqueShapeBTModule from './data/solver/backtrack/rules/uniqueShape.js';
|
|
|
60
60
|
import AreaNumberBTModule from './data/solver/backtrack/symbols/areaNumber.js';
|
|
61
61
|
import DartBTModule from './data/solver/backtrack/symbols/dart.js';
|
|
62
62
|
import DirectionLinkerBTModule from './data/solver/backtrack/symbols/directionLinker.js';
|
|
63
|
+
import FocusBTModule from './data/solver/backtrack/symbols/focus.js';
|
|
63
64
|
import GalaxyBTModule from './data/solver/backtrack/symbols/galaxy.js';
|
|
64
65
|
import LetterBTModule from './data/solver/backtrack/symbols/letter.js';
|
|
65
66
|
import LotusBTModule from './data/solver/backtrack/symbols/lotus.js';
|
|
@@ -88,6 +89,7 @@ import CustomSymbol from './data/symbols/customSymbol.js';
|
|
|
88
89
|
import CustomTextSymbol from './data/symbols/customTextSymbol.js';
|
|
89
90
|
import DartSymbol from './data/symbols/dartSymbol.js';
|
|
90
91
|
import DirectionLinkerSymbol from './data/symbols/directionLinkerSymbol.js';
|
|
92
|
+
import FocusSymbol from './data/symbols/focusSymbol.js';
|
|
91
93
|
import GalaxySymbol from './data/symbols/galaxySymbol.js';
|
|
92
94
|
import HiddenSymbol from './data/symbols/hiddenSymbol.js';
|
|
93
95
|
import { allSymbols } from './data/symbols/index.js';
|
|
@@ -102,4 +104,4 @@ import ViewpointSymbol from './data/symbols/viewpointSymbol.js';
|
|
|
102
104
|
import TileData from './data/tile.js';
|
|
103
105
|
import TileConnections from './data/tileConnections.js';
|
|
104
106
|
import validateGrid, { aggregateState, applyFinalOverrides } from './data/validate.js';
|
|
105
|
-
export { ConfigType, configEquals, Configurable, CachedAccess, allEqual, array, directionToRotation, escape, isSameEdge, maxBy, minBy, move, orientationToRotation, resize, unescape, isEventHandler, handlesFinalValidation, handlesGetTile, handlesGridChange, handlesGridResize, handlesSetGrid, invokeSetGrid, handlesSymbolDisplay, handlesSymbolValidation, GridData, NEIGHBOR_OFFSETS, GridConnections, GridZones, Instruction, COMPARISONS, Color, Comparison, DIRECTIONS, Direction, MajorRule, Mode, ORIENTATIONS, Orientation, State, WRAPPINGS, Wrapping, directionToggle, orientationToggle, MetadataSchema, PuzzleSchema, BanPatternRule, CellCountPerZoneRule, CellCountRule, CompletePatternRule, ConnectAllRule, CustomRule, ForesightRule, allRules, LyingSymbolRule, ControlLine, Row, MusicGridRule, MysteryRule, OffByXRule, PerfectionRule, RegionAreaRule, RegionShapeRule, Rule, SameShapeRule, SymbolsPerRegionRule, UndercluedRule, UniqueShapeRule, WrapAroundRule, Serializer, Compressor, CompressorBase, DeflateCompressor, GzipCompressor, StreamCompressor, SerializerBase, SerializerV0, getShapeVariants, normalizeShape, positionsToShape, shapeEquals, tilesToShape, allSolvers, BacktrackSolver, BTModule, BTGridData, BTTile, IntArray2D, colorToBTTile, createOneTileResult, getOppositeColor, BanPatternBTModule, CellCountBTModule, ConnectAllBTModule, RegionAreaBTModule, RegionShapeBTModule, SameShapeBTModule, SymbolsPerRegionBTModule, UniqueShapeBTModule, AreaNumberBTModule, DartBTModule, DirectionLinkerBTModule, GalaxyBTModule, LetterBTModule, LotusBTModule, MinesweeperBTModule, MyopiaBTModule, ViewpointBTModule, EventIteratingSolver, Solver, UniversalSolver, AreaNumberModule, CellCountModule, ConnectAllModule, DartModule, allZ3Modules, LetterModule, MyopiaModule, RegionAreaModule, ViewpointModule, Z3Module, convertDirection, Z3Solver, Z3SolverContext, AreaNumberSymbol, CustomIconSymbol, CustomSymbol, CustomTextSymbol, DartSymbol, DirectionLinkerSymbol, GalaxySymbol, HiddenSymbol, allSymbols, LetterSymbol, LotusSymbol, MinesweeperSymbol, MultiEntrySymbol, MyopiaSymbol, NumberSymbol, Symbol, ViewpointSymbol, TileData, TileConnections, validateGrid, aggregateState, applyFinalOverrides, };
|
|
107
|
+
export { ConfigType, configEquals, Configurable, CachedAccess, allEqual, array, directionToRotation, escape, isSameEdge, maxBy, minBy, move, orientationToRotation, resize, unescape, isEventHandler, handlesFinalValidation, handlesGetTile, handlesGridChange, handlesGridResize, handlesSetGrid, invokeSetGrid, handlesSymbolDisplay, handlesSymbolValidation, GridData, NEIGHBOR_OFFSETS, GridConnections, GridZones, Instruction, COMPARISONS, Color, Comparison, DIRECTIONS, Direction, MajorRule, Mode, ORIENTATIONS, Orientation, State, WRAPPINGS, Wrapping, directionToggle, orientationToggle, MetadataSchema, PuzzleSchema, BanPatternRule, CellCountPerZoneRule, CellCountRule, CompletePatternRule, ConnectAllRule, CustomRule, ForesightRule, allRules, LyingSymbolRule, ControlLine, Row, MusicGridRule, MysteryRule, OffByXRule, PerfectionRule, RegionAreaRule, RegionShapeRule, Rule, SameShapeRule, SymbolsPerRegionRule, UndercluedRule, UniqueShapeRule, WrapAroundRule, Serializer, Compressor, CompressorBase, DeflateCompressor, GzipCompressor, StreamCompressor, SerializerBase, SerializerV0, getShapeVariants, normalizeShape, positionsToShape, shapeEquals, tilesToShape, allSolvers, BacktrackSolver, BTModule, BTGridData, BTTile, IntArray2D, colorToBTTile, createOneTileResult, getOppositeColor, BanPatternBTModule, CellCountBTModule, ConnectAllBTModule, RegionAreaBTModule, RegionShapeBTModule, SameShapeBTModule, SymbolsPerRegionBTModule, UniqueShapeBTModule, AreaNumberBTModule, DartBTModule, DirectionLinkerBTModule, FocusBTModule, GalaxyBTModule, LetterBTModule, LotusBTModule, MinesweeperBTModule, MyopiaBTModule, ViewpointBTModule, EventIteratingSolver, Solver, UniversalSolver, AreaNumberModule, CellCountModule, ConnectAllModule, DartModule, allZ3Modules, LetterModule, MyopiaModule, RegionAreaModule, ViewpointModule, Z3Module, convertDirection, Z3Solver, Z3SolverContext, AreaNumberSymbol, CustomIconSymbol, CustomSymbol, CustomTextSymbol, DartSymbol, DirectionLinkerSymbol, FocusSymbol, GalaxySymbol, HiddenSymbol, allSymbols, LetterSymbol, LotusSymbol, MinesweeperSymbol, MultiEntrySymbol, MyopiaSymbol, NumberSymbol, Symbol, ViewpointSymbol, TileData, TileConnections, validateGrid, aggregateState, applyFinalOverrides, };
|
package/dist/index.js
CHANGED
|
@@ -63,6 +63,7 @@ import UniqueShapeBTModule from './data/solver/backtrack/rules/uniqueShape.js';
|
|
|
63
63
|
import AreaNumberBTModule from './data/solver/backtrack/symbols/areaNumber.js';
|
|
64
64
|
import DartBTModule from './data/solver/backtrack/symbols/dart.js';
|
|
65
65
|
import DirectionLinkerBTModule from './data/solver/backtrack/symbols/directionLinker.js';
|
|
66
|
+
import FocusBTModule from './data/solver/backtrack/symbols/focus.js';
|
|
66
67
|
import GalaxyBTModule from './data/solver/backtrack/symbols/galaxy.js';
|
|
67
68
|
import LetterBTModule from './data/solver/backtrack/symbols/letter.js';
|
|
68
69
|
import LotusBTModule from './data/solver/backtrack/symbols/lotus.js';
|
|
@@ -91,6 +92,7 @@ import CustomSymbol from './data/symbols/customSymbol.js';
|
|
|
91
92
|
import CustomTextSymbol from './data/symbols/customTextSymbol.js';
|
|
92
93
|
import DartSymbol from './data/symbols/dartSymbol.js';
|
|
93
94
|
import DirectionLinkerSymbol from './data/symbols/directionLinkerSymbol.js';
|
|
95
|
+
import FocusSymbol from './data/symbols/focusSymbol.js';
|
|
94
96
|
import GalaxySymbol from './data/symbols/galaxySymbol.js';
|
|
95
97
|
import HiddenSymbol from './data/symbols/hiddenSymbol.js';
|
|
96
98
|
import { allSymbols } from './data/symbols/index.js';
|
|
@@ -105,4 +107,4 @@ import ViewpointSymbol from './data/symbols/viewpointSymbol.js';
|
|
|
105
107
|
import TileData from './data/tile.js';
|
|
106
108
|
import TileConnections from './data/tileConnections.js';
|
|
107
109
|
import validateGrid, { aggregateState, applyFinalOverrides } from './data/validate.js';
|
|
108
|
-
export { ConfigType, configEquals, Configurable, CachedAccess, allEqual, array, directionToRotation, escape, isSameEdge, maxBy, minBy, move, orientationToRotation, resize, unescape, isEventHandler, handlesFinalValidation, handlesGetTile, handlesGridChange, handlesGridResize, handlesSetGrid, invokeSetGrid, handlesSymbolDisplay, handlesSymbolValidation, GridData, NEIGHBOR_OFFSETS, GridConnections, GridZones, Instruction, COMPARISONS, Color, Comparison, DIRECTIONS, Direction, MajorRule, Mode, ORIENTATIONS, Orientation, State, WRAPPINGS, Wrapping, directionToggle, orientationToggle, MetadataSchema, PuzzleSchema, BanPatternRule, CellCountPerZoneRule, CellCountRule, CompletePatternRule, ConnectAllRule, CustomRule, ForesightRule, allRules, LyingSymbolRule, ControlLine, Row, MusicGridRule, MysteryRule, OffByXRule, PerfectionRule, RegionAreaRule, RegionShapeRule, Rule, SameShapeRule, SymbolsPerRegionRule, UndercluedRule, UniqueShapeRule, WrapAroundRule, Serializer, Compressor, CompressorBase, DeflateCompressor, GzipCompressor, StreamCompressor, SerializerBase, SerializerV0, getShapeVariants, normalizeShape, positionsToShape, shapeEquals, tilesToShape, allSolvers, BacktrackSolver, BTModule, BTGridData, BTTile, IntArray2D, colorToBTTile, createOneTileResult, getOppositeColor, BanPatternBTModule, CellCountBTModule, ConnectAllBTModule, RegionAreaBTModule, RegionShapeBTModule, SameShapeBTModule, SymbolsPerRegionBTModule, UniqueShapeBTModule, AreaNumberBTModule, DartBTModule, DirectionLinkerBTModule, GalaxyBTModule, LetterBTModule, LotusBTModule, MinesweeperBTModule, MyopiaBTModule, ViewpointBTModule, EventIteratingSolver, Solver, UniversalSolver, AreaNumberModule, CellCountModule, ConnectAllModule, DartModule, allZ3Modules, LetterModule, MyopiaModule, RegionAreaModule, ViewpointModule, Z3Module, convertDirection, Z3Solver, Z3SolverContext, AreaNumberSymbol, CustomIconSymbol, CustomSymbol, CustomTextSymbol, DartSymbol, DirectionLinkerSymbol, GalaxySymbol, HiddenSymbol, allSymbols, LetterSymbol, LotusSymbol, MinesweeperSymbol, MultiEntrySymbol, MyopiaSymbol, NumberSymbol, Symbol, ViewpointSymbol, TileData, TileConnections, validateGrid, aggregateState, applyFinalOverrides, };
|
|
110
|
+
export { ConfigType, configEquals, Configurable, CachedAccess, allEqual, array, directionToRotation, escape, isSameEdge, maxBy, minBy, move, orientationToRotation, resize, unescape, isEventHandler, handlesFinalValidation, handlesGetTile, handlesGridChange, handlesGridResize, handlesSetGrid, invokeSetGrid, handlesSymbolDisplay, handlesSymbolValidation, GridData, NEIGHBOR_OFFSETS, GridConnections, GridZones, Instruction, COMPARISONS, Color, Comparison, DIRECTIONS, Direction, MajorRule, Mode, ORIENTATIONS, Orientation, State, WRAPPINGS, Wrapping, directionToggle, orientationToggle, MetadataSchema, PuzzleSchema, BanPatternRule, CellCountPerZoneRule, CellCountRule, CompletePatternRule, ConnectAllRule, CustomRule, ForesightRule, allRules, LyingSymbolRule, ControlLine, Row, MusicGridRule, MysteryRule, OffByXRule, PerfectionRule, RegionAreaRule, RegionShapeRule, Rule, SameShapeRule, SymbolsPerRegionRule, UndercluedRule, UniqueShapeRule, WrapAroundRule, Serializer, Compressor, CompressorBase, DeflateCompressor, GzipCompressor, StreamCompressor, SerializerBase, SerializerV0, getShapeVariants, normalizeShape, positionsToShape, shapeEquals, tilesToShape, allSolvers, BacktrackSolver, BTModule, BTGridData, BTTile, IntArray2D, colorToBTTile, createOneTileResult, getOppositeColor, BanPatternBTModule, CellCountBTModule, ConnectAllBTModule, RegionAreaBTModule, RegionShapeBTModule, SameShapeBTModule, SymbolsPerRegionBTModule, UniqueShapeBTModule, AreaNumberBTModule, DartBTModule, DirectionLinkerBTModule, FocusBTModule, GalaxyBTModule, LetterBTModule, LotusBTModule, MinesweeperBTModule, MyopiaBTModule, ViewpointBTModule, EventIteratingSolver, Solver, UniversalSolver, AreaNumberModule, CellCountModule, ConnectAllModule, DartModule, allZ3Modules, LetterModule, MyopiaModule, RegionAreaModule, ViewpointModule, Z3Module, convertDirection, Z3Solver, Z3SolverContext, AreaNumberSymbol, CustomIconSymbol, CustomSymbol, CustomTextSymbol, DartSymbol, DirectionLinkerSymbol, FocusSymbol, GalaxySymbol, HiddenSymbol, allSymbols, LetterSymbol, LotusSymbol, MinesweeperSymbol, MultiEntrySymbol, MyopiaSymbol, NumberSymbol, Symbol, ViewpointSymbol, TileData, TileConnections, validateGrid, aggregateState, applyFinalOverrides, };
|