@logic-pad/core 0.1.4 → 0.2.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 +383 -305
- package/dist/data/dataHelper.d.ts +8 -0
- package/dist/data/dataHelper.js +31 -0
- package/dist/data/events/onSymbolDisplay.d.ts +15 -0
- package/dist/data/events/onSymbolDisplay.js +4 -0
- package/dist/data/grid.d.ts +7 -0
- package/dist/data/grid.js +23 -2
- package/dist/data/instruction.d.ts +1 -0
- package/dist/data/instruction.js +3 -0
- package/dist/data/primitives.d.ts +8 -0
- package/dist/data/primitives.js +9 -0
- package/dist/data/rules/completePatternRule.js +2 -2
- package/dist/data/rules/foresightRule.d.ts +1 -0
- package/dist/data/rules/foresightRule.js +3 -0
- package/dist/data/rules/musicGridRule.js +2 -2
- package/dist/data/rules/offByXRule.d.ts +1 -0
- package/dist/data/rules/offByXRule.js +3 -0
- package/dist/data/rules/rule.d.ts +0 -1
- package/dist/data/rules/rule.js +0 -3
- package/dist/data/rules/symbolsPerRegionRule.js +3 -1
- package/dist/data/rules/undercluedRule.js +2 -2
- package/dist/data/solver/backtrack/backtrackWorker.js +6 -7
- package/dist/data/solver/backtrack/rules/banPattern.d.ts +1 -1
- package/dist/data/solver/backtrack/rules/banPattern.js +18 -2
- package/dist/data/solver/backtrack/symbols/dart.d.ts +0 -1
- package/dist/data/solver/backtrack/symbols/dart.js +1 -9
- package/dist/data/solver/underclued/undercluedSolver.js +2 -2
- package/dist/data/solver/underclued/undercluedWorker.js +28 -24
- package/dist/data/symbols/hiddenSymbol.d.ts +36 -0
- package/dist/data/symbols/hiddenSymbol.js +119 -0
- package/dist/data/symbols/symbol.d.ts +7 -0
- package/dist/data/symbols/symbol.js +9 -0
- package/dist/data/symbols/symbols.gen.d.ts +1 -0
- package/dist/data/symbols/symbols.gen.js +1 -0
- package/dist/index.d.ts +5 -3
- package/dist/index.js +5 -3
- package/package.json +1 -1
|
@@ -75,3 +75,11 @@ export declare function escape(text: string, escapeCharacters?: string): string;
|
|
|
75
75
|
* @returns The unescaped text.
|
|
76
76
|
*/
|
|
77
77
|
export declare function unescape(text: string, escapeCharacters?: string): string;
|
|
78
|
+
export declare class CachedAccess<T> {
|
|
79
|
+
private readonly getter;
|
|
80
|
+
private static readonly UNCACHED;
|
|
81
|
+
private cache;
|
|
82
|
+
private constructor();
|
|
83
|
+
static of<T>(getter: () => T): CachedAccess<T>;
|
|
84
|
+
get value(): T;
|
|
85
|
+
}
|
package/dist/data/dataHelper.js
CHANGED
|
@@ -188,3 +188,34 @@ export function unescape(text, escapeCharacters = '=,:|') {
|
|
|
188
188
|
}
|
|
189
189
|
return result + text.substring(index);
|
|
190
190
|
}
|
|
191
|
+
export class CachedAccess {
|
|
192
|
+
constructor(getter) {
|
|
193
|
+
Object.defineProperty(this, "getter", {
|
|
194
|
+
enumerable: true,
|
|
195
|
+
configurable: true,
|
|
196
|
+
writable: true,
|
|
197
|
+
value: getter
|
|
198
|
+
});
|
|
199
|
+
Object.defineProperty(this, "cache", {
|
|
200
|
+
enumerable: true,
|
|
201
|
+
configurable: true,
|
|
202
|
+
writable: true,
|
|
203
|
+
value: CachedAccess.UNCACHED
|
|
204
|
+
});
|
|
205
|
+
}
|
|
206
|
+
static of(getter) {
|
|
207
|
+
return new CachedAccess(getter);
|
|
208
|
+
}
|
|
209
|
+
get value() {
|
|
210
|
+
if (this.cache === CachedAccess.UNCACHED) {
|
|
211
|
+
this.cache = this.getter();
|
|
212
|
+
}
|
|
213
|
+
return this.cache;
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
Object.defineProperty(CachedAccess, "UNCACHED", {
|
|
217
|
+
enumerable: true,
|
|
218
|
+
configurable: true,
|
|
219
|
+
writable: true,
|
|
220
|
+
value: Symbol('uncached')
|
|
221
|
+
});
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import GridData from '../grid.js';
|
|
2
|
+
import Instruction from '../instruction.js';
|
|
3
|
+
import Symbol from '../symbols/symbol.js';
|
|
4
|
+
export interface SymbolDisplayHandler {
|
|
5
|
+
/**
|
|
6
|
+
* Controls whether a symbol should be visible in the grid.
|
|
7
|
+
*
|
|
8
|
+
* @param grid The grid that is being displayed.
|
|
9
|
+
* @param symbol The symbol that is being displayed.
|
|
10
|
+
* @param editing Whether the grid is being edited.
|
|
11
|
+
* @returns True if the symbol should be displayed, false otherwise. The symbol will not be displayed if any handler returns false.
|
|
12
|
+
*/
|
|
13
|
+
onSymbolDisplay(grid: GridData, symbol: Symbol, editing: boolean): boolean;
|
|
14
|
+
}
|
|
15
|
+
export declare function handlesSymbolDisplay<T extends Instruction>(val: T): val is T & SymbolDisplayHandler;
|
package/dist/data/grid.d.ts
CHANGED
|
@@ -1,8 +1,12 @@
|
|
|
1
1
|
import GridConnections from './gridConnections.js';
|
|
2
|
+
import { CachedAccess } from './dataHelper.js';
|
|
2
3
|
import { Color, Direction, Orientation, Position } from './primitives.js';
|
|
3
4
|
import Rule from './rules/rule.js';
|
|
4
5
|
import Symbol from './symbols/symbol.js';
|
|
5
6
|
import TileData from './tile.js';
|
|
7
|
+
import MusicGridRule from './rules/musicGridRule.js';
|
|
8
|
+
import CompletePatternRule from './rules/completePatternRule.js';
|
|
9
|
+
import UndercluedRule from './rules/undercluedRule.js';
|
|
6
10
|
export default class GridData {
|
|
7
11
|
readonly width: number;
|
|
8
12
|
readonly height: number;
|
|
@@ -10,6 +14,9 @@ export default class GridData {
|
|
|
10
14
|
readonly connections: GridConnections;
|
|
11
15
|
readonly symbols: ReadonlyMap<string, readonly Symbol[]>;
|
|
12
16
|
readonly rules: readonly Rule[];
|
|
17
|
+
readonly musicGrid: CachedAccess<MusicGridRule | undefined>;
|
|
18
|
+
readonly completePattern: CachedAccess<CompletePatternRule | undefined>;
|
|
19
|
+
readonly underclued: CachedAccess<UndercluedRule | undefined>;
|
|
13
20
|
/**
|
|
14
21
|
* Create a new grid with tiles, connections, symbols and rules.
|
|
15
22
|
* @param width The width of the grid.
|
package/dist/data/grid.js
CHANGED
|
@@ -2,8 +2,8 @@ import { handlesGridChange } from './events/onGridChange.js';
|
|
|
2
2
|
import { handlesGridResize } from './events/onGridResize.js';
|
|
3
3
|
import { handlesSetGrid } from './events/onSetGrid.js';
|
|
4
4
|
import GridConnections from './gridConnections.js';
|
|
5
|
-
import { array, move } from './dataHelper.js';
|
|
6
|
-
import { Color } from './primitives.js';
|
|
5
|
+
import { CachedAccess, array, move } from './dataHelper.js';
|
|
6
|
+
import { Color, MajorRule, } from './primitives.js';
|
|
7
7
|
import TileData from './tile.js';
|
|
8
8
|
const NEIGHBOR_OFFSETS = [
|
|
9
9
|
{ x: -1, y: 0 },
|
|
@@ -12,6 +12,7 @@ const NEIGHBOR_OFFSETS = [
|
|
|
12
12
|
{ x: 0, y: 1 },
|
|
13
13
|
];
|
|
14
14
|
export default class GridData {
|
|
15
|
+
/* eslint-enable @typescript-eslint/no-unsafe-enum-comparison */
|
|
15
16
|
/**
|
|
16
17
|
* Create a new grid with tiles, connections, symbols and rules.
|
|
17
18
|
* @param width The width of the grid.
|
|
@@ -58,6 +59,26 @@ export default class GridData {
|
|
|
58
59
|
writable: true,
|
|
59
60
|
value: void 0
|
|
60
61
|
});
|
|
62
|
+
// Important rules are cached for quick access
|
|
63
|
+
/* eslint-disable @typescript-eslint/no-unsafe-enum-comparison */
|
|
64
|
+
Object.defineProperty(this, "musicGrid", {
|
|
65
|
+
enumerable: true,
|
|
66
|
+
configurable: true,
|
|
67
|
+
writable: true,
|
|
68
|
+
value: CachedAccess.of(() => this.findRule(rule => rule.id === MajorRule.MusicGrid))
|
|
69
|
+
});
|
|
70
|
+
Object.defineProperty(this, "completePattern", {
|
|
71
|
+
enumerable: true,
|
|
72
|
+
configurable: true,
|
|
73
|
+
writable: true,
|
|
74
|
+
value: CachedAccess.of(() => this.findRule(rule => rule.id === MajorRule.CompletePattern))
|
|
75
|
+
});
|
|
76
|
+
Object.defineProperty(this, "underclued", {
|
|
77
|
+
enumerable: true,
|
|
78
|
+
configurable: true,
|
|
79
|
+
writable: true,
|
|
80
|
+
value: CachedAccess.of(() => this.findRule(rule => rule.id === MajorRule.Underclued))
|
|
81
|
+
});
|
|
61
82
|
this.width = width;
|
|
62
83
|
this.height = height;
|
|
63
84
|
this.tiles = tiles ?? array(width, height, () => TileData.empty());
|
|
@@ -9,6 +9,7 @@ export default abstract class Instruction extends Configurable {
|
|
|
9
9
|
*/
|
|
10
10
|
get validateWithSolution(): boolean;
|
|
11
11
|
get necessaryForCompletion(): boolean;
|
|
12
|
+
get visibleWhenSolving(): boolean;
|
|
12
13
|
/**
|
|
13
14
|
* Check if this instruction is equal to another instruction by comparing their IDs and configs.
|
|
14
15
|
*
|
package/dist/data/instruction.js
CHANGED
|
@@ -9,6 +9,9 @@ export default class Instruction extends Configurable {
|
|
|
9
9
|
get necessaryForCompletion() {
|
|
10
10
|
return true;
|
|
11
11
|
}
|
|
12
|
+
get visibleWhenSolving() {
|
|
13
|
+
return true;
|
|
14
|
+
}
|
|
12
15
|
/**
|
|
13
16
|
* Check if this instruction is equal to another instruction by comparing their IDs and configs.
|
|
14
17
|
*
|
|
@@ -8,6 +8,14 @@ export interface Edge {
|
|
|
8
8
|
readonly x2: number;
|
|
9
9
|
readonly y2: number;
|
|
10
10
|
}
|
|
11
|
+
/**
|
|
12
|
+
* Major rules are frequently referenced in grids to provide additional UI.
|
|
13
|
+
*/
|
|
14
|
+
export declare enum MajorRule {
|
|
15
|
+
MusicGrid = "music",
|
|
16
|
+
CompletePattern = "complete_pattern",
|
|
17
|
+
Underclued = "underclued"
|
|
18
|
+
}
|
|
11
19
|
export declare enum State {
|
|
12
20
|
Error = "error",
|
|
13
21
|
Satisfied = "satisfied",
|
package/dist/data/primitives.js
CHANGED
|
@@ -1,3 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Major rules are frequently referenced in grids to provide additional UI.
|
|
3
|
+
*/
|
|
4
|
+
export var MajorRule;
|
|
5
|
+
(function (MajorRule) {
|
|
6
|
+
MajorRule["MusicGrid"] = "music";
|
|
7
|
+
MajorRule["CompletePattern"] = "complete_pattern";
|
|
8
|
+
MajorRule["Underclued"] = "underclued";
|
|
9
|
+
})(MajorRule || (MajorRule = {}));
|
|
1
10
|
export var State;
|
|
2
11
|
(function (State) {
|
|
3
12
|
State["Error"] = "error";
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import GridData from '../grid.js';
|
|
2
|
-
import { State } from '../primitives.js';
|
|
2
|
+
import { MajorRule, State } from '../primitives.js';
|
|
3
3
|
import Rule from './rule.js';
|
|
4
4
|
class CompletePatternRule extends Rule {
|
|
5
5
|
/**
|
|
@@ -11,7 +11,7 @@ class CompletePatternRule extends Rule {
|
|
|
11
11
|
super();
|
|
12
12
|
}
|
|
13
13
|
get id() {
|
|
14
|
-
return
|
|
14
|
+
return MajorRule.CompletePattern;
|
|
15
15
|
}
|
|
16
16
|
get explanation() {
|
|
17
17
|
return `Complete the pattern`;
|
|
@@ -21,6 +21,7 @@ export default class ForesightRule extends Rule {
|
|
|
21
21
|
get searchVariants(): SearchVariant[];
|
|
22
22
|
validateGrid(_grid: GridData): RuleState;
|
|
23
23
|
get necessaryForCompletion(): boolean;
|
|
24
|
+
get isSingleton(): boolean;
|
|
24
25
|
copyWith({ count, regenInterval, startFull, }: {
|
|
25
26
|
count?: number;
|
|
26
27
|
regenInterval?: number;
|
|
@@ -55,6 +55,9 @@ class ForesightRule extends Rule {
|
|
|
55
55
|
get necessaryForCompletion() {
|
|
56
56
|
return false;
|
|
57
57
|
}
|
|
58
|
+
get isSingleton() {
|
|
59
|
+
return true;
|
|
60
|
+
}
|
|
58
61
|
copyWith({ count, regenInterval, startFull, }) {
|
|
59
62
|
return new ForesightRule(count ?? this.count, regenInterval ?? this.regenInterval, startFull ?? this.startFull);
|
|
60
63
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { ConfigType } from '../config.js';
|
|
2
2
|
import GridData from '../grid.js';
|
|
3
3
|
import { resize } from '../dataHelper.js';
|
|
4
|
-
import { Color, State } from '../primitives.js';
|
|
4
|
+
import { Color, MajorRule, State } from '../primitives.js';
|
|
5
5
|
import CustomIconSymbol from '../symbols/customIconSymbol.js';
|
|
6
6
|
import { ControlLine, Row } from './musicControlLine.js';
|
|
7
7
|
import Rule from './rule.js';
|
|
@@ -39,7 +39,7 @@ class MusicGridRule extends Rule {
|
|
|
39
39
|
this.track = track;
|
|
40
40
|
}
|
|
41
41
|
get id() {
|
|
42
|
-
return
|
|
42
|
+
return MajorRule.MusicGrid;
|
|
43
43
|
}
|
|
44
44
|
get explanation() {
|
|
45
45
|
return `*Music Grid:* Listen to the solution`;
|
|
@@ -22,6 +22,7 @@ export default class OffByXRule extends Rule implements SymbolValidationHandler
|
|
|
22
22
|
get searchVariants(): SearchVariant[];
|
|
23
23
|
validateGrid(_grid: GridData): RuleState;
|
|
24
24
|
onSymbolValidation(grid: GridData, symbol: Symbol, _validator: (grid: GridData) => State): State | undefined;
|
|
25
|
+
get isSingleton(): boolean;
|
|
25
26
|
copyWith({ number }: {
|
|
26
27
|
number?: number;
|
|
27
28
|
}): this;
|
|
@@ -9,7 +9,6 @@ export default abstract class Rule extends Instruction {
|
|
|
9
9
|
abstract validateGrid(grid: GridData): RuleState;
|
|
10
10
|
abstract get searchVariants(): SearchVariant[];
|
|
11
11
|
searchVariant(): SearchVariant;
|
|
12
|
-
get visibleWhenSolving(): boolean;
|
|
13
12
|
/**
|
|
14
13
|
* Whether only one instance of this rule is allowed in a grid.
|
|
15
14
|
*/
|
package/dist/data/rules/rule.js
CHANGED
|
@@ -136,7 +136,9 @@ class SymbolsPerRegionRule extends Rule {
|
|
|
136
136
|
static countAllSymbolsOfPosition(grid, x, y) {
|
|
137
137
|
let count = 0;
|
|
138
138
|
for (const symbolKind of grid.symbols.values()) {
|
|
139
|
-
if (symbolKind.some(symbol => Math.floor(symbol.x) === x &&
|
|
139
|
+
if (symbolKind.some(symbol => Math.floor(symbol.x) === x &&
|
|
140
|
+
Math.floor(symbol.y) === y &&
|
|
141
|
+
symbol.necessaryForCompletion)) {
|
|
140
142
|
count++;
|
|
141
143
|
}
|
|
142
144
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import GridData from '../grid.js';
|
|
2
|
-
import { State } from '../primitives.js';
|
|
2
|
+
import { MajorRule, State } from '../primitives.js';
|
|
3
3
|
import AreaNumberSymbol from '../symbols/areaNumberSymbol.js';
|
|
4
4
|
import CustomTextSymbol from '../symbols/customTextSymbol.js';
|
|
5
5
|
import Rule from './rule.js';
|
|
@@ -13,7 +13,7 @@ class UndercluedRule extends Rule {
|
|
|
13
13
|
super();
|
|
14
14
|
}
|
|
15
15
|
get id() {
|
|
16
|
-
return
|
|
16
|
+
return MajorRule.Underclued;
|
|
17
17
|
}
|
|
18
18
|
get explanation() {
|
|
19
19
|
return `*Underclued Grid:* Mark only what is definitely true`;
|
|
@@ -218,13 +218,13 @@ function solveNormal(input, solutionFn) {
|
|
|
218
218
|
}
|
|
219
219
|
function solveUnderclued(input) {
|
|
220
220
|
let grid = input;
|
|
221
|
-
let count = 0;
|
|
221
|
+
// let count = 0;
|
|
222
222
|
const possibles = array(grid.width, grid.height, () => ({
|
|
223
223
|
dark: false,
|
|
224
224
|
light: false,
|
|
225
225
|
}));
|
|
226
226
|
function search(x, y, tile, color) {
|
|
227
|
-
count++;
|
|
227
|
+
// count++;
|
|
228
228
|
// console.log(`Trying (${x}, ${y}) with ${color}`);
|
|
229
229
|
const newGrid = grid.setTile(x, y, tile.withColor(color));
|
|
230
230
|
// Solve
|
|
@@ -263,7 +263,7 @@ function solveUnderclued(input) {
|
|
|
263
263
|
grid = grid.setTile(x, y, tile.withColor(Color.Light));
|
|
264
264
|
}
|
|
265
265
|
}
|
|
266
|
-
console.log(`Solve count: ${count}`);
|
|
266
|
+
// console.log(`Solve count: ${count}`);
|
|
267
267
|
return grid;
|
|
268
268
|
}
|
|
269
269
|
function solve(grid, solutionFn) {
|
|
@@ -278,16 +278,15 @@ function solve(grid, solutionFn) {
|
|
|
278
278
|
}
|
|
279
279
|
onmessage = e => {
|
|
280
280
|
const grid = Serializer.parseGrid(e.data);
|
|
281
|
-
console.time('Solve time');
|
|
281
|
+
// console.time('Solve time');
|
|
282
282
|
let count = 0;
|
|
283
283
|
solve(grid, solution => {
|
|
284
|
-
if (count === 0)
|
|
285
|
-
console.timeLog('Solve time', 'First solution');
|
|
284
|
+
// if (count === 0) console.timeLog('Solve time', 'First solution');
|
|
286
285
|
postMessage(Serializer.stringifyGrid(solution));
|
|
287
286
|
count += 1;
|
|
288
287
|
return count < 2;
|
|
289
288
|
});
|
|
290
|
-
console.timeEnd('Solve time');
|
|
289
|
+
// console.timeEnd('Solve time');
|
|
291
290
|
postMessage(null);
|
|
292
291
|
};
|
|
293
292
|
// make typescript happy
|
|
@@ -4,6 +4,6 @@ import BTModule, { BTGridData, CheckResult } from '../data.js';
|
|
|
4
4
|
export default class BanPatternBTModule extends BTModule {
|
|
5
5
|
instr: BanPatternRule;
|
|
6
6
|
constructor(instr: BanPatternRule);
|
|
7
|
-
checkGlobal(
|
|
7
|
+
checkGlobal(grid: BTGridData): CheckResult | false;
|
|
8
8
|
checkLocal(grid: BTGridData, positions: Position[]): CheckResult | false;
|
|
9
9
|
}
|
|
@@ -10,8 +10,24 @@ export default class BanPatternBTModule extends BTModule {
|
|
|
10
10
|
});
|
|
11
11
|
this.instr = instr;
|
|
12
12
|
}
|
|
13
|
-
checkGlobal(
|
|
14
|
-
|
|
13
|
+
checkGlobal(grid) {
|
|
14
|
+
for (const pattern of this.instr.cache) {
|
|
15
|
+
for (let y = 0; y <= grid.height - pattern.height; y++) {
|
|
16
|
+
for (let x = 0; x <= grid.width - pattern.width; x++) {
|
|
17
|
+
let match = true;
|
|
18
|
+
for (const tile of pattern.elements) {
|
|
19
|
+
const t = grid.getTile(x + tile.x, y + tile.y);
|
|
20
|
+
if (t !== colorToBTTile(tile.color)) {
|
|
21
|
+
match = false;
|
|
22
|
+
break;
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
if (match) {
|
|
26
|
+
return false;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
}
|
|
15
31
|
return { tilesNeedCheck: null, ratings: null };
|
|
16
32
|
}
|
|
17
33
|
checkLocal(grid, positions) {
|
|
@@ -2,7 +2,6 @@ import DartSymbol from '../../../symbols/dartSymbol.js';
|
|
|
2
2
|
import BTModule, { BTGridData, CheckResult } from '../data.js';
|
|
3
3
|
export default class DartBTModule extends BTModule {
|
|
4
4
|
instr: DartSymbol;
|
|
5
|
-
private cachedCheckResult?;
|
|
6
5
|
constructor(instr: DartSymbol);
|
|
7
6
|
checkGlobal(grid: BTGridData): CheckResult | false;
|
|
8
7
|
private buildCheckAndRating;
|
|
@@ -9,12 +9,6 @@ export default class DartBTModule extends BTModule {
|
|
|
9
9
|
writable: true,
|
|
10
10
|
value: void 0
|
|
11
11
|
});
|
|
12
|
-
Object.defineProperty(this, "cachedCheckResult", {
|
|
13
|
-
enumerable: true,
|
|
14
|
-
configurable: true,
|
|
15
|
-
writable: true,
|
|
16
|
-
value: void 0
|
|
17
|
-
});
|
|
18
12
|
this.instr = instr;
|
|
19
13
|
}
|
|
20
14
|
checkGlobal(grid) {
|
|
@@ -38,9 +32,7 @@ export default class DartBTModule extends BTModule {
|
|
|
38
32
|
}
|
|
39
33
|
if (completed + empty < this.instr.number)
|
|
40
34
|
return false;
|
|
41
|
-
|
|
42
|
-
this.cachedCheckResult = this.buildCheckAndRating(grid);
|
|
43
|
-
return this.cachedCheckResult;
|
|
35
|
+
return this.buildCheckAndRating(grid);
|
|
44
36
|
}
|
|
45
37
|
buildCheckAndRating(grid) {
|
|
46
38
|
const tilesNeedCheck = IntArray2D.create(grid.width, grid.height);
|
|
@@ -26,14 +26,14 @@ export default class UndercluedSolver extends Solver {
|
|
|
26
26
|
const solved = await new Promise(resolve => {
|
|
27
27
|
worker.addEventListener('message', e => {
|
|
28
28
|
const solution = Serializer.parseGrid(e.data);
|
|
29
|
-
console.timeEnd('Solve time');
|
|
29
|
+
// console.timeEnd('Solve time');
|
|
30
30
|
if (solution.resetTiles().equals(solution))
|
|
31
31
|
resolve(null);
|
|
32
32
|
else
|
|
33
33
|
resolve(solution);
|
|
34
34
|
});
|
|
35
35
|
worker.postMessage(Serializer.stringifyGrid(grid));
|
|
36
|
-
console.time('Solve time');
|
|
36
|
+
// console.time('Solve time');
|
|
37
37
|
});
|
|
38
38
|
yield solved;
|
|
39
39
|
if (solved) {
|
|
@@ -70,18 +70,20 @@ function computeSolution(initialGrid) {
|
|
|
70
70
|
let anyNewGrid;
|
|
71
71
|
while (assumptions.length > 0 || lastValidGrid.length === 0) {
|
|
72
72
|
[currentGrid, assumptions, anyNewGrid] = getValidGrid(currentGrid, assumptions, canAssump);
|
|
73
|
-
console.log(
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
})
|
|
83
|
-
|
|
84
|
-
|
|
73
|
+
// console.log(
|
|
74
|
+
// currentGrid.tiles
|
|
75
|
+
// .map(row =>
|
|
76
|
+
// row
|
|
77
|
+
// .map(t => {
|
|
78
|
+
// const color = t.color === Color.Light ? 'w' : 'b';
|
|
79
|
+
// if (t.color === Color.Gray) return 'n';
|
|
80
|
+
// if (!t.exists) return '.';
|
|
81
|
+
// return t.fixed ? color.toUpperCase() : color;
|
|
82
|
+
// })
|
|
83
|
+
// .join('')
|
|
84
|
+
// )
|
|
85
|
+
// .join('\n')
|
|
86
|
+
// );
|
|
85
87
|
if (!anyNewGrid) {
|
|
86
88
|
break;
|
|
87
89
|
}
|
|
@@ -105,18 +107,20 @@ function computeSolution(initialGrid) {
|
|
|
105
107
|
const coords = posToCoords(i, solutionGrid.width);
|
|
106
108
|
solutionGrid = solutionGrid.setTile(coords[0], coords[1], tile => tile.withColor(color));
|
|
107
109
|
});
|
|
108
|
-
console.log(
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
})
|
|
118
|
-
|
|
119
|
-
|
|
110
|
+
// console.log(
|
|
111
|
+
// solutionGrid.tiles
|
|
112
|
+
// .map(row =>
|
|
113
|
+
// row
|
|
114
|
+
// .map(t => {
|
|
115
|
+
// const color = t.color === Color.Light ? 'w' : 'b';
|
|
116
|
+
// if (t.color === Color.Gray) return 'n';
|
|
117
|
+
// if (!t.exists) return '.';
|
|
118
|
+
// return t.fixed ? color.toUpperCase() : color;
|
|
119
|
+
// })
|
|
120
|
+
// .join('')
|
|
121
|
+
// )
|
|
122
|
+
// .join('\n')
|
|
123
|
+
// );
|
|
120
124
|
return solutionGrid;
|
|
121
125
|
}
|
|
122
126
|
onmessage = e => {
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { AnyConfig } from '../config.js';
|
|
2
|
+
import { SymbolDisplayHandler } from '../events/onSymbolDisplay.js';
|
|
3
|
+
import GridData from '../grid.js';
|
|
4
|
+
import { Color, State } from '../primitives.js';
|
|
5
|
+
import Symbol from './symbol.js';
|
|
6
|
+
export default class HiddenSymbol extends Symbol implements SymbolDisplayHandler {
|
|
7
|
+
readonly x: number;
|
|
8
|
+
readonly y: number;
|
|
9
|
+
readonly color: Color;
|
|
10
|
+
private static readonly CONFIGS;
|
|
11
|
+
private static readonly EXAMPLE_GRID;
|
|
12
|
+
/**
|
|
13
|
+
* **Hidden Symbols: color cells correctly to reveal more clues**
|
|
14
|
+
*
|
|
15
|
+
* @param x - The x-coordinate of the symbol.
|
|
16
|
+
* @param y - The y-coordinate of the symbol.
|
|
17
|
+
* @param color - The target color of the cell.
|
|
18
|
+
*/
|
|
19
|
+
constructor(x: number, y: number, color: Color);
|
|
20
|
+
get id(): string;
|
|
21
|
+
get explanation(): string;
|
|
22
|
+
get configs(): readonly AnyConfig[] | null;
|
|
23
|
+
createExampleGrid(): GridData;
|
|
24
|
+
get necessaryForCompletion(): boolean;
|
|
25
|
+
get visibleWhenSolving(): boolean;
|
|
26
|
+
get sortOrder(): number;
|
|
27
|
+
validateSymbol(grid: GridData): State;
|
|
28
|
+
onSymbolDisplay(grid: GridData, symbol: Symbol, editing: boolean): boolean;
|
|
29
|
+
copyWith({ x, y, color, }: {
|
|
30
|
+
x?: number;
|
|
31
|
+
y?: number;
|
|
32
|
+
color?: Color;
|
|
33
|
+
}): this;
|
|
34
|
+
withColor(color: Color): this;
|
|
35
|
+
}
|
|
36
|
+
export declare const instance: HiddenSymbol;
|