@logic-pad/core 0.25.3 → 0.26.1
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 +31 -104
- package/dist/src/data/rules/offByXRule.js +2 -0
- package/dist/src/data/solver/allSolvers.js +0 -2
- package/dist/src/data/solver/auto/autoSolver.d.ts +2 -1
- package/dist/src/data/solver/auto/autoSolver.js +18 -19
- package/dist/src/data/solver/backtrack/backtrackSolver.d.ts +3 -1
- package/dist/src/data/solver/backtrack/backtrackSolver.js +4 -2
- package/dist/src/data/solver/backtrack/backtrackWorker.js +6 -2
- package/dist/src/data/solver/backtrack/data.d.ts +1 -0
- package/dist/src/data/solver/backtrack/data.js +43 -0
- package/dist/src/data/solver/backtrack/symbols/areaNumber.js +4 -1
- package/dist/src/data/solver/backtrack/symbols/letter.js +6 -1
- package/dist/src/data/solver/cspuz/cspuzSolver.d.ts +2 -1
- package/dist/src/data/solver/cspuz/cspuzSolver.js +53 -19
- package/dist/src/data/solver/cspuz/jsonify.js +4 -0
- package/dist/src/data/solver/solver.d.ts +2 -1
- package/dist/src/data/solver/solver.js +8 -7
- package/dist/src/data/solver/universal/universalSolver.d.ts +0 -1
- package/dist/src/data/solver/universal/universalSolver.js +0 -7
- package/dist/src/data/symbols/areaNumberSymbol.d.ts +1 -1
- package/dist/src/data/symbols/areaNumberSymbol.js +2 -0
- package/dist/src/data/symbols/everyLetterSymbol.js +2 -0
- package/dist/src/data/symbols/houseSymbol.d.ts +1 -1
- package/dist/src/data/symbols/houseSymbol.js +2 -0
- package/dist/src/data/symbols/letterSymbol.js +2 -0
- package/dist/src/data/symbols/numberSymbol.d.ts +1 -1
- package/dist/src/data/symbols/numberSymbol.js +4 -1
- package/dist/src/data/symbols/symbol.d.ts +5 -0
- package/dist/src/data/symbols/symbol.js +32 -0
- package/dist/src/data/symbols/symbols.gen.d.ts +1 -0
- package/dist/src/data/symbols/symbols.gen.js +1 -0
- package/dist/src/data/symbols/unsupportedSymbol.d.ts +23 -0
- package/dist/src/data/symbols/unsupportedSymbol.js +47 -0
- package/dist/src/index.d.ts +3 -15
- package/dist/src/index.js +3 -15
- package/package.json +1 -3
- package/dist/src/data/solver/z3/modules/areaNumberModule.d.ts +0 -9
- package/dist/src/data/solver/z3/modules/areaNumberModule.js +0 -27
- package/dist/src/data/solver/z3/modules/cellCountModule.d.ts +0 -9
- package/dist/src/data/solver/z3/modules/cellCountModule.js +0 -51
- package/dist/src/data/solver/z3/modules/connectAllModule.d.ts +0 -9
- package/dist/src/data/solver/z3/modules/connectAllModule.js +0 -24
- package/dist/src/data/solver/z3/modules/dartModule.d.ts +0 -9
- package/dist/src/data/solver/z3/modules/dartModule.js +0 -61
- package/dist/src/data/solver/z3/modules/index.d.ts +0 -3
- package/dist/src/data/solver/z3/modules/index.js +0 -10
- package/dist/src/data/solver/z3/modules/letterModule.d.ts +0 -9
- package/dist/src/data/solver/z3/modules/letterModule.js +0 -33
- package/dist/src/data/solver/z3/modules/modules.gen.d.ts +0 -8
- package/dist/src/data/solver/z3/modules/modules.gen.js +0 -12
- package/dist/src/data/solver/z3/modules/myopiaModule.d.ts +0 -9
- package/dist/src/data/solver/z3/modules/myopiaModule.js +0 -56
- package/dist/src/data/solver/z3/modules/regionAreaModule.d.ts +0 -9
- package/dist/src/data/solver/z3/modules/regionAreaModule.js +0 -40
- package/dist/src/data/solver/z3/modules/viewpointModule.d.ts +0 -9
- package/dist/src/data/solver/z3/modules/viewpointModule.js +0 -29
- package/dist/src/data/solver/z3/modules/z3Module.d.ts +0 -7
- package/dist/src/data/solver/z3/modules/z3Module.js +0 -3
- package/dist/src/data/solver/z3/utils.d.ts +0 -2
- package/dist/src/data/solver/z3/utils.js +0 -26
- package/dist/src/data/solver/z3/z3Solver.d.ts +0 -12
- package/dist/src/data/solver/z3/z3Solver.js +0 -123
- package/dist/src/data/solver/z3/z3SolverContext.d.ts +0 -13
- package/dist/src/data/solver/z3/z3SolverContext.js +0 -40
|
@@ -8,9 +8,7 @@
|
|
|
8
8
|
declare global {
|
|
9
9
|
// Generated by dts-bundle-generator v9.5.1
|
|
10
10
|
|
|
11
|
-
import { RegionConstrainer, SymbolGrid } from 'grilops';
|
|
12
11
|
import { PuzzleData as PuzzleData$1 } from 'logic-pad-solver-core';
|
|
13
|
-
import { Optimize, Solver as Solver$1, Z3LowLevel } from 'z3-solver';
|
|
14
12
|
import { z } from 'zod';
|
|
15
13
|
|
|
16
14
|
interface Position$1 {
|
|
@@ -454,6 +452,11 @@ declare global {
|
|
|
454
452
|
withX(x: number): this;
|
|
455
453
|
withY(y: number): this;
|
|
456
454
|
withPosition(x: number, y: number): this;
|
|
455
|
+
/**
|
|
456
|
+
* For symbols that can be placed between tiles, this method implements the default validation logic,
|
|
457
|
+
* which requires all tiles touching the symbol to be either gray or of the same color.
|
|
458
|
+
*/
|
|
459
|
+
protected validateSubtilePlacement(grid: GridData): boolean;
|
|
457
460
|
}
|
|
458
461
|
export declare class TileData {
|
|
459
462
|
readonly exists: boolean;
|
|
@@ -2388,7 +2391,7 @@ declare global {
|
|
|
2388
2391
|
*
|
|
2389
2392
|
* @param instructionId The unique identifier of the instruction.
|
|
2390
2393
|
*/
|
|
2391
|
-
isInstructionSupported(
|
|
2394
|
+
isInstructionSupported(_grid: GridData, instruction: Instruction): boolean;
|
|
2392
2395
|
/**
|
|
2393
2396
|
* Check if the solver supports the given grid. This methid is frequently called when the user changes the grid, and
|
|
2394
2397
|
* the result is used to enable or disable the "Solve" button.
|
|
@@ -2410,7 +2413,7 @@ declare global {
|
|
|
2410
2413
|
readonly supportsCancellation = true;
|
|
2411
2414
|
private static readonly nonAdditiveInstructions;
|
|
2412
2415
|
isGridSupported(grid: GridData): boolean;
|
|
2413
|
-
isInstructionSupported(
|
|
2416
|
+
isInstructionSupported(grid: GridData, instruction: Instruction): boolean;
|
|
2414
2417
|
protected isEnvironmentSupported(): Promise<boolean>;
|
|
2415
2418
|
private fillSolution;
|
|
2416
2419
|
private fixGrid;
|
|
@@ -2437,7 +2440,7 @@ declare global {
|
|
|
2437
2440
|
readonly description =
|
|
2438
2441
|
'Solves puzzles pretty fast using backtracking with optimizations. Support most rules and symbols (including underclued).';
|
|
2439
2442
|
protected createWorker(): Worker;
|
|
2440
|
-
isInstructionSupported(
|
|
2443
|
+
isInstructionSupported(_grid: GridData, instruction: Instruction): boolean;
|
|
2441
2444
|
}
|
|
2442
2445
|
export declare enum BTTile {
|
|
2443
2446
|
Empty = 0,
|
|
@@ -2494,6 +2497,10 @@ declare global {
|
|
|
2494
2497
|
pos: Position$1,
|
|
2495
2498
|
score?: number | undefined
|
|
2496
2499
|
): CheckResult;
|
|
2500
|
+
export declare function checkSubtilePlacement(
|
|
2501
|
+
grid: BTGridData,
|
|
2502
|
+
pos: Position$1
|
|
2503
|
+
): CheckResult | false | undefined;
|
|
2497
2504
|
export declare class BanPatternBTModule extends BTModule {
|
|
2498
2505
|
instr: BanPatternRule;
|
|
2499
2506
|
constructor(instr: BanPatternRule);
|
|
@@ -2555,7 +2562,7 @@ declare global {
|
|
|
2555
2562
|
abstract countTiles(grid: GridData): {
|
|
2556
2563
|
completed: number;
|
|
2557
2564
|
possible: number;
|
|
2558
|
-
};
|
|
2565
|
+
} | null;
|
|
2559
2566
|
validateSymbol(grid: GridData): State;
|
|
2560
2567
|
withNumber(number: number): this;
|
|
2561
2568
|
}
|
|
@@ -2578,7 +2585,7 @@ declare global {
|
|
|
2578
2585
|
countTiles(grid: GridData): {
|
|
2579
2586
|
completed: number;
|
|
2580
2587
|
possible: number;
|
|
2581
|
-
};
|
|
2588
|
+
} | null;
|
|
2582
2589
|
copyWith({
|
|
2583
2590
|
x,
|
|
2584
2591
|
y,
|
|
@@ -2966,7 +2973,7 @@ declare global {
|
|
|
2966
2973
|
'A blazingly fast WebAssembly solver that supports most rules and symbols (including underclued).';
|
|
2967
2974
|
protected createWorker(): Worker;
|
|
2968
2975
|
isGridSupported(grid: GridData): boolean;
|
|
2969
|
-
isInstructionSupported(
|
|
2976
|
+
isInstructionSupported(grid: GridData, instruction: Instruction): boolean;
|
|
2970
2977
|
isEnvironmentSupported(): Promise<boolean>;
|
|
2971
2978
|
}
|
|
2972
2979
|
export declare function gridToJson(grid: GridData): PuzzleData$1;
|
|
@@ -2976,101 +2983,6 @@ declare global {
|
|
|
2976
2983
|
readonly description =
|
|
2977
2984
|
'A backtracking solver that supports all rules and symbols (including underclued) but is less optimized.';
|
|
2978
2985
|
protected createWorker(): Worker;
|
|
2979
|
-
isInstructionSupported(instructionId: string): boolean;
|
|
2980
|
-
}
|
|
2981
|
-
export declare class Z3SolverContext<
|
|
2982
|
-
Name extends string,
|
|
2983
|
-
const Core extends Solver$1<Name> | Optimize<Name> =
|
|
2984
|
-
| Solver$1<Name>
|
|
2985
|
-
| Optimize<Name>,
|
|
2986
|
-
> {
|
|
2987
|
-
readonly grid: SymbolGrid<Name, Core>;
|
|
2988
|
-
private _regionConstrainer;
|
|
2989
|
-
constructor(grid: SymbolGrid<Name, Core>);
|
|
2990
|
-
get solver(): Core;
|
|
2991
|
-
get lattice(): import('grilops').Lattice;
|
|
2992
|
-
get symbolSet(): import('grilops').SymbolSet;
|
|
2993
|
-
get ctx(): import('z3-solver').Context<Name>;
|
|
2994
|
-
get z3(): Z3LowLevel['Z3'];
|
|
2995
|
-
get regionConstrainer(): RegionConstrainer<Name, Core>;
|
|
2996
|
-
}
|
|
2997
|
-
export declare abstract class Z3Module {
|
|
2998
|
-
abstract get id(): string;
|
|
2999
|
-
abstract encode<Name extends string>(
|
|
3000
|
-
grid: GridData,
|
|
3001
|
-
ctx: Z3SolverContext<Name>
|
|
3002
|
-
): void;
|
|
3003
|
-
}
|
|
3004
|
-
export declare class AreaNumberModule extends Z3Module {
|
|
3005
|
-
readonly id: string;
|
|
3006
|
-
encode<Name extends string>(
|
|
3007
|
-
grid: GridData,
|
|
3008
|
-
ctx: Z3SolverContext<Name, Solver$1<Name> | Optimize<Name>>
|
|
3009
|
-
): void;
|
|
3010
|
-
}
|
|
3011
|
-
export declare class CellCountModule extends Z3Module {
|
|
3012
|
-
readonly id: string;
|
|
3013
|
-
encode<Name extends string>(
|
|
3014
|
-
grid: GridData,
|
|
3015
|
-
ctx: Z3SolverContext<Name, Solver$1<Name> | Optimize<Name>>
|
|
3016
|
-
): void;
|
|
3017
|
-
}
|
|
3018
|
-
export declare class ConnectAllModule extends Z3Module {
|
|
3019
|
-
readonly id: string;
|
|
3020
|
-
encode<Name extends string>(
|
|
3021
|
-
grid: GridData,
|
|
3022
|
-
ctx: Z3SolverContext<Name, Solver$1<Name> | Optimize<Name>>
|
|
3023
|
-
): void;
|
|
3024
|
-
}
|
|
3025
|
-
export declare class DartModule extends Z3Module {
|
|
3026
|
-
readonly id: string;
|
|
3027
|
-
encode<Name extends string>(
|
|
3028
|
-
grid: GridData,
|
|
3029
|
-
ctx: Z3SolverContext<Name, Solver$1<Name> | Optimize<Name>>
|
|
3030
|
-
): void;
|
|
3031
|
-
}
|
|
3032
|
-
export declare const allZ3Modules: Map<string, Z3Module>;
|
|
3033
|
-
export declare class LetterModule extends Z3Module {
|
|
3034
|
-
readonly id: string;
|
|
3035
|
-
encode<Name extends string>(
|
|
3036
|
-
grid: GridData,
|
|
3037
|
-
ctx: Z3SolverContext<Name, Solver$1<Name> | Optimize<Name>>
|
|
3038
|
-
): void;
|
|
3039
|
-
}
|
|
3040
|
-
export declare class MyopiaModule extends Z3Module {
|
|
3041
|
-
readonly id: string;
|
|
3042
|
-
encode<Name extends string>(
|
|
3043
|
-
grid: GridData,
|
|
3044
|
-
ctx: Z3SolverContext<Name, Solver$1<Name> | Optimize<Name>>
|
|
3045
|
-
): void;
|
|
3046
|
-
}
|
|
3047
|
-
export declare class RegionAreaModule extends Z3Module {
|
|
3048
|
-
readonly id: string;
|
|
3049
|
-
encode<Name extends string>(
|
|
3050
|
-
grid: GridData,
|
|
3051
|
-
ctx: Z3SolverContext<Name, Solver$1<Name> | Optimize<Name>>
|
|
3052
|
-
): void;
|
|
3053
|
-
}
|
|
3054
|
-
export declare class ViewpointModule extends Z3Module {
|
|
3055
|
-
readonly id: string;
|
|
3056
|
-
encode<Name extends string>(
|
|
3057
|
-
grid: GridData,
|
|
3058
|
-
ctx: Z3SolverContext<Name, Solver$1<Name> | Optimize<Name>>
|
|
3059
|
-
): void;
|
|
3060
|
-
}
|
|
3061
|
-
export declare function convertDirection(
|
|
3062
|
-
direction: Orientation | Direction
|
|
3063
|
-
): import('grilops').Direction;
|
|
3064
|
-
export declare class Z3Solver extends Solver {
|
|
3065
|
-
readonly id = 'z3';
|
|
3066
|
-
readonly author = 'Lysine';
|
|
3067
|
-
readonly description =
|
|
3068
|
-
'(Obsolete) A WebAssembly solver that supports a limited set of rules and symbols.';
|
|
3069
|
-
readonly supportsCancellation = false;
|
|
3070
|
-
protected isEnvironmentSupported(): Promise<boolean>;
|
|
3071
|
-
solve(grid: GridData): AsyncGenerator<GridData | null>;
|
|
3072
|
-
isInstructionSupported(instructionId: string): boolean;
|
|
3073
|
-
isGridSupported(grid: GridData): boolean;
|
|
3074
2986
|
}
|
|
3075
2987
|
export declare abstract class CustomSymbol
|
|
3076
2988
|
extends Symbol$1
|
|
@@ -3282,7 +3194,7 @@ declare global {
|
|
|
3282
3194
|
countTiles(grid: GridData): {
|
|
3283
3195
|
completed: number;
|
|
3284
3196
|
possible: number;
|
|
3285
|
-
};
|
|
3197
|
+
} | null;
|
|
3286
3198
|
copyWith({
|
|
3287
3199
|
x,
|
|
3288
3200
|
y,
|
|
@@ -3294,6 +3206,21 @@ declare global {
|
|
|
3294
3206
|
}): this;
|
|
3295
3207
|
}
|
|
3296
3208
|
export declare const allSymbols: Map<string, Symbol$1>;
|
|
3209
|
+
/**
|
|
3210
|
+
* A marker for symbols not supported by the current solver.
|
|
3211
|
+
* Solvers should count these symbols in the symbols per region rule but otherwise ignore them.
|
|
3212
|
+
*/
|
|
3213
|
+
export declare class UnsupportedSymbol extends Symbol$1 {
|
|
3214
|
+
readonly title = 'Unsupported Symbol';
|
|
3215
|
+
private static readonly CONFIGS;
|
|
3216
|
+
private static readonly EXAMPLE_GRID;
|
|
3217
|
+
get id(): string;
|
|
3218
|
+
get explanation(): string;
|
|
3219
|
+
get configs(): readonly AnyConfig[] | null;
|
|
3220
|
+
createExampleGrid(): GridData;
|
|
3221
|
+
validateSymbol(_grid: GridData, _solution: GridData | null): State;
|
|
3222
|
+
copyWith({ x, y }: { x?: number; y?: number }): this;
|
|
3223
|
+
}
|
|
3297
3224
|
export declare function aggregateState(
|
|
3298
3225
|
rules: readonly RuleState[],
|
|
3299
3226
|
grid: GridData,
|
|
@@ -90,6 +90,8 @@ export default class OffByXRule extends Rule {
|
|
|
90
90
|
onSymbolValidation(grid, symbol, _validator) {
|
|
91
91
|
if (symbol instanceof NumberSymbol) {
|
|
92
92
|
const counts = symbol.countTiles(grid);
|
|
93
|
+
if (counts === null)
|
|
94
|
+
return State.Error;
|
|
93
95
|
if (counts.completed > symbol.number + this.number ||
|
|
94
96
|
counts.possible < symbol.number - this.number ||
|
|
95
97
|
(counts.completed > symbol.number - this.number &&
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import UniversalSolver from './universal/universalSolver.js';
|
|
2
2
|
import BacktrackSolver from './backtrack/backtrackSolver.js';
|
|
3
|
-
import Z3Solver from './z3/z3Solver.js';
|
|
4
3
|
import CspuzSolver from './cspuz/cspuzSolver.js';
|
|
5
4
|
import AutoSolver from './auto/autoSolver.js';
|
|
6
5
|
const allSolvers = new Map();
|
|
@@ -11,5 +10,4 @@ register(new AutoSolver());
|
|
|
11
10
|
register(new CspuzSolver());
|
|
12
11
|
register(new BacktrackSolver());
|
|
13
12
|
register(new UniversalSolver());
|
|
14
|
-
register(new Z3Solver());
|
|
15
13
|
export { allSolvers };
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import GridData from '../../grid.js';
|
|
2
2
|
import Solver from '../solver.js';
|
|
3
|
+
import Instruction from '../../instruction.js';
|
|
3
4
|
export default class AutoSolver extends Solver {
|
|
4
5
|
readonly id = "auto";
|
|
5
6
|
readonly author = "various contributors";
|
|
@@ -7,7 +8,7 @@ export default class AutoSolver extends Solver {
|
|
|
7
8
|
readonly supportsCancellation = true;
|
|
8
9
|
private static readonly nonAdditiveInstructions;
|
|
9
10
|
isGridSupported(grid: GridData): boolean;
|
|
10
|
-
isInstructionSupported(
|
|
11
|
+
isInstructionSupported(grid: GridData, instruction: Instruction): boolean;
|
|
11
12
|
protected isEnvironmentSupported(): Promise<boolean>;
|
|
12
13
|
private fillSolution;
|
|
13
14
|
private fixGrid;
|
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
import { Color, State } from '../../primitives.js';
|
|
2
2
|
import { instance as lyingSymbolInstance } from '../../rules/lyingSymbolRule.js';
|
|
3
3
|
import { instance as offByXInstance } from '../../rules/offByXRule.js';
|
|
4
|
-
import { instance as lotusInstance } from '../../symbols/lotusSymbol.js';
|
|
5
|
-
import { instance as galaxyInstance } from '../../symbols/galaxySymbol.js';
|
|
6
4
|
import { instance as wrapAroundInstance } from '../../rules/wrapAroundRule.js';
|
|
7
|
-
import { instance as
|
|
5
|
+
import { instance as areaNumberInstance } from '../../symbols/areaNumberSymbol.js';
|
|
6
|
+
import { instance as letterInstance } from '../../symbols/letterSymbol.js';
|
|
8
7
|
import { allSolvers } from '../allSolvers.js';
|
|
9
8
|
import Solver from '../solver.js';
|
|
10
9
|
import UndercluedRule from '../../rules/undercluedRule.js';
|
|
11
10
|
import validateGrid from '../../validate.js';
|
|
11
|
+
import UnsupportedSymbol from '../../symbols/unsupportedSymbol.js';
|
|
12
12
|
export default class AutoSolver extends Solver {
|
|
13
13
|
id = 'auto';
|
|
14
14
|
author = 'various contributors';
|
|
@@ -18,7 +18,6 @@ export default class AutoSolver extends Solver {
|
|
|
18
18
|
offByXInstance.id,
|
|
19
19
|
lyingSymbolInstance.id,
|
|
20
20
|
wrapAroundInstance.id,
|
|
21
|
-
symbolsPerRegionInstance.id,
|
|
22
21
|
]);
|
|
23
22
|
isGridSupported(grid) {
|
|
24
23
|
for (const solver of allSolvers.values()) {
|
|
@@ -30,11 +29,11 @@ export default class AutoSolver extends Solver {
|
|
|
30
29
|
}
|
|
31
30
|
return false;
|
|
32
31
|
}
|
|
33
|
-
isInstructionSupported(
|
|
32
|
+
isInstructionSupported(grid, instruction) {
|
|
34
33
|
for (const solver of allSolvers.values()) {
|
|
35
34
|
if (solver.id === this.id)
|
|
36
35
|
continue;
|
|
37
|
-
if (solver.isInstructionSupported(
|
|
36
|
+
if (solver.isInstructionSupported(grid, instruction)) {
|
|
38
37
|
return true;
|
|
39
38
|
}
|
|
40
39
|
}
|
|
@@ -113,24 +112,24 @@ export default class AutoSolver extends Solver {
|
|
|
113
112
|
return;
|
|
114
113
|
}
|
|
115
114
|
else {
|
|
116
|
-
|
|
117
|
-
.withRules(rules => rules.filter(r => solver.isInstructionSupported(r
|
|
115
|
+
const undercluedGrid = progressGrid
|
|
116
|
+
.withRules(rules => rules.filter(r => solver.isInstructionSupported(progressGrid, r)))
|
|
118
117
|
.withSymbols(symbols => {
|
|
119
|
-
for (const id of symbols.
|
|
120
|
-
|
|
121
|
-
symbols
|
|
118
|
+
for (const [id, symbolList] of symbols.entries()) {
|
|
119
|
+
symbols.set(id, symbolList.map(symbol => {
|
|
120
|
+
// special handling: do not delete area number and letter symbols as they can be solved
|
|
121
|
+
// underclued even if the solver doesn't fully support them
|
|
122
|
+
if (symbol.id === areaNumberInstance.id ||
|
|
123
|
+
symbol.id === letterInstance.id)
|
|
124
|
+
return symbol;
|
|
125
|
+
if (solver.isInstructionSupported(progressGrid, symbol))
|
|
126
|
+
return symbol;
|
|
127
|
+
return new UnsupportedSymbol(symbol.x, symbol.y);
|
|
128
|
+
}));
|
|
122
129
|
}
|
|
123
130
|
return symbols;
|
|
124
131
|
})
|
|
125
132
|
.addRule(new UndercluedRule());
|
|
126
|
-
if (!solver.isGridSupported(undercluedGrid)) {
|
|
127
|
-
// special case for solvers that support lotus and galaxy symbols but not dual-color placement
|
|
128
|
-
undercluedGrid = undercluedGrid.withSymbols(symbols => {
|
|
129
|
-
symbols.delete(lotusInstance.id);
|
|
130
|
-
symbols.delete(galaxyInstance.id);
|
|
131
|
-
return symbols;
|
|
132
|
-
});
|
|
133
|
-
}
|
|
134
133
|
if (!solver.isGridSupported(undercluedGrid))
|
|
135
134
|
continue;
|
|
136
135
|
const undercluedSolution = await this.solveOne(this.solveWithProgress(solver, progressGrid, undercluedGrid, abortSignal));
|
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
import EventIteratingSolver from '../eventIteratingSolver.js';
|
|
2
|
+
import Instruction from '../../instruction.js';
|
|
3
|
+
import GridData from '../../grid.js';
|
|
2
4
|
export default class BacktrackSolver extends EventIteratingSolver {
|
|
3
5
|
private static readonly supportedInstrs;
|
|
4
6
|
readonly id = "backtrack";
|
|
5
7
|
readonly author = "ALaggyDev";
|
|
6
8
|
readonly description = "Solves puzzles pretty fast using backtracking with optimizations. Support most rules and symbols (including underclued).";
|
|
7
9
|
protected createWorker(): Worker;
|
|
8
|
-
isInstructionSupported(
|
|
10
|
+
isInstructionSupported(_grid: GridData, instruction: Instruction): boolean;
|
|
9
11
|
}
|
|
@@ -15,6 +15,7 @@ import { instance as focusInstance } from '../../symbols/focusSymbol.js';
|
|
|
15
15
|
import { instance as myopiaInstance } from '../../symbols/myopiaSymbol.js';
|
|
16
16
|
import { instance as viewpointInstance } from '../../symbols/viewpointSymbol.js';
|
|
17
17
|
import { instance as connectAllInstance } from '../../rules/connectAllRule.js';
|
|
18
|
+
import { instance as unsupportedInstance } from '../../symbols/unsupportedSymbol.js';
|
|
18
19
|
import EventIteratingSolver from '../eventIteratingSolver.js';
|
|
19
20
|
// eslint-disable-next-line @typescript-eslint/no-unused-expressions
|
|
20
21
|
('vite-apply-code-mod');
|
|
@@ -37,6 +38,7 @@ export default class BacktrackSolver extends EventIteratingSolver {
|
|
|
37
38
|
cellCountInstance.id,
|
|
38
39
|
sameShapeInstance.id,
|
|
39
40
|
uniqueShapeInstance.id,
|
|
41
|
+
unsupportedInstance.id,
|
|
40
42
|
];
|
|
41
43
|
id = 'backtrack';
|
|
42
44
|
author = 'ALaggyDev';
|
|
@@ -46,7 +48,7 @@ export default class BacktrackSolver extends EventIteratingSolver {
|
|
|
46
48
|
type: 'module',
|
|
47
49
|
});
|
|
48
50
|
}
|
|
49
|
-
isInstructionSupported(
|
|
50
|
-
return BacktrackSolver.supportedInstrs.includes(
|
|
51
|
+
isInstructionSupported(_grid, instruction) {
|
|
52
|
+
return BacktrackSolver.supportedInstrs.includes(instruction.id);
|
|
51
53
|
}
|
|
52
54
|
}
|
|
@@ -2,6 +2,7 @@ import { array } from '../../dataHelper.js';
|
|
|
2
2
|
import { Color } from '../../primitives.js';
|
|
3
3
|
import { instance as banPatternInstance, } from '../../rules/banPatternRule.js';
|
|
4
4
|
import { instance as cellCountInstance, } from '../../rules/cellCountRule.js';
|
|
5
|
+
import { instance as connectAllInstance, } from '../../rules/connectAllRule.js';
|
|
5
6
|
import { instance as regionAreaInstance, } from '../../rules/regionAreaRule.js';
|
|
6
7
|
import { instance as sameShapeInstance, } from '../../rules/sameShapeRule.js';
|
|
7
8
|
import { instance as symbolsPerRegionInstance, } from '../../rules/symbolsPerRegionRule.js';
|
|
@@ -17,7 +18,7 @@ import { instance as minesweeperInstance, } from '../../symbols/minesweeperSymbo
|
|
|
17
18
|
import { instance as focusInstance, } from '../../symbols/focusSymbol.js';
|
|
18
19
|
import { instance as myopiaInstance, } from '../../symbols/myopiaSymbol.js';
|
|
19
20
|
import { instance as viewpointInstance, } from '../../symbols/viewpointSymbol.js';
|
|
20
|
-
import { instance as
|
|
21
|
+
import { instance as unsupportedInstance } from '../../symbols/unsupportedSymbol.js';
|
|
21
22
|
import { BTGridData, BTTile } from './data.js';
|
|
22
23
|
import BanPatternBTModule from './rules/banPattern.js';
|
|
23
24
|
import CellCountBTModule from './rules/cellCount.js';
|
|
@@ -79,6 +80,9 @@ function translateToBTGridData(grid) {
|
|
|
79
80
|
else if (id === letterInstance.id) {
|
|
80
81
|
continue;
|
|
81
82
|
}
|
|
83
|
+
else if (id === unsupportedInstance.id) {
|
|
84
|
+
continue;
|
|
85
|
+
}
|
|
82
86
|
if (!module && symbol.necessaryForCompletion)
|
|
83
87
|
throw new Error('Symbol not supported.');
|
|
84
88
|
if (module)
|
|
@@ -104,7 +108,7 @@ function translateToBTGridData(grid) {
|
|
|
104
108
|
}
|
|
105
109
|
else if (rule.id === symbolsPerRegionInstance.id) {
|
|
106
110
|
const allSymbols = [];
|
|
107
|
-
grid.symbols.forEach(symbols => allSymbols.push(...symbols));
|
|
111
|
+
grid.symbols.forEach(symbols => allSymbols.push(...symbols.filter(symbol => symbol.necessaryForCompletion)));
|
|
108
112
|
module = new SymbolsPerRegionBTModule(rule, grid.width, grid.height, allSymbols);
|
|
109
113
|
}
|
|
110
114
|
else if (rule.id === cellCountInstance.id) {
|
|
@@ -44,3 +44,4 @@ export default abstract class BTModule {
|
|
|
44
44
|
export declare function getOppositeColor(color: BTColor): BTColor;
|
|
45
45
|
export declare function colorToBTTile(color: Color): BTTile;
|
|
46
46
|
export declare function createOneTileResult(grid: BTGridData, pos: Position, score?: number | undefined): CheckResult;
|
|
47
|
+
export declare function checkSubtilePlacement(grid: BTGridData, pos: Position): CheckResult | false | undefined;
|
|
@@ -106,3 +106,46 @@ export function createOneTileResult(grid, pos, score = 1) {
|
|
|
106
106
|
const ratings = [{ pos, score }];
|
|
107
107
|
return { tilesNeedCheck, ratings };
|
|
108
108
|
}
|
|
109
|
+
export function checkSubtilePlacement(grid, pos) {
|
|
110
|
+
const minX = Math.floor(pos.x);
|
|
111
|
+
const minY = Math.floor(pos.y);
|
|
112
|
+
if (minX === pos.x && minY === pos.y)
|
|
113
|
+
return undefined;
|
|
114
|
+
const maxX = Math.ceil(pos.x);
|
|
115
|
+
const maxY = Math.ceil(pos.y);
|
|
116
|
+
let color = null;
|
|
117
|
+
let complete = true;
|
|
118
|
+
for (let i = 0; i < 4; i++) {
|
|
119
|
+
const x = i % 2 === 0 ? minX : maxX;
|
|
120
|
+
const y = i < 2 ? minY : maxY;
|
|
121
|
+
if (!grid.isInBound(x, y))
|
|
122
|
+
return false;
|
|
123
|
+
const tile = grid.getTile(x, y);
|
|
124
|
+
if (tile === BTTile.NonExist)
|
|
125
|
+
return false;
|
|
126
|
+
if (tile !== BTTile.Empty) {
|
|
127
|
+
if (color !== null && tile !== color)
|
|
128
|
+
return false;
|
|
129
|
+
color = tile;
|
|
130
|
+
}
|
|
131
|
+
else {
|
|
132
|
+
complete = false;
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
if (complete) {
|
|
136
|
+
return undefined;
|
|
137
|
+
}
|
|
138
|
+
else {
|
|
139
|
+
const tilesNeedCheck = IntArray2D.create(grid.width, grid.height);
|
|
140
|
+
const ratings = [];
|
|
141
|
+
for (let i = 0; i < 4; i++) {
|
|
142
|
+
const x = i % 2 === 0 ? minX : maxX;
|
|
143
|
+
const y = i < 2 ? minY : maxY;
|
|
144
|
+
if (grid.getTile(x, y) === BTTile.Empty) {
|
|
145
|
+
tilesNeedCheck.set(x, y, 1);
|
|
146
|
+
ratings.push({ pos: { x, y }, score: 1 });
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
return { tilesNeedCheck, ratings };
|
|
150
|
+
}
|
|
151
|
+
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import BTModule, { BTTile, IntArray2D, createOneTileResult, } from '../data.js';
|
|
1
|
+
import BTModule, { BTTile, checkSubtilePlacement, IntArray2D, createOneTileResult, } from '../data.js';
|
|
2
2
|
export default class AreaNumberBTModule extends BTModule {
|
|
3
3
|
instr;
|
|
4
4
|
constructor(instr) {
|
|
@@ -6,6 +6,9 @@ export default class AreaNumberBTModule extends BTModule {
|
|
|
6
6
|
this.instr = instr;
|
|
7
7
|
}
|
|
8
8
|
checkGlobal(grid) {
|
|
9
|
+
const checkResult = checkSubtilePlacement(grid, this.instr);
|
|
10
|
+
if (checkResult !== undefined)
|
|
11
|
+
return checkResult;
|
|
9
12
|
const thisX = Math.floor(this.instr.x);
|
|
10
13
|
const thisY = Math.floor(this.instr.y);
|
|
11
14
|
const tile = grid.getTile(thisX, thisY);
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import BTModule, { BTTile, IntArray2D, } from '../data.js';
|
|
1
|
+
import BTModule, { BTTile, checkSubtilePlacement, IntArray2D, } from '../data.js';
|
|
2
2
|
export default class LetterBTModule extends BTModule {
|
|
3
3
|
letters;
|
|
4
4
|
letterGrid;
|
|
@@ -22,6 +22,11 @@ export default class LetterBTModule extends BTModule {
|
|
|
22
22
|
checkGlobal(grid) {
|
|
23
23
|
const visited = IntArray2D.create(grid.width, grid.height);
|
|
24
24
|
for (let id = 0; id < this.letters.length; id++) {
|
|
25
|
+
for (const symbol of this.letters[id]) {
|
|
26
|
+
const checkResult = checkSubtilePlacement(grid, symbol);
|
|
27
|
+
if (checkResult !== undefined)
|
|
28
|
+
return checkResult;
|
|
29
|
+
}
|
|
25
30
|
for (const symbol of this.letters[id]) {
|
|
26
31
|
const symbolX = Math.floor(symbol.x);
|
|
27
32
|
const symbolY = Math.floor(symbol.y);
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import EventIteratingSolver from '../eventIteratingSolver.js';
|
|
2
2
|
import GridData from '../../grid.js';
|
|
3
|
+
import Instruction from '../../instruction.js';
|
|
3
4
|
export default class CspuzSolver extends EventIteratingSolver {
|
|
4
5
|
private static readonly supportedInstrs;
|
|
5
6
|
readonly id = "cspuz";
|
|
@@ -7,6 +8,6 @@ export default class CspuzSolver extends EventIteratingSolver {
|
|
|
7
8
|
readonly description = "A blazingly fast WebAssembly solver that supports most rules and symbols (including underclued).";
|
|
8
9
|
protected createWorker(): Worker;
|
|
9
10
|
isGridSupported(grid: GridData): boolean;
|
|
10
|
-
isInstructionSupported(
|
|
11
|
+
isInstructionSupported(grid: GridData, instruction: Instruction): boolean;
|
|
11
12
|
isEnvironmentSupported(): Promise<boolean>;
|
|
12
13
|
}
|
|
@@ -6,14 +6,15 @@ import { instance as symbolsPerRegionInstance } from '../../rules/symbolsPerRegi
|
|
|
6
6
|
import { instance as undercluedInstance } from '../../rules/undercluedRule.js';
|
|
7
7
|
import { instance as uniqueShapeInstance } from '../../rules/uniqueShapeRule.js';
|
|
8
8
|
import { instance as offByXInstance } from '../../rules/offByXRule.js';
|
|
9
|
-
import { instance as areaNumberInstance } from '../../symbols/areaNumberSymbol.js';
|
|
9
|
+
import AreaNumberSymbol, { instance as areaNumberInstance, } from '../../symbols/areaNumberSymbol.js';
|
|
10
10
|
import { instance as dartInstance } from '../../symbols/dartSymbol.js';
|
|
11
11
|
import GalaxySymbol, { instance as galaxyInstance, } from '../../symbols/galaxySymbol.js';
|
|
12
|
-
import { instance as letterInstance } from '../../symbols/letterSymbol.js';
|
|
12
|
+
import LetterSymbol, { instance as letterInstance, } from '../../symbols/letterSymbol.js';
|
|
13
13
|
import LotusSymbol, { instance as lotusInstance, } from '../../symbols/lotusSymbol.js';
|
|
14
14
|
import { instance as minesweeperInstance } from '../../symbols/minesweeperSymbol.js';
|
|
15
15
|
import { instance as viewpointInstance } from '../../symbols/viewpointSymbol.js';
|
|
16
16
|
import { instance as connectAllInstance } from '../../rules/connectAllRule.js';
|
|
17
|
+
import { instance as unsupportedInstance } from '../../symbols/unsupportedSymbol.js';
|
|
17
18
|
import EventIteratingSolver from '../eventIteratingSolver.js';
|
|
18
19
|
import GridData from '../../grid.js';
|
|
19
20
|
import { Color } from '../../primitives.js';
|
|
@@ -37,6 +38,7 @@ export default class CspuzSolver extends EventIteratingSolver {
|
|
|
37
38
|
offByXInstance.id,
|
|
38
39
|
undercluedInstance.id,
|
|
39
40
|
symbolsPerRegionInstance.id,
|
|
41
|
+
unsupportedInstance.id,
|
|
40
42
|
];
|
|
41
43
|
id = 'cspuz';
|
|
42
44
|
author = 'semiexp';
|
|
@@ -50,31 +52,63 @@ export default class CspuzSolver extends EventIteratingSolver {
|
|
|
50
52
|
if (!super.isGridSupported(grid)) {
|
|
51
53
|
return false;
|
|
52
54
|
}
|
|
53
|
-
// special handling for
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
55
|
+
// special handling for fixed gray tiles
|
|
56
|
+
if (grid.getTileCount(true, true, Color.Gray) > 0) {
|
|
57
|
+
return false;
|
|
58
|
+
}
|
|
59
|
+
// the solver doesn't count symbols correctly if some symbols are unsupported
|
|
60
|
+
if (grid.findSymbol(symbol => symbol.id === unsupportedInstance.id) &&
|
|
61
|
+
grid.findRule(rule => rule.id === symbolsPerRegionInstance.id)) {
|
|
62
|
+
return false;
|
|
63
|
+
}
|
|
64
|
+
return true;
|
|
65
|
+
}
|
|
66
|
+
isInstructionSupported(grid, instruction) {
|
|
67
|
+
if (instruction instanceof LotusSymbol ||
|
|
68
|
+
instruction instanceof GalaxySymbol) {
|
|
69
|
+
if (instruction.x % 1 !== 0 && instruction.y % 1 !== 0) {
|
|
70
|
+
return false;
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
if (instruction instanceof LotusSymbol ||
|
|
74
|
+
instruction instanceof GalaxySymbol ||
|
|
75
|
+
instruction instanceof AreaNumberSymbol ||
|
|
76
|
+
instruction instanceof LetterSymbol) {
|
|
77
|
+
if (instruction.x % 1 !== 0 || instruction.y % 1 !== 0) {
|
|
78
|
+
const minX = Math.floor(instruction.x);
|
|
79
|
+
const minY = Math.floor(instruction.y);
|
|
80
|
+
const maxX = Math.ceil(instruction.x);
|
|
81
|
+
const maxY = Math.ceil(instruction.y);
|
|
82
|
+
const connectedTiles = grid.connections.getConnectedTiles({
|
|
83
|
+
x: minX,
|
|
84
|
+
y: minY,
|
|
85
|
+
});
|
|
86
|
+
if (connectedTiles.some(tile => tile.x === minX && tile.y === maxY) &&
|
|
87
|
+
connectedTiles.some(tile => tile.x === maxX && tile.y === minY) &&
|
|
88
|
+
connectedTiles.some(tile => tile.x === maxX && tile.y === maxY)) {
|
|
89
|
+
return true;
|
|
90
|
+
}
|
|
91
|
+
let color = Color.Gray;
|
|
92
|
+
for (let i = 0; i < 4; i++) {
|
|
93
|
+
const x = i % 2 === 0 ? minX : maxX;
|
|
94
|
+
const y = i < 2 ? minY : maxY;
|
|
95
|
+
const tile = grid.getTile(x, y);
|
|
96
|
+
if (!tile.fixed || !tile.exists) {
|
|
58
97
|
return false;
|
|
59
98
|
}
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
99
|
+
if (tile.color !== Color.Gray) {
|
|
100
|
+
if (color === Color.Gray) {
|
|
101
|
+
color = tile.color;
|
|
102
|
+
}
|
|
103
|
+
else if (color !== tile.color) {
|
|
64
104
|
return false;
|
|
65
105
|
}
|
|
66
106
|
}
|
|
67
107
|
}
|
|
108
|
+
return true;
|
|
68
109
|
}
|
|
69
110
|
}
|
|
70
|
-
|
|
71
|
-
if (grid.getTileCount(true, true, Color.Gray) > 0) {
|
|
72
|
-
return false;
|
|
73
|
-
}
|
|
74
|
-
return true;
|
|
75
|
-
}
|
|
76
|
-
isInstructionSupported(instructionId) {
|
|
77
|
-
return CspuzSolver.supportedInstrs.includes(instructionId);
|
|
111
|
+
return CspuzSolver.supportedInstrs.includes(instruction.id);
|
|
78
112
|
}
|
|
79
113
|
async isEnvironmentSupported() {
|
|
80
114
|
try {
|
|
@@ -15,6 +15,7 @@ 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
17
|
import { instance as viewpointInstance, } from '../../symbols/viewpointSymbol.js';
|
|
18
|
+
import { instance as unsupportedInstance } from '../../symbols/unsupportedSymbol.js';
|
|
18
19
|
import TileData from '../../tile.js';
|
|
19
20
|
function canonizeTiles(tileData) {
|
|
20
21
|
const ret = [];
|
|
@@ -180,6 +181,9 @@ export function gridToJson(grid) {
|
|
|
180
181
|
tiles,
|
|
181
182
|
});
|
|
182
183
|
}
|
|
184
|
+
else if (rule === unsupportedInstance.id) {
|
|
185
|
+
continue;
|
|
186
|
+
}
|
|
183
187
|
else if (symbols.some(s => s.necessaryForCompletion)) {
|
|
184
188
|
throw new Error(`Unknown symbol type: ${rule}`);
|
|
185
189
|
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { CachedAccess } from '../dataHelper.js';
|
|
2
2
|
import GridData from '../grid.js';
|
|
3
|
+
import { Instruction } from '../../index.js';
|
|
3
4
|
/**
|
|
4
5
|
* Base class that all solvers must extend.
|
|
5
6
|
*/
|
|
@@ -61,7 +62,7 @@ export default abstract class Solver {
|
|
|
61
62
|
*
|
|
62
63
|
* @param instructionId The unique identifier of the instruction.
|
|
63
64
|
*/
|
|
64
|
-
isInstructionSupported(
|
|
65
|
+
isInstructionSupported(_grid: GridData, instruction: Instruction): boolean;
|
|
65
66
|
/**
|
|
66
67
|
* Check if the solver supports the given grid. This methid is frequently called when the user changes the grid, and
|
|
67
68
|
* the result is used to enable or disable the "Solve" button.
|