@logic-pad/core 0.3.0 → 0.4.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 +70 -16
- package/dist/data/dataHelper.d.ts +8 -1
- package/dist/data/dataHelper.js +10 -0
- package/dist/data/grid.d.ts +13 -2
- package/dist/data/grid.js +66 -10
- package/dist/data/gridConnections.d.ts +2 -16
- package/dist/data/gridConnections.js +8 -46
- package/dist/data/gridZones.d.ts +25 -0
- package/dist/data/gridZones.js +91 -0
- package/dist/data/rules/cellCountPerZoneRule.d.ts +29 -0
- package/dist/data/rules/cellCountPerZoneRule.js +165 -0
- package/dist/data/rules/rules.gen.d.ts +1 -0
- package/dist/data/rules/rules.gen.js +1 -0
- package/dist/data/serializer/serializerBase.d.ts +3 -0
- package/dist/data/serializer/serializer_v0.d.ts +3 -0
- package/dist/data/serializer/serializer_v0.js +20 -1
- package/dist/index.d.ts +5 -3
- package/dist/index.js +5 -3
- package/package.json +1 -1
|
@@ -112,6 +112,30 @@ declare global {
|
|
|
112
112
|
Create = 'create',
|
|
113
113
|
Solve = 'solve',
|
|
114
114
|
}
|
|
115
|
+
export declare class GridZones {
|
|
116
|
+
readonly edges: readonly Edge[];
|
|
117
|
+
constructor(edges?: readonly Edge[]);
|
|
118
|
+
addEdge(edge: Edge): GridZones;
|
|
119
|
+
removeEdge(edge: Edge): GridZones;
|
|
120
|
+
hasEdge(edge: Edge): boolean;
|
|
121
|
+
getEdgesAt({ x, y }: Position$1): readonly Edge[];
|
|
122
|
+
/**
|
|
123
|
+
* Check if two GridZones objects are equal.
|
|
124
|
+
* @param other The other GridZones object to compare to.
|
|
125
|
+
* @returns Whether the two objects are equal.
|
|
126
|
+
*/
|
|
127
|
+
equals(other: GridZones): boolean;
|
|
128
|
+
/**
|
|
129
|
+
* Deduplicate an array of edges.
|
|
130
|
+
* @param edges The array of edges to deduplicate.
|
|
131
|
+
* @returns The deduplicated array of edges.
|
|
132
|
+
*/
|
|
133
|
+
static deduplicateEdges(edges: readonly Edge[]): readonly Edge[];
|
|
134
|
+
insertColumn(index: number): GridZones;
|
|
135
|
+
insertRow(index: number): GridZones;
|
|
136
|
+
removeColumn(index: number): GridZones;
|
|
137
|
+
removeRow(index: number): GridZones;
|
|
138
|
+
}
|
|
115
139
|
export declare class TileConnections {
|
|
116
140
|
[y: number]: {
|
|
117
141
|
[x: number]: boolean;
|
|
@@ -137,13 +161,10 @@ declare global {
|
|
|
137
161
|
set bottomRight(value: boolean);
|
|
138
162
|
equals(other: TileConnections): boolean;
|
|
139
163
|
}
|
|
140
|
-
export declare class GridConnections {
|
|
141
|
-
readonly edges: readonly Edge[];
|
|
164
|
+
export declare class GridConnections extends GridZones {
|
|
142
165
|
constructor(edges?: readonly Edge[]);
|
|
143
166
|
addEdge(edge: Edge): GridConnections;
|
|
144
167
|
removeEdge(edge: Edge): GridConnections;
|
|
145
|
-
isConnected(edge: Edge): boolean;
|
|
146
|
-
getConnectionsAt({ x, y }: Position$1): readonly Edge[];
|
|
147
168
|
getForTile({ x, y }: Position$1): TileConnections;
|
|
148
169
|
getConnectedTiles({ x, y }: Position$1): readonly Position$1[];
|
|
149
170
|
/**
|
|
@@ -156,18 +177,6 @@ declare global {
|
|
|
156
177
|
* @returns The created connections. You can apply this to a GridData object using GridData.withConnections.
|
|
157
178
|
*/
|
|
158
179
|
static create(array: string[]): GridConnections;
|
|
159
|
-
/**
|
|
160
|
-
* Check if two GridConnections objects are equal.
|
|
161
|
-
* @param other The other GridConnections object to compare to.
|
|
162
|
-
* @returns Whether the two objects are equal.
|
|
163
|
-
*/
|
|
164
|
-
equals(other: GridConnections): boolean;
|
|
165
|
-
/**
|
|
166
|
-
* Deduplicate an array of edges.
|
|
167
|
-
* @param edges The array of edges to deduplicate.
|
|
168
|
-
* @returns The deduplicated array of edges.
|
|
169
|
-
*/
|
|
170
|
-
static deduplicateEdges(edges: readonly Edge[]): readonly Edge[];
|
|
171
180
|
insertColumn(index: number): GridConnections;
|
|
172
181
|
insertRow(index: number): GridConnections;
|
|
173
182
|
removeColumn(index: number): GridConnections;
|
|
@@ -188,6 +197,13 @@ declare global {
|
|
|
188
197
|
x: number;
|
|
189
198
|
y: number;
|
|
190
199
|
};
|
|
200
|
+
/**
|
|
201
|
+
* Check if two edges are the same, regardless of direction.
|
|
202
|
+
* @param a The first edge.
|
|
203
|
+
* @param b The second edge.
|
|
204
|
+
* @returns Whether the edges are the same.
|
|
205
|
+
*/
|
|
206
|
+
export declare function isSameEdge(a: Edge, b: Edge): boolean;
|
|
191
207
|
/**
|
|
192
208
|
* Convert the given direction to a rotation in degrees.
|
|
193
209
|
* @param direction The direction to convert.
|
|
@@ -577,11 +593,13 @@ declare global {
|
|
|
577
593
|
get validateWithSolution(): boolean;
|
|
578
594
|
get isSingleton(): boolean;
|
|
579
595
|
}
|
|
596
|
+
export declare const NEIGHBOR_OFFSETS: Position$1[];
|
|
580
597
|
export declare class GridData {
|
|
581
598
|
readonly width: number;
|
|
582
599
|
readonly height: number;
|
|
583
600
|
readonly tiles: readonly (readonly TileData[])[];
|
|
584
601
|
readonly connections: GridConnections;
|
|
602
|
+
readonly zones: GridZones;
|
|
585
603
|
readonly symbols: ReadonlyMap<string, readonly Symbol$1[]>;
|
|
586
604
|
readonly rules: readonly Rule[];
|
|
587
605
|
readonly musicGrid: CachedAccess<MusicGridRule | undefined>;
|
|
@@ -593,6 +611,7 @@ declare global {
|
|
|
593
611
|
* @param height The height of the grid.
|
|
594
612
|
* @param tiles The tiles of the grid.
|
|
595
613
|
* @param connections The connections of the grid, which determines which tiles are merged.
|
|
614
|
+
* @param zones The zones of the grid.
|
|
596
615
|
* @param symbols The symbols in the grid.
|
|
597
616
|
* @param rules The rules of the grid.
|
|
598
617
|
*/
|
|
@@ -601,6 +620,7 @@ declare global {
|
|
|
601
620
|
height: number,
|
|
602
621
|
tiles?: readonly (readonly TileData[])[],
|
|
603
622
|
connections?: GridConnections,
|
|
623
|
+
zones?: GridZones,
|
|
604
624
|
symbols?: ReadonlyMap<string, readonly Symbol$1[]>,
|
|
605
625
|
rules?: readonly Rule[]
|
|
606
626
|
);
|
|
@@ -614,6 +634,7 @@ declare global {
|
|
|
614
634
|
height,
|
|
615
635
|
tiles,
|
|
616
636
|
connections,
|
|
637
|
+
zones,
|
|
617
638
|
symbols,
|
|
618
639
|
rules,
|
|
619
640
|
}: {
|
|
@@ -621,6 +642,7 @@ declare global {
|
|
|
621
642
|
height?: number;
|
|
622
643
|
tiles?: readonly (readonly TileData[])[];
|
|
623
644
|
connections?: GridConnections;
|
|
645
|
+
zones?: GridZones;
|
|
624
646
|
symbols?: ReadonlyMap<string, readonly Symbol$1[]>;
|
|
625
647
|
rules?: readonly Rule[];
|
|
626
648
|
}): GridData;
|
|
@@ -668,6 +690,12 @@ declare global {
|
|
|
668
690
|
| GridConnections
|
|
669
691
|
| ((value: GridConnections) => GridConnections)
|
|
670
692
|
): GridData;
|
|
693
|
+
/**
|
|
694
|
+
* Add or modify the zones in the grid.
|
|
695
|
+
* @param zones The new zones to add or modify.
|
|
696
|
+
* @returns The new grid with the new zones.
|
|
697
|
+
*/
|
|
698
|
+
withZones(zones: GridZones | ((value: GridZones) => GridZones)): GridData;
|
|
671
699
|
/**
|
|
672
700
|
* Add or modify the symbols in the grid.
|
|
673
701
|
* @param symbols The new symbols to add or modify.
|
|
@@ -1332,6 +1360,28 @@ declare global {
|
|
|
1332
1360
|
copyWith({ pattern }: { pattern?: GridData }): this;
|
|
1333
1361
|
withPattern(pattern: GridData): this;
|
|
1334
1362
|
}
|
|
1363
|
+
export declare class CellCountPerZoneRule extends Rule {
|
|
1364
|
+
readonly color: Color;
|
|
1365
|
+
private static readonly CONFIGS;
|
|
1366
|
+
private static readonly EXAMPLE_GRID_LIGHT;
|
|
1367
|
+
private static readonly EXAMPLE_GRID_DARK;
|
|
1368
|
+
private static readonly EXAMPLE_GRID_GRAY;
|
|
1369
|
+
private static readonly SEARCH_VARIANTS;
|
|
1370
|
+
/**
|
|
1371
|
+
* **Every zone has the same number of <color> cells.**
|
|
1372
|
+
*
|
|
1373
|
+
* @param color - The color of the cells to count.
|
|
1374
|
+
*/
|
|
1375
|
+
constructor(color: Color);
|
|
1376
|
+
get id(): string;
|
|
1377
|
+
get explanation(): string;
|
|
1378
|
+
get configs(): readonly AnyConfig[] | null;
|
|
1379
|
+
createExampleGrid(): GridData;
|
|
1380
|
+
get searchVariants(): SearchVariant[];
|
|
1381
|
+
validateGrid(grid: GridData): RuleState;
|
|
1382
|
+
copyWith({ color }: { color?: Color }): this;
|
|
1383
|
+
withColor(color: Color): this;
|
|
1384
|
+
}
|
|
1335
1385
|
export declare class CellCountRule extends Rule {
|
|
1336
1386
|
readonly color: Color;
|
|
1337
1387
|
readonly count: number;
|
|
@@ -1746,6 +1796,8 @@ declare global {
|
|
|
1746
1796
|
abstract parseSymbol(str: string): Symbol$1;
|
|
1747
1797
|
abstract stringifyConnections(connections: GridConnections): string;
|
|
1748
1798
|
abstract parseConnections(input: string): GridConnections;
|
|
1799
|
+
abstract stringifyZones(zones: GridZones): string;
|
|
1800
|
+
abstract parseZones(input: string): GridZones;
|
|
1749
1801
|
abstract stringifyTiles(tiles: readonly (readonly TileData[])[]): string;
|
|
1750
1802
|
abstract parseTiles(input: string): TileData[][];
|
|
1751
1803
|
abstract stringifyRules(rules: readonly Rule[]): string;
|
|
@@ -1777,6 +1829,8 @@ declare global {
|
|
|
1777
1829
|
parseSymbol(str: string): Symbol$1;
|
|
1778
1830
|
stringifyConnections(connections: GridConnections): string;
|
|
1779
1831
|
parseConnections(input: string): GridConnections;
|
|
1832
|
+
stringifyZones(zones: GridZones): string;
|
|
1833
|
+
parseZones(input: string): GridZones;
|
|
1780
1834
|
stringifyTiles(tiles: readonly (readonly TileData[])[]): string;
|
|
1781
1835
|
parseTiles(input: string): TileData[][];
|
|
1782
1836
|
stringifyRules(rules: readonly Rule[]): string;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Direction, Orientation, Position } from './primitives.js';
|
|
1
|
+
import { Direction, Edge, Orientation, Position } from './primitives.js';
|
|
2
2
|
/**
|
|
3
3
|
* Offset the given position by a given step in the given direction.
|
|
4
4
|
* @param position The position to offset.
|
|
@@ -10,6 +10,13 @@ export declare function move(position: Position, direction: Direction | Orientat
|
|
|
10
10
|
x: number;
|
|
11
11
|
y: number;
|
|
12
12
|
};
|
|
13
|
+
/**
|
|
14
|
+
* Check if two edges are the same, regardless of direction.
|
|
15
|
+
* @param a The first edge.
|
|
16
|
+
* @param b The second edge.
|
|
17
|
+
* @returns Whether the edges are the same.
|
|
18
|
+
*/
|
|
19
|
+
export declare function isSameEdge(a: Edge, b: Edge): boolean;
|
|
13
20
|
/**
|
|
14
21
|
* Convert the given direction to a rotation in degrees.
|
|
15
22
|
* @param direction The direction to convert.
|
package/dist/data/dataHelper.js
CHANGED
|
@@ -30,6 +30,16 @@ export function move(position, direction, step = 1) {
|
|
|
30
30
|
return { x: position.x + step, y: position.y + step };
|
|
31
31
|
}
|
|
32
32
|
}
|
|
33
|
+
/**
|
|
34
|
+
* Check if two edges are the same, regardless of direction.
|
|
35
|
+
* @param a The first edge.
|
|
36
|
+
* @param b The second edge.
|
|
37
|
+
* @returns Whether the edges are the same.
|
|
38
|
+
*/
|
|
39
|
+
export function isSameEdge(a, b) {
|
|
40
|
+
return ((a.x1 === b.x1 && a.y1 === b.y1 && a.x2 === b.x2 && a.y2 === b.y2) ||
|
|
41
|
+
(a.x1 === b.x2 && a.y1 === b.y2 && a.x2 === b.x1 && a.y2 === b.y1));
|
|
42
|
+
}
|
|
33
43
|
/**
|
|
34
44
|
* Convert the given direction to a rotation in degrees.
|
|
35
45
|
* @param direction The direction to convert.
|
package/dist/data/grid.d.ts
CHANGED
|
@@ -7,11 +7,14 @@ import TileData from './tile.js';
|
|
|
7
7
|
import MusicGridRule from './rules/musicGridRule.js';
|
|
8
8
|
import CompletePatternRule from './rules/completePatternRule.js';
|
|
9
9
|
import UndercluedRule from './rules/undercluedRule.js';
|
|
10
|
+
import GridZones from './gridZones.js';
|
|
11
|
+
export declare const NEIGHBOR_OFFSETS: Position[];
|
|
10
12
|
export default class GridData {
|
|
11
13
|
readonly width: number;
|
|
12
14
|
readonly height: number;
|
|
13
15
|
readonly tiles: readonly (readonly TileData[])[];
|
|
14
16
|
readonly connections: GridConnections;
|
|
17
|
+
readonly zones: GridZones;
|
|
15
18
|
readonly symbols: ReadonlyMap<string, readonly Symbol[]>;
|
|
16
19
|
readonly rules: readonly Rule[];
|
|
17
20
|
readonly musicGrid: CachedAccess<MusicGridRule | undefined>;
|
|
@@ -23,20 +26,22 @@ export default class GridData {
|
|
|
23
26
|
* @param height The height of the grid.
|
|
24
27
|
* @param tiles The tiles of the grid.
|
|
25
28
|
* @param connections The connections of the grid, which determines which tiles are merged.
|
|
29
|
+
* @param zones The zones of the grid.
|
|
26
30
|
* @param symbols The symbols in the grid.
|
|
27
31
|
* @param rules The rules of the grid.
|
|
28
32
|
*/
|
|
29
|
-
constructor(width: number, height: number, tiles?: readonly (readonly TileData[])[], connections?: GridConnections, symbols?: ReadonlyMap<string, readonly Symbol[]>, rules?: readonly Rule[]);
|
|
33
|
+
constructor(width: number, height: number, tiles?: readonly (readonly TileData[])[], connections?: GridConnections, zones?: GridZones, symbols?: ReadonlyMap<string, readonly Symbol[]>, rules?: readonly Rule[]);
|
|
30
34
|
/**
|
|
31
35
|
* Copy the current grid while modifying the provided properties.
|
|
32
36
|
* @param param0 The properties to modify.
|
|
33
37
|
* @returns The new grid with the modified properties.
|
|
34
38
|
*/
|
|
35
|
-
copyWith({ width, height, tiles, connections, symbols, rules, }: {
|
|
39
|
+
copyWith({ width, height, tiles, connections, zones, symbols, rules, }: {
|
|
36
40
|
width?: number;
|
|
37
41
|
height?: number;
|
|
38
42
|
tiles?: readonly (readonly TileData[])[];
|
|
39
43
|
connections?: GridConnections;
|
|
44
|
+
zones?: GridZones;
|
|
40
45
|
symbols?: ReadonlyMap<string, readonly Symbol[]>;
|
|
41
46
|
rules?: readonly Rule[];
|
|
42
47
|
}): GridData;
|
|
@@ -72,6 +77,12 @@ export default class GridData {
|
|
|
72
77
|
* @returns The new grid with the new connections.
|
|
73
78
|
*/
|
|
74
79
|
withConnections(connections: GridConnections | ((value: GridConnections) => GridConnections)): GridData;
|
|
80
|
+
/**
|
|
81
|
+
* Add or modify the zones in the grid.
|
|
82
|
+
* @param zones The new zones to add or modify.
|
|
83
|
+
* @returns The new grid with the new zones.
|
|
84
|
+
*/
|
|
85
|
+
withZones(zones: GridZones | ((value: GridZones) => GridZones)): GridData;
|
|
75
86
|
/**
|
|
76
87
|
* Add or modify the symbols in the grid.
|
|
77
88
|
* @param symbols The new symbols to add or modify.
|
package/dist/data/grid.js
CHANGED
|
@@ -5,7 +5,8 @@ import GridConnections from './gridConnections.js';
|
|
|
5
5
|
import { CachedAccess, array, move } from './dataHelper.js';
|
|
6
6
|
import { Color, MajorRule, } from './primitives.js';
|
|
7
7
|
import TileData from './tile.js';
|
|
8
|
-
|
|
8
|
+
import GridZones from './gridZones.js';
|
|
9
|
+
export const NEIGHBOR_OFFSETS = [
|
|
9
10
|
{ x: -1, y: 0 },
|
|
10
11
|
{ x: 1, y: 0 },
|
|
11
12
|
{ x: 0, y: -1 },
|
|
@@ -19,10 +20,11 @@ export default class GridData {
|
|
|
19
20
|
* @param height The height of the grid.
|
|
20
21
|
* @param tiles The tiles of the grid.
|
|
21
22
|
* @param connections The connections of the grid, which determines which tiles are merged.
|
|
23
|
+
* @param zones The zones of the grid.
|
|
22
24
|
* @param symbols The symbols in the grid.
|
|
23
25
|
* @param rules The rules of the grid.
|
|
24
26
|
*/
|
|
25
|
-
constructor(width, height, tiles, connections, symbols, rules) {
|
|
27
|
+
constructor(width, height, tiles, connections, zones, symbols, rules) {
|
|
26
28
|
Object.defineProperty(this, "width", {
|
|
27
29
|
enumerable: true,
|
|
28
30
|
configurable: true,
|
|
@@ -47,6 +49,12 @@ export default class GridData {
|
|
|
47
49
|
writable: true,
|
|
48
50
|
value: void 0
|
|
49
51
|
});
|
|
52
|
+
Object.defineProperty(this, "zones", {
|
|
53
|
+
enumerable: true,
|
|
54
|
+
configurable: true,
|
|
55
|
+
writable: true,
|
|
56
|
+
value: void 0
|
|
57
|
+
});
|
|
50
58
|
Object.defineProperty(this, "symbols", {
|
|
51
59
|
enumerable: true,
|
|
52
60
|
configurable: true,
|
|
@@ -83,6 +91,7 @@ export default class GridData {
|
|
|
83
91
|
this.height = height;
|
|
84
92
|
this.tiles = tiles ?? array(width, height, () => TileData.empty());
|
|
85
93
|
this.connections = connections ?? new GridConnections();
|
|
94
|
+
this.zones = zones ?? new GridZones();
|
|
86
95
|
const newSymbols = symbols
|
|
87
96
|
? GridData.deduplicateSymbols(symbols)
|
|
88
97
|
: new Map();
|
|
@@ -108,8 +117,8 @@ export default class GridData {
|
|
|
108
117
|
* @param param0 The properties to modify.
|
|
109
118
|
* @returns The new grid with the modified properties.
|
|
110
119
|
*/
|
|
111
|
-
copyWith({ width, height, tiles, connections, symbols, rules, }) {
|
|
112
|
-
return new GridData(width ?? this.width, height ?? this.height, tiles ?? this.tiles, connections ?? this.connections, symbols ?? this.symbols, rules ?? this.rules);
|
|
120
|
+
copyWith({ width, height, tiles, connections, zones, symbols, rules, }) {
|
|
121
|
+
return new GridData(width ?? this.width, height ?? this.height, tiles ?? this.tiles, connections ?? this.connections, zones ?? this.zones, symbols ?? this.symbols, rules ?? this.rules);
|
|
113
122
|
}
|
|
114
123
|
isPositionValid(x, y) {
|
|
115
124
|
return x >= 0 && x < this.width && y >= 0 && y < this.height;
|
|
@@ -173,6 +182,16 @@ export default class GridData {
|
|
|
173
182
|
: connections,
|
|
174
183
|
});
|
|
175
184
|
}
|
|
185
|
+
/**
|
|
186
|
+
* Add or modify the zones in the grid.
|
|
187
|
+
* @param zones The new zones to add or modify.
|
|
188
|
+
* @returns The new grid with the new zones.
|
|
189
|
+
*/
|
|
190
|
+
withZones(zones) {
|
|
191
|
+
return this.copyWith({
|
|
192
|
+
zones: typeof zones === 'function' ? zones(this.zones) : zones,
|
|
193
|
+
});
|
|
194
|
+
}
|
|
176
195
|
/**
|
|
177
196
|
* Add or modify the symbols in the grid.
|
|
178
197
|
* @param symbols The new symbols to add or modify.
|
|
@@ -346,6 +365,7 @@ export default class GridData {
|
|
|
346
365
|
return this.getTile(x - 1, y);
|
|
347
366
|
});
|
|
348
367
|
const connections = this.connections.insertColumn(index);
|
|
368
|
+
const zones = this.zones.insertColumn(index);
|
|
349
369
|
const rules = this.rules
|
|
350
370
|
.map(rule => {
|
|
351
371
|
if (handlesGridResize(rule))
|
|
@@ -366,6 +386,7 @@ export default class GridData {
|
|
|
366
386
|
width: this.width + 1,
|
|
367
387
|
tiles,
|
|
368
388
|
connections,
|
|
389
|
+
zones,
|
|
369
390
|
rules,
|
|
370
391
|
symbols,
|
|
371
392
|
});
|
|
@@ -386,6 +407,7 @@ export default class GridData {
|
|
|
386
407
|
return this.getTile(x, y - 1);
|
|
387
408
|
});
|
|
388
409
|
const connections = this.connections.insertRow(index);
|
|
410
|
+
const zones = this.zones.insertRow(index);
|
|
389
411
|
const rules = this.rules
|
|
390
412
|
.map(rule => {
|
|
391
413
|
if (handlesGridResize(rule))
|
|
@@ -406,6 +428,7 @@ export default class GridData {
|
|
|
406
428
|
height: this.height + 1,
|
|
407
429
|
tiles,
|
|
408
430
|
connections,
|
|
431
|
+
zones,
|
|
409
432
|
rules,
|
|
410
433
|
symbols,
|
|
411
434
|
});
|
|
@@ -420,6 +443,7 @@ export default class GridData {
|
|
|
420
443
|
return this;
|
|
421
444
|
const tiles = array(this.width - 1, this.height, (x, y) => x < index ? this.getTile(x, y) : this.getTile(x + 1, y));
|
|
422
445
|
const connections = this.connections.removeColumn(index);
|
|
446
|
+
const zones = this.zones.removeColumn(index);
|
|
423
447
|
const rules = this.rules
|
|
424
448
|
.map(rule => {
|
|
425
449
|
if (handlesGridResize(rule))
|
|
@@ -440,6 +464,7 @@ export default class GridData {
|
|
|
440
464
|
width: this.width - 1,
|
|
441
465
|
tiles,
|
|
442
466
|
connections,
|
|
467
|
+
zones,
|
|
443
468
|
rules,
|
|
444
469
|
symbols,
|
|
445
470
|
});
|
|
@@ -454,6 +479,7 @@ export default class GridData {
|
|
|
454
479
|
return this;
|
|
455
480
|
const tiles = array(this.width, this.height - 1, (x, y) => y < index ? this.getTile(x, y) : this.getTile(x, y + 1));
|
|
456
481
|
const connections = this.connections.removeRow(index);
|
|
482
|
+
const zones = this.zones.removeRow(index);
|
|
457
483
|
const rules = this.rules
|
|
458
484
|
.map(rule => {
|
|
459
485
|
if (handlesGridResize(rule))
|
|
@@ -474,6 +500,7 @@ export default class GridData {
|
|
|
474
500
|
height: this.height - 1,
|
|
475
501
|
tiles,
|
|
476
502
|
connections,
|
|
503
|
+
zones,
|
|
477
504
|
rules,
|
|
478
505
|
symbols,
|
|
479
506
|
});
|
|
@@ -573,10 +600,7 @@ export default class GridData {
|
|
|
573
600
|
return ret;
|
|
574
601
|
for (const offset of NEIGHBOR_OFFSETS) {
|
|
575
602
|
const next = { x: x + offset.x, y: y + offset.y };
|
|
576
|
-
if (next.x
|
|
577
|
-
next.x < this.width &&
|
|
578
|
-
next.y >= 0 &&
|
|
579
|
-
next.y < this.height) {
|
|
603
|
+
if (this.isPositionValid(next.x, next.y)) {
|
|
580
604
|
const nextTile = this.getTile(next.x, next.y);
|
|
581
605
|
if (nextTile.exists && predicate(nextTile))
|
|
582
606
|
stack.push(next);
|
|
@@ -747,6 +771,21 @@ export default class GridData {
|
|
|
747
771
|
x2: edge.x2 - origin.x,
|
|
748
772
|
y2: edge.y2 - origin.y,
|
|
749
773
|
})));
|
|
774
|
+
const zones = new GridZones(this.zones.edges
|
|
775
|
+
.filter(edge => edge.x1 >= origin.x &&
|
|
776
|
+
edge.y1 >= origin.y &&
|
|
777
|
+
edge.x2 >= origin.x &&
|
|
778
|
+
edge.y2 >= origin.y &&
|
|
779
|
+
edge.x1 < origin.x + width &&
|
|
780
|
+
edge.y1 < origin.y + height &&
|
|
781
|
+
edge.x2 < origin.x + width &&
|
|
782
|
+
edge.y2 < origin.y + height)
|
|
783
|
+
.map(edge => ({
|
|
784
|
+
x1: edge.x1 - origin.x,
|
|
785
|
+
y1: edge.y1 - origin.y,
|
|
786
|
+
x2: edge.x2 - origin.x,
|
|
787
|
+
y2: edge.y2 - origin.y,
|
|
788
|
+
})));
|
|
750
789
|
const symbols = new Map();
|
|
751
790
|
for (const [id, symbolList] of this.symbols) {
|
|
752
791
|
const newSymbolList = symbolList.filter(symbol => symbol.x >= origin.x &&
|
|
@@ -756,7 +795,7 @@ export default class GridData {
|
|
|
756
795
|
if (newSymbolList.length > 0)
|
|
757
796
|
symbols.set(id, newSymbolList);
|
|
758
797
|
}
|
|
759
|
-
return new GridData(width, height, newTiles, connections, symbols, this.rules);
|
|
798
|
+
return new GridData(width, height, newTiles, connections, zones, symbols, this.rules);
|
|
760
799
|
}
|
|
761
800
|
pasteTiles(origin, grid) {
|
|
762
801
|
if (!(grid instanceof GridData))
|
|
@@ -775,6 +814,15 @@ export default class GridData {
|
|
|
775
814
|
y2: edge.y2 + origin.y,
|
|
776
815
|
})),
|
|
777
816
|
]);
|
|
817
|
+
const zones = new GridZones([
|
|
818
|
+
...this.zones.edges,
|
|
819
|
+
...grid.zones.edges.map(edge => ({
|
|
820
|
+
x1: edge.x1 + origin.x,
|
|
821
|
+
y1: edge.y1 + origin.y,
|
|
822
|
+
x2: edge.x2 + origin.x,
|
|
823
|
+
y2: edge.y2 + origin.y,
|
|
824
|
+
})),
|
|
825
|
+
]);
|
|
778
826
|
const symbols = new Map(this.symbols);
|
|
779
827
|
for (const [id, sourceList] of grid.symbols) {
|
|
780
828
|
const symbolList = sourceList.map(symbol => symbol.copyWith({ x: symbol.x + origin.x, y: symbol.y + origin.y }));
|
|
@@ -786,7 +834,13 @@ export default class GridData {
|
|
|
786
834
|
}
|
|
787
835
|
}
|
|
788
836
|
const rules = [...this.rules, ...grid.rules];
|
|
789
|
-
return this.copyWith({
|
|
837
|
+
return this.copyWith({
|
|
838
|
+
tiles: newTiles,
|
|
839
|
+
connections,
|
|
840
|
+
zones,
|
|
841
|
+
symbols,
|
|
842
|
+
rules,
|
|
843
|
+
});
|
|
790
844
|
}
|
|
791
845
|
/**
|
|
792
846
|
* Check if this grid is equal to another grid in terms of size and tile colors.
|
|
@@ -839,6 +893,8 @@ export default class GridData {
|
|
|
839
893
|
return false;
|
|
840
894
|
if (!this.connections.equals(other.connections))
|
|
841
895
|
return false;
|
|
896
|
+
if (!this.zones.equals(other.zones))
|
|
897
|
+
return false;
|
|
842
898
|
if (this.symbols.size !== other.symbols.size)
|
|
843
899
|
return false;
|
|
844
900
|
for (const [id, symbols] of this.symbols) {
|
|
@@ -1,12 +1,10 @@
|
|
|
1
|
+
import GridZones from './gridZones.js';
|
|
1
2
|
import { Edge, Position } from './primitives.js';
|
|
2
3
|
import TileConnections from './tileConnections.js';
|
|
3
|
-
export default class GridConnections {
|
|
4
|
-
readonly edges: readonly Edge[];
|
|
4
|
+
export default class GridConnections extends GridZones {
|
|
5
5
|
constructor(edges?: readonly Edge[]);
|
|
6
6
|
addEdge(edge: Edge): GridConnections;
|
|
7
7
|
removeEdge(edge: Edge): GridConnections;
|
|
8
|
-
isConnected(edge: Edge): boolean;
|
|
9
|
-
getConnectionsAt({ x, y }: Position): readonly Edge[];
|
|
10
8
|
getForTile({ x, y }: Position): TileConnections;
|
|
11
9
|
getConnectedTiles({ x, y }: Position): readonly Position[];
|
|
12
10
|
/**
|
|
@@ -19,18 +17,6 @@ export default class GridConnections {
|
|
|
19
17
|
* @returns The created connections. You can apply this to a GridData object using GridData.withConnections.
|
|
20
18
|
*/
|
|
21
19
|
static create(array: string[]): GridConnections;
|
|
22
|
-
/**
|
|
23
|
-
* Check if two GridConnections objects are equal.
|
|
24
|
-
* @param other The other GridConnections object to compare to.
|
|
25
|
-
* @returns Whether the two objects are equal.
|
|
26
|
-
*/
|
|
27
|
-
equals(other: GridConnections): boolean;
|
|
28
|
-
/**
|
|
29
|
-
* Deduplicate an array of edges.
|
|
30
|
-
* @param edges The array of edges to deduplicate.
|
|
31
|
-
* @returns The deduplicated array of edges.
|
|
32
|
-
*/
|
|
33
|
-
static deduplicateEdges(edges: readonly Edge[]): readonly Edge[];
|
|
34
20
|
insertColumn(index: number): GridConnections;
|
|
35
21
|
insertRow(index: number): GridConnections;
|
|
36
22
|
removeColumn(index: number): GridConnections;
|
|
@@ -1,17 +1,9 @@
|
|
|
1
|
+
import { isSameEdge } from './dataHelper.js';
|
|
2
|
+
import GridZones from './gridZones.js';
|
|
1
3
|
import TileConnections from './tileConnections.js';
|
|
2
|
-
|
|
3
|
-
return ((a.x1 === b.x1 && a.y1 === b.y1 && a.x2 === b.x2 && a.y2 === b.y2) ||
|
|
4
|
-
(a.x1 === b.x2 && a.y1 === b.y2 && a.x2 === b.x1 && a.y2 === b.y1));
|
|
5
|
-
}
|
|
6
|
-
export default class GridConnections {
|
|
4
|
+
export default class GridConnections extends GridZones {
|
|
7
5
|
constructor(edges) {
|
|
8
|
-
|
|
9
|
-
enumerable: true,
|
|
10
|
-
configurable: true,
|
|
11
|
-
writable: true,
|
|
12
|
-
value: void 0
|
|
13
|
-
});
|
|
14
|
-
this.edges = GridConnections.deduplicateEdges(edges ?? []);
|
|
6
|
+
super(edges);
|
|
15
7
|
}
|
|
16
8
|
addEdge(edge) {
|
|
17
9
|
if (this.edges.some(e => isSameEdge(e, edge))) {
|
|
@@ -22,26 +14,18 @@ export default class GridConnections {
|
|
|
22
14
|
removeEdge(edge) {
|
|
23
15
|
return new GridConnections(this.edges.filter(e => !isSameEdge(e, edge)));
|
|
24
16
|
}
|
|
25
|
-
isConnected(edge) {
|
|
26
|
-
if (edge.x1 === edge.x2 && edge.y1 === edge.y2)
|
|
27
|
-
return true;
|
|
28
|
-
return this.edges.some(e => isSameEdge(e, edge));
|
|
29
|
-
}
|
|
30
|
-
getConnectionsAt({ x, y }) {
|
|
31
|
-
return this.edges.filter(e => (e.x1 === x && e.y1 === y) || (e.x2 === x && e.y2 === y));
|
|
32
|
-
}
|
|
33
17
|
getForTile({ x, y }) {
|
|
34
18
|
const result = new TileConnections();
|
|
35
19
|
// Get all connections within 2 steps of the tile
|
|
36
|
-
const edges = this.
|
|
20
|
+
const edges = this.getEdgesAt({ x, y });
|
|
37
21
|
const edges2 = [
|
|
38
22
|
...edges,
|
|
39
23
|
...edges.flatMap(edge => {
|
|
40
24
|
if (edge.x1 === x && edge.y1 === y) {
|
|
41
|
-
return this.
|
|
25
|
+
return this.getEdgesAt({ x: edge.x2, y: edge.y2 });
|
|
42
26
|
}
|
|
43
27
|
else {
|
|
44
|
-
return this.
|
|
28
|
+
return this.getEdgesAt({ x: edge.x1, y: edge.y1 });
|
|
45
29
|
}
|
|
46
30
|
}),
|
|
47
31
|
];
|
|
@@ -89,7 +73,7 @@ export default class GridConnections {
|
|
|
89
73
|
}
|
|
90
74
|
visited.add(`${current.x},${current.y}`);
|
|
91
75
|
result.push(current);
|
|
92
|
-
const edges = this.
|
|
76
|
+
const edges = this.getEdgesAt(current);
|
|
93
77
|
for (const edge of edges) {
|
|
94
78
|
if (edge.x1 === current.x && edge.y1 === current.y) {
|
|
95
79
|
queue.push({ x: edge.x2, y: edge.y2 });
|
|
@@ -127,28 +111,6 @@ export default class GridConnections {
|
|
|
127
111
|
}
|
|
128
112
|
return new GridConnections(edges);
|
|
129
113
|
}
|
|
130
|
-
/**
|
|
131
|
-
* Check if two GridConnections objects are equal.
|
|
132
|
-
* @param other The other GridConnections object to compare to.
|
|
133
|
-
* @returns Whether the two objects are equal.
|
|
134
|
-
*/
|
|
135
|
-
equals(other) {
|
|
136
|
-
if (this.edges.length !== other.edges.length)
|
|
137
|
-
return false;
|
|
138
|
-
for (const edge of this.edges) {
|
|
139
|
-
if (!other.isConnected(edge))
|
|
140
|
-
return false;
|
|
141
|
-
}
|
|
142
|
-
return true;
|
|
143
|
-
}
|
|
144
|
-
/**
|
|
145
|
-
* Deduplicate an array of edges.
|
|
146
|
-
* @param edges The array of edges to deduplicate.
|
|
147
|
-
* @returns The deduplicated array of edges.
|
|
148
|
-
*/
|
|
149
|
-
static deduplicateEdges(edges) {
|
|
150
|
-
return edges.filter((edge, index) => edges.findIndex(e => isSameEdge(e, edge)) === index);
|
|
151
|
-
}
|
|
152
114
|
insertColumn(index) {
|
|
153
115
|
return new GridConnections(this.edges.flatMap(edge => {
|
|
154
116
|
if ((edge.x1 < index && edge.x2 < index) ||
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { Edge, Position } from './primitives.js';
|
|
2
|
+
export default class GridZones {
|
|
3
|
+
readonly edges: readonly Edge[];
|
|
4
|
+
constructor(edges?: readonly Edge[]);
|
|
5
|
+
addEdge(edge: Edge): GridZones;
|
|
6
|
+
removeEdge(edge: Edge): GridZones;
|
|
7
|
+
hasEdge(edge: Edge): boolean;
|
|
8
|
+
getEdgesAt({ x, y }: Position): readonly Edge[];
|
|
9
|
+
/**
|
|
10
|
+
* Check if two GridZones objects are equal.
|
|
11
|
+
* @param other The other GridZones object to compare to.
|
|
12
|
+
* @returns Whether the two objects are equal.
|
|
13
|
+
*/
|
|
14
|
+
equals(other: GridZones): boolean;
|
|
15
|
+
/**
|
|
16
|
+
* Deduplicate an array of edges.
|
|
17
|
+
* @param edges The array of edges to deduplicate.
|
|
18
|
+
* @returns The deduplicated array of edges.
|
|
19
|
+
*/
|
|
20
|
+
static deduplicateEdges(edges: readonly Edge[]): readonly Edge[];
|
|
21
|
+
insertColumn(index: number): GridZones;
|
|
22
|
+
insertRow(index: number): GridZones;
|
|
23
|
+
removeColumn(index: number): GridZones;
|
|
24
|
+
removeRow(index: number): GridZones;
|
|
25
|
+
}
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
import { isSameEdge } from './dataHelper.js';
|
|
2
|
+
export default class GridZones {
|
|
3
|
+
constructor(edges) {
|
|
4
|
+
Object.defineProperty(this, "edges", {
|
|
5
|
+
enumerable: true,
|
|
6
|
+
configurable: true,
|
|
7
|
+
writable: true,
|
|
8
|
+
value: void 0
|
|
9
|
+
});
|
|
10
|
+
this.edges = GridZones.deduplicateEdges(edges ?? []);
|
|
11
|
+
}
|
|
12
|
+
addEdge(edge) {
|
|
13
|
+
if (this.edges.some(e => isSameEdge(e, edge))) {
|
|
14
|
+
return this;
|
|
15
|
+
}
|
|
16
|
+
return new GridZones([...this.edges, edge]);
|
|
17
|
+
}
|
|
18
|
+
removeEdge(edge) {
|
|
19
|
+
return new GridZones(this.edges.filter(e => !isSameEdge(e, edge)));
|
|
20
|
+
}
|
|
21
|
+
hasEdge(edge) {
|
|
22
|
+
if (edge.x1 === edge.x2 && edge.y1 === edge.y2)
|
|
23
|
+
return true;
|
|
24
|
+
return this.edges.some(e => isSameEdge(e, edge));
|
|
25
|
+
}
|
|
26
|
+
getEdgesAt({ x, y }) {
|
|
27
|
+
return this.edges.filter(e => (e.x1 === x && e.y1 === y) || (e.x2 === x && e.y2 === y));
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Check if two GridZones objects are equal.
|
|
31
|
+
* @param other The other GridZones object to compare to.
|
|
32
|
+
* @returns Whether the two objects are equal.
|
|
33
|
+
*/
|
|
34
|
+
equals(other) {
|
|
35
|
+
if (this.edges.length !== other.edges.length)
|
|
36
|
+
return false;
|
|
37
|
+
for (const edge of this.edges) {
|
|
38
|
+
if (!other.hasEdge(edge))
|
|
39
|
+
return false;
|
|
40
|
+
}
|
|
41
|
+
return true;
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Deduplicate an array of edges.
|
|
45
|
+
* @param edges The array of edges to deduplicate.
|
|
46
|
+
* @returns The deduplicated array of edges.
|
|
47
|
+
*/
|
|
48
|
+
static deduplicateEdges(edges) {
|
|
49
|
+
return edges.filter((edge, index) => edges.findIndex(e => isSameEdge(e, edge)) === index);
|
|
50
|
+
}
|
|
51
|
+
insertColumn(index) {
|
|
52
|
+
return new GridZones(this.edges.map(edge => {
|
|
53
|
+
if (edge.x1 < index || edge.x2 < index) {
|
|
54
|
+
return edge;
|
|
55
|
+
}
|
|
56
|
+
else {
|
|
57
|
+
return { x1: edge.x1 + 1, y1: edge.y1, x2: edge.x2 + 1, y2: edge.y2 };
|
|
58
|
+
}
|
|
59
|
+
}));
|
|
60
|
+
}
|
|
61
|
+
insertRow(index) {
|
|
62
|
+
return new GridZones(this.edges.map(edge => {
|
|
63
|
+
if (edge.y1 < index || edge.y2 < index) {
|
|
64
|
+
return edge;
|
|
65
|
+
}
|
|
66
|
+
else {
|
|
67
|
+
return { x1: edge.x1, y1: edge.y1 + 1, x2: edge.x2, y2: edge.y2 + 1 };
|
|
68
|
+
}
|
|
69
|
+
}));
|
|
70
|
+
}
|
|
71
|
+
removeColumn(index) {
|
|
72
|
+
return new GridZones(this.edges.map(edge => {
|
|
73
|
+
if (edge.x1 > index || edge.x2 > index) {
|
|
74
|
+
return { x1: edge.x1 - 1, y1: edge.y1, x2: edge.x2 - 1, y2: edge.y2 };
|
|
75
|
+
}
|
|
76
|
+
else {
|
|
77
|
+
return edge;
|
|
78
|
+
}
|
|
79
|
+
}));
|
|
80
|
+
}
|
|
81
|
+
removeRow(index) {
|
|
82
|
+
return new GridZones(this.edges.map(edge => {
|
|
83
|
+
if (edge.y1 > index || edge.y2 > index) {
|
|
84
|
+
return { x1: edge.x1, y1: edge.y1 - 1, x2: edge.x2, y2: edge.y2 - 1 };
|
|
85
|
+
}
|
|
86
|
+
else {
|
|
87
|
+
return edge;
|
|
88
|
+
}
|
|
89
|
+
}));
|
|
90
|
+
}
|
|
91
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { AnyConfig } from '../config.js';
|
|
2
|
+
import GridData from '../grid.js';
|
|
3
|
+
import { Color, RuleState } from '../primitives.js';
|
|
4
|
+
import Rule, { SearchVariant } from './rule.js';
|
|
5
|
+
export default class CellCountPerZoneRule extends Rule {
|
|
6
|
+
readonly color: Color;
|
|
7
|
+
private static readonly CONFIGS;
|
|
8
|
+
private static readonly EXAMPLE_GRID_LIGHT;
|
|
9
|
+
private static readonly EXAMPLE_GRID_DARK;
|
|
10
|
+
private static readonly EXAMPLE_GRID_GRAY;
|
|
11
|
+
private static readonly SEARCH_VARIANTS;
|
|
12
|
+
/**
|
|
13
|
+
* **Every zone has the same number of <color> cells.**
|
|
14
|
+
*
|
|
15
|
+
* @param color - The color of the cells to count.
|
|
16
|
+
*/
|
|
17
|
+
constructor(color: Color);
|
|
18
|
+
get id(): string;
|
|
19
|
+
get explanation(): string;
|
|
20
|
+
get configs(): readonly AnyConfig[] | null;
|
|
21
|
+
createExampleGrid(): GridData;
|
|
22
|
+
get searchVariants(): SearchVariant[];
|
|
23
|
+
validateGrid(grid: GridData): RuleState;
|
|
24
|
+
copyWith({ color }: {
|
|
25
|
+
color?: Color;
|
|
26
|
+
}): this;
|
|
27
|
+
withColor(color: Color): this;
|
|
28
|
+
}
|
|
29
|
+
export declare const instance: CellCountPerZoneRule;
|
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
import { ConfigType } from '../config.js';
|
|
2
|
+
import { array } from '../dataHelper.js';
|
|
3
|
+
import GridData, { NEIGHBOR_OFFSETS } from '../grid.js';
|
|
4
|
+
import GridZones from '../gridZones.js';
|
|
5
|
+
import { Color, State } from '../primitives.js';
|
|
6
|
+
import Rule from './rule.js';
|
|
7
|
+
class CellCountPerZoneRule extends Rule {
|
|
8
|
+
/**
|
|
9
|
+
* **Every zone has the same number of <color> cells.**
|
|
10
|
+
*
|
|
11
|
+
* @param color - The color of the cells to count.
|
|
12
|
+
*/
|
|
13
|
+
constructor(color) {
|
|
14
|
+
super();
|
|
15
|
+
Object.defineProperty(this, "color", {
|
|
16
|
+
enumerable: true,
|
|
17
|
+
configurable: true,
|
|
18
|
+
writable: true,
|
|
19
|
+
value: color
|
|
20
|
+
});
|
|
21
|
+
this.color = color;
|
|
22
|
+
}
|
|
23
|
+
get id() {
|
|
24
|
+
return `zone_cell_count`;
|
|
25
|
+
}
|
|
26
|
+
get explanation() {
|
|
27
|
+
return `Every zone has the same number of ${this.color} cells`;
|
|
28
|
+
}
|
|
29
|
+
get configs() {
|
|
30
|
+
return CellCountPerZoneRule.CONFIGS;
|
|
31
|
+
}
|
|
32
|
+
createExampleGrid() {
|
|
33
|
+
if (this.color === Color.Light) {
|
|
34
|
+
return CellCountPerZoneRule.EXAMPLE_GRID_LIGHT;
|
|
35
|
+
}
|
|
36
|
+
else if (this.color === Color.Dark) {
|
|
37
|
+
return CellCountPerZoneRule.EXAMPLE_GRID_DARK;
|
|
38
|
+
}
|
|
39
|
+
else {
|
|
40
|
+
return CellCountPerZoneRule.EXAMPLE_GRID_GRAY;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
get searchVariants() {
|
|
44
|
+
return CellCountPerZoneRule.SEARCH_VARIANTS;
|
|
45
|
+
}
|
|
46
|
+
validateGrid(grid) {
|
|
47
|
+
let complete = true;
|
|
48
|
+
const visited = array(grid.width, grid.height, (i, j) => !grid.getTile(i, j).exists);
|
|
49
|
+
const zones = [];
|
|
50
|
+
while (true) {
|
|
51
|
+
const seed = grid.find((_tile, x, y) => !visited[y][x]);
|
|
52
|
+
if (!seed)
|
|
53
|
+
break;
|
|
54
|
+
const zone = {
|
|
55
|
+
positions: [],
|
|
56
|
+
completed: 0,
|
|
57
|
+
possible: 0,
|
|
58
|
+
};
|
|
59
|
+
const stack = [seed];
|
|
60
|
+
while (stack.length > 0) {
|
|
61
|
+
const { x, y } = stack.pop();
|
|
62
|
+
if (visited[y][x])
|
|
63
|
+
continue;
|
|
64
|
+
visited[y][x] = true;
|
|
65
|
+
zone.positions.push({ x, y });
|
|
66
|
+
if (grid.getTile(x, y).color === this.color) {
|
|
67
|
+
zone.completed++;
|
|
68
|
+
}
|
|
69
|
+
else if (grid.getTile(x, y).color === Color.Gray) {
|
|
70
|
+
zone.possible++;
|
|
71
|
+
complete = false;
|
|
72
|
+
}
|
|
73
|
+
for (const offset of NEIGHBOR_OFFSETS) {
|
|
74
|
+
const next = { x: x + offset.x, y: y + offset.y };
|
|
75
|
+
if (!grid.zones.edges.some(e => (e.x1 === x &&
|
|
76
|
+
e.y1 === y &&
|
|
77
|
+
e.x2 === next.x &&
|
|
78
|
+
e.y2 === next.y) ||
|
|
79
|
+
(e.x1 === next.x && e.y1 === next.y && e.x2 === x && e.y2 === y))) {
|
|
80
|
+
const nextTile = grid.getTile(next.x, next.y);
|
|
81
|
+
if (nextTile.exists) {
|
|
82
|
+
stack.push(next);
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
zones.push(zone);
|
|
88
|
+
}
|
|
89
|
+
if (zones.length <= 1) {
|
|
90
|
+
return { state: complete ? State.Satisfied : State.Incomplete };
|
|
91
|
+
}
|
|
92
|
+
else {
|
|
93
|
+
const errorZone = zones.find(z => zones.some(zz => zz !== z &&
|
|
94
|
+
(zz.completed > z.completed + z.possible ||
|
|
95
|
+
zz.completed + zz.possible < z.completed)));
|
|
96
|
+
if (errorZone) {
|
|
97
|
+
return {
|
|
98
|
+
state: State.Error,
|
|
99
|
+
positions: errorZone.positions,
|
|
100
|
+
};
|
|
101
|
+
}
|
|
102
|
+
else {
|
|
103
|
+
return { state: complete ? State.Satisfied : State.Incomplete };
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
copyWith({ color }) {
|
|
108
|
+
return new CellCountPerZoneRule(color ?? this.color);
|
|
109
|
+
}
|
|
110
|
+
withColor(color) {
|
|
111
|
+
return this.copyWith({ color });
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
Object.defineProperty(CellCountPerZoneRule, "CONFIGS", {
|
|
115
|
+
enumerable: true,
|
|
116
|
+
configurable: true,
|
|
117
|
+
writable: true,
|
|
118
|
+
value: Object.freeze([
|
|
119
|
+
{
|
|
120
|
+
type: ConfigType.Color,
|
|
121
|
+
default: Color.Light,
|
|
122
|
+
allowGray: true,
|
|
123
|
+
field: 'color',
|
|
124
|
+
description: 'Color',
|
|
125
|
+
configurable: true,
|
|
126
|
+
},
|
|
127
|
+
])
|
|
128
|
+
});
|
|
129
|
+
Object.defineProperty(CellCountPerZoneRule, "EXAMPLE_GRID_LIGHT", {
|
|
130
|
+
enumerable: true,
|
|
131
|
+
configurable: true,
|
|
132
|
+
writable: true,
|
|
133
|
+
value: Object.freeze(GridData.create(['bwbbb', 'wbbwb', 'bbbwb', 'bwbwb'])
|
|
134
|
+
.withZones(new GridZones([
|
|
135
|
+
{ x1: 0, y1: 1, x2: 0, y2: 2 },
|
|
136
|
+
{ x1: 1, y1: 1, x2: 1, y2: 2 },
|
|
137
|
+
{ x1: 2, y1: 1, x2: 2, y2: 2 },
|
|
138
|
+
{ x1: 3, y1: 1, x2: 3, y2: 2 },
|
|
139
|
+
{ x1: 4, y1: 1, x2: 4, y2: 2 },
|
|
140
|
+
]))
|
|
141
|
+
.addRule(new CellCountPerZoneRule(Color.Light)))
|
|
142
|
+
});
|
|
143
|
+
Object.defineProperty(CellCountPerZoneRule, "EXAMPLE_GRID_DARK", {
|
|
144
|
+
enumerable: true,
|
|
145
|
+
configurable: true,
|
|
146
|
+
writable: true,
|
|
147
|
+
value: Object.freeze(CellCountPerZoneRule.EXAMPLE_GRID_LIGHT.withTiles(tiles => tiles.map(row => row.map(tile => tile.withColor(tile.color === Color.Dark ? Color.Light : Color.Dark)))))
|
|
148
|
+
});
|
|
149
|
+
Object.defineProperty(CellCountPerZoneRule, "EXAMPLE_GRID_GRAY", {
|
|
150
|
+
enumerable: true,
|
|
151
|
+
configurable: true,
|
|
152
|
+
writable: true,
|
|
153
|
+
value: Object.freeze(CellCountPerZoneRule.EXAMPLE_GRID_LIGHT.withTiles(tiles => tiles.map(row => row.map(tile => tile.withColor(tile.color === Color.Light ? Color.Gray : tile.color)))))
|
|
154
|
+
});
|
|
155
|
+
Object.defineProperty(CellCountPerZoneRule, "SEARCH_VARIANTS", {
|
|
156
|
+
enumerable: true,
|
|
157
|
+
configurable: true,
|
|
158
|
+
writable: true,
|
|
159
|
+
value: [
|
|
160
|
+
new CellCountPerZoneRule(Color.Light).searchVariant(),
|
|
161
|
+
new CellCountPerZoneRule(Color.Dark).searchVariant(),
|
|
162
|
+
]
|
|
163
|
+
});
|
|
164
|
+
export default CellCountPerZoneRule;
|
|
165
|
+
export const instance = new CellCountPerZoneRule(Color.Light);
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
export { instance as BanPatternRule } from './banPatternRule.js';
|
|
2
|
+
export { instance as CellCountPerZoneRule } from './cellCountPerZoneRule.js';
|
|
2
3
|
export { instance as CellCountRule } from './cellCountRule.js';
|
|
3
4
|
export { instance as CompletePatternRule } from './completePatternRule.js';
|
|
4
5
|
export { instance as ConnectAllRule } from './connectAllRule.js';
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
// @ts-nocheck
|
|
4
4
|
// noinspection JSUnusedGlobalSymbols
|
|
5
5
|
export { instance as BanPatternRule } from './banPatternRule.js';
|
|
6
|
+
export { instance as CellCountPerZoneRule } from './cellCountPerZoneRule.js';
|
|
6
7
|
export { instance as CellCountRule } from './cellCountRule.js';
|
|
7
8
|
export { instance as CompletePatternRule } from './completePatternRule.js';
|
|
8
9
|
export { instance as ConnectAllRule } from './connectAllRule.js';
|
|
@@ -4,6 +4,7 @@ import Rule from '../rules/rule.js';
|
|
|
4
4
|
import TileData from '../tile.js';
|
|
5
5
|
import Symbol from '../symbols/symbol.js';
|
|
6
6
|
import { Puzzle } from '../puzzle.js';
|
|
7
|
+
import GridZones from '../gridZones.js';
|
|
7
8
|
export default abstract class SerializerBase {
|
|
8
9
|
abstract get version(): number;
|
|
9
10
|
abstract stringifyTile(tile: TileData): string;
|
|
@@ -14,6 +15,8 @@ export default abstract class SerializerBase {
|
|
|
14
15
|
abstract parseSymbol(str: string): Symbol;
|
|
15
16
|
abstract stringifyConnections(connections: GridConnections): string;
|
|
16
17
|
abstract parseConnections(input: string): GridConnections;
|
|
18
|
+
abstract stringifyZones(zones: GridZones): string;
|
|
19
|
+
abstract parseZones(input: string): GridZones;
|
|
17
20
|
abstract stringifyTiles(tiles: readonly (readonly TileData[])[]): string;
|
|
18
21
|
abstract parseTiles(input: string): TileData[][];
|
|
19
22
|
abstract stringifyRules(rules: readonly Rule[]): string;
|
|
@@ -8,6 +8,7 @@ import { AnyConfig } from '../config.js';
|
|
|
8
8
|
import SerializerBase from './serializerBase.js';
|
|
9
9
|
import { Puzzle } from '../puzzle.js';
|
|
10
10
|
import { ControlLine } from '../rules/musicControlLine.js';
|
|
11
|
+
import GridZones from '../gridZones.js';
|
|
11
12
|
export default class SerializerV0 extends SerializerBase {
|
|
12
13
|
readonly version = 0;
|
|
13
14
|
stringifyTile(tile: TileData): string;
|
|
@@ -23,6 +24,8 @@ export default class SerializerV0 extends SerializerBase {
|
|
|
23
24
|
parseSymbol(str: string): Symbol;
|
|
24
25
|
stringifyConnections(connections: GridConnections): string;
|
|
25
26
|
parseConnections(input: string): GridConnections;
|
|
27
|
+
stringifyZones(zones: GridZones): string;
|
|
28
|
+
parseZones(input: string): GridZones;
|
|
26
29
|
stringifyTiles(tiles: readonly (readonly TileData[])[]): string;
|
|
27
30
|
parseTiles(input: string): TileData[][];
|
|
28
31
|
stringifyRules(rules: readonly Rule[]): string;
|
|
@@ -8,6 +8,7 @@ import { allRules } from '../rules/index.js';
|
|
|
8
8
|
import { allSymbols } from '../symbols/index.js';
|
|
9
9
|
import SerializerBase from './serializerBase.js';
|
|
10
10
|
import { ControlLine, Row } from '../rules/musicControlLine.js';
|
|
11
|
+
import GridZones from '../gridZones.js';
|
|
11
12
|
const OFFSETS = [
|
|
12
13
|
{ x: 0, y: -1 },
|
|
13
14
|
{ x: -1, y: 0 },
|
|
@@ -314,6 +315,19 @@ export default class SerializerV0 extends SerializerBase {
|
|
|
314
315
|
const tiles = array(width, Math.ceil(data.length / width), (x, y) => data[y * width + x]);
|
|
315
316
|
return GridConnections.create(tiles.map(row => row.join('')));
|
|
316
317
|
}
|
|
318
|
+
stringifyZones(zones) {
|
|
319
|
+
return `Z${zones.edges.map(edge => `${edge.x1}_${edge.y1}_${edge.x2 - edge.x1}_${edge.y2 - edge.y1}`).join(':')}`;
|
|
320
|
+
}
|
|
321
|
+
parseZones(input) {
|
|
322
|
+
if (!input.startsWith('Z')) {
|
|
323
|
+
throw new Error('Invalid grid zones\n' + input);
|
|
324
|
+
}
|
|
325
|
+
const data = input.slice(1).split(':');
|
|
326
|
+
return new GridZones(data.map(entry => {
|
|
327
|
+
const [x1, y1, w, h] = entry.split('_').map(Number);
|
|
328
|
+
return { x1, y1, x2: x1 + w, y2: y1 + h };
|
|
329
|
+
}));
|
|
330
|
+
}
|
|
317
331
|
stringifyTiles(tiles) {
|
|
318
332
|
return `T${tiles[0]?.length ?? 0}:${tiles.map(row => row.map(tile => this.stringifyTile(tile)).join('')).join('')}`;
|
|
319
333
|
}
|
|
@@ -368,6 +382,7 @@ export default class SerializerV0 extends SerializerBase {
|
|
|
368
382
|
const data = [
|
|
369
383
|
this.stringifyTiles(grid.tiles),
|
|
370
384
|
this.stringifyConnections(grid.connections),
|
|
385
|
+
this.stringifyZones(grid.zones),
|
|
371
386
|
this.stringifySymbols(grid.symbols),
|
|
372
387
|
this.stringifyRules(grid.rules),
|
|
373
388
|
];
|
|
@@ -379,6 +394,7 @@ export default class SerializerV0 extends SerializerBase {
|
|
|
379
394
|
let height;
|
|
380
395
|
let tiles;
|
|
381
396
|
let connections;
|
|
397
|
+
let zones;
|
|
382
398
|
let symbols;
|
|
383
399
|
let rules;
|
|
384
400
|
for (const d of data) {
|
|
@@ -391,6 +407,9 @@ export default class SerializerV0 extends SerializerBase {
|
|
|
391
407
|
else if (d.startsWith('C')) {
|
|
392
408
|
connections = this.parseConnections(d);
|
|
393
409
|
}
|
|
410
|
+
else if (d.startsWith('Z')) {
|
|
411
|
+
zones = this.parseZones(d);
|
|
412
|
+
}
|
|
394
413
|
else if (d.startsWith('S')) {
|
|
395
414
|
symbols = this.parseSymbols(d);
|
|
396
415
|
}
|
|
@@ -401,7 +420,7 @@ export default class SerializerV0 extends SerializerBase {
|
|
|
401
420
|
throw new Error(`Invalid data: ${d}`);
|
|
402
421
|
}
|
|
403
422
|
}
|
|
404
|
-
return new GridData(width ?? tiles?.[0].length ?? 0, height ?? tiles?.length ?? 0, tiles, connections, symbols, rules);
|
|
423
|
+
return new GridData(width ?? tiles?.[0].length ?? 0, height ?? tiles?.length ?? 0, tiles, connections, zones, symbols, rules);
|
|
405
424
|
}
|
|
406
425
|
stringifyPuzzle(puzzle) {
|
|
407
426
|
let grid = puzzle.grid;
|
package/dist/index.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { ConfigType, configEquals } from './data/config.js';
|
|
2
2
|
import Configurable from './data/configurable.js';
|
|
3
|
-
import { CachedAccess, allEqual, array, directionToRotation, escape, maxBy, minBy, move, orientationToRotation, resize, unescape } from './data/dataHelper.js';
|
|
3
|
+
import { CachedAccess, allEqual, array, directionToRotation, escape, isSameEdge, maxBy, minBy, move, orientationToRotation, resize, unescape } from './data/dataHelper.js';
|
|
4
4
|
import { isEventHandler } from './data/events/eventHelper.js';
|
|
5
5
|
import { handlesFinalValidation } from './data/events/onFinalValidation.js';
|
|
6
6
|
import { handlesGridChange } from './data/events/onGridChange.js';
|
|
@@ -8,12 +8,14 @@ import { handlesGridResize } from './data/events/onGridResize.js';
|
|
|
8
8
|
import { handlesSetGrid } from './data/events/onSetGrid.js';
|
|
9
9
|
import { handlesSymbolDisplay } from './data/events/onSymbolDisplay.js';
|
|
10
10
|
import { handlesSymbolValidation } from './data/events/onSymbolValidation.js';
|
|
11
|
-
import GridData from './data/grid.js';
|
|
11
|
+
import GridData, { NEIGHBOR_OFFSETS } from './data/grid.js';
|
|
12
12
|
import GridConnections from './data/gridConnections.js';
|
|
13
|
+
import GridZones from './data/gridZones.js';
|
|
13
14
|
import Instruction from './data/instruction.js';
|
|
14
15
|
import { COMPARISONS, Color, Comparison, DIRECTIONS, Direction, MajorRule, Mode, ORIENTATIONS, Orientation, State, directionToggle, orientationToggle } from './data/primitives.js';
|
|
15
16
|
import { MetadataSchema, PuzzleSchema } from './data/puzzle.js';
|
|
16
17
|
import BanPatternRule from './data/rules/banPatternRule.js';
|
|
18
|
+
import CellCountPerZoneRule from './data/rules/cellCountPerZoneRule.js';
|
|
17
19
|
import CellCountRule from './data/rules/cellCountRule.js';
|
|
18
20
|
import CompletePatternRule from './data/rules/completePatternRule.js';
|
|
19
21
|
import ConnectAllRule from './data/rules/connectAllRule.js';
|
|
@@ -96,4 +98,4 @@ import ViewpointSymbol from './data/symbols/viewpointSymbol.js';
|
|
|
96
98
|
import TileData from './data/tile.js';
|
|
97
99
|
import TileConnections from './data/tileConnections.js';
|
|
98
100
|
import validateGrid, { aggregateState, applyFinalOverrides } from './data/validate.js';
|
|
99
|
-
export { ConfigType, configEquals, Configurable, CachedAccess, allEqual, array, directionToRotation, escape, maxBy, minBy, move, orientationToRotation, resize, unescape, isEventHandler, handlesFinalValidation, handlesGridChange, handlesGridResize, handlesSetGrid, handlesSymbolDisplay, handlesSymbolValidation, GridData, GridConnections, Instruction, COMPARISONS, Color, Comparison, DIRECTIONS, Direction, MajorRule, Mode, ORIENTATIONS, Orientation, State, directionToggle, orientationToggle, MetadataSchema, PuzzleSchema, BanPatternRule, CellCountRule, CompletePatternRule, ConnectAllRule, CustomRule, ForesightRule, allRules, ControlLine, Row, MusicGridRule, MysteryRule, OffByXRule, PerfectionRule, RegionAreaRule, RegionShapeRule, Rule, SameShapeRule, SymbolsPerRegionRule, UndercluedRule, UniqueShapeRule, 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, Solver, UndercluedSolver, 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, };
|
|
101
|
+
export { ConfigType, configEquals, Configurable, CachedAccess, allEqual, array, directionToRotation, escape, isSameEdge, maxBy, minBy, move, orientationToRotation, resize, unescape, isEventHandler, handlesFinalValidation, handlesGridChange, handlesGridResize, handlesSetGrid, handlesSymbolDisplay, handlesSymbolValidation, GridData, NEIGHBOR_OFFSETS, GridConnections, GridZones, Instruction, COMPARISONS, Color, Comparison, DIRECTIONS, Direction, MajorRule, Mode, ORIENTATIONS, Orientation, State, directionToggle, orientationToggle, MetadataSchema, PuzzleSchema, BanPatternRule, CellCountPerZoneRule, CellCountRule, CompletePatternRule, ConnectAllRule, CustomRule, ForesightRule, allRules, ControlLine, Row, MusicGridRule, MysteryRule, OffByXRule, PerfectionRule, RegionAreaRule, RegionShapeRule, Rule, SameShapeRule, SymbolsPerRegionRule, UndercluedRule, UniqueShapeRule, 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, Solver, UndercluedSolver, 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, };
|
package/dist/index.js
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
// noinspection JSUnusedGlobalSymbols
|
|
4
4
|
import { ConfigType, configEquals } from './data/config.js';
|
|
5
5
|
import Configurable from './data/configurable.js';
|
|
6
|
-
import { CachedAccess, allEqual, array, directionToRotation, escape, maxBy, minBy, move, orientationToRotation, resize, unescape } from './data/dataHelper.js';
|
|
6
|
+
import { CachedAccess, allEqual, array, directionToRotation, escape, isSameEdge, maxBy, minBy, move, orientationToRotation, resize, unescape } from './data/dataHelper.js';
|
|
7
7
|
import { isEventHandler } from './data/events/eventHelper.js';
|
|
8
8
|
import { handlesFinalValidation } from './data/events/onFinalValidation.js';
|
|
9
9
|
import { handlesGridChange } from './data/events/onGridChange.js';
|
|
@@ -11,12 +11,14 @@ import { handlesGridResize } from './data/events/onGridResize.js';
|
|
|
11
11
|
import { handlesSetGrid } from './data/events/onSetGrid.js';
|
|
12
12
|
import { handlesSymbolDisplay } from './data/events/onSymbolDisplay.js';
|
|
13
13
|
import { handlesSymbolValidation } from './data/events/onSymbolValidation.js';
|
|
14
|
-
import GridData from './data/grid.js';
|
|
14
|
+
import GridData, { NEIGHBOR_OFFSETS } from './data/grid.js';
|
|
15
15
|
import GridConnections from './data/gridConnections.js';
|
|
16
|
+
import GridZones from './data/gridZones.js';
|
|
16
17
|
import Instruction from './data/instruction.js';
|
|
17
18
|
import { COMPARISONS, Color, Comparison, DIRECTIONS, Direction, MajorRule, Mode, ORIENTATIONS, Orientation, State, directionToggle, orientationToggle } from './data/primitives.js';
|
|
18
19
|
import { MetadataSchema, PuzzleSchema } from './data/puzzle.js';
|
|
19
20
|
import BanPatternRule from './data/rules/banPatternRule.js';
|
|
21
|
+
import CellCountPerZoneRule from './data/rules/cellCountPerZoneRule.js';
|
|
20
22
|
import CellCountRule from './data/rules/cellCountRule.js';
|
|
21
23
|
import CompletePatternRule from './data/rules/completePatternRule.js';
|
|
22
24
|
import ConnectAllRule from './data/rules/connectAllRule.js';
|
|
@@ -99,4 +101,4 @@ import ViewpointSymbol from './data/symbols/viewpointSymbol.js';
|
|
|
99
101
|
import TileData from './data/tile.js';
|
|
100
102
|
import TileConnections from './data/tileConnections.js';
|
|
101
103
|
import validateGrid, { aggregateState, applyFinalOverrides } from './data/validate.js';
|
|
102
|
-
export { ConfigType, configEquals, Configurable, CachedAccess, allEqual, array, directionToRotation, escape, maxBy, minBy, move, orientationToRotation, resize, unescape, isEventHandler, handlesFinalValidation, handlesGridChange, handlesGridResize, handlesSetGrid, handlesSymbolDisplay, handlesSymbolValidation, GridData, GridConnections, Instruction, COMPARISONS, Color, Comparison, DIRECTIONS, Direction, MajorRule, Mode, ORIENTATIONS, Orientation, State, directionToggle, orientationToggle, MetadataSchema, PuzzleSchema, BanPatternRule, CellCountRule, CompletePatternRule, ConnectAllRule, CustomRule, ForesightRule, allRules, ControlLine, Row, MusicGridRule, MysteryRule, OffByXRule, PerfectionRule, RegionAreaRule, RegionShapeRule, Rule, SameShapeRule, SymbolsPerRegionRule, UndercluedRule, UniqueShapeRule, 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, Solver, UndercluedSolver, 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, };
|
|
104
|
+
export { ConfigType, configEquals, Configurable, CachedAccess, allEqual, array, directionToRotation, escape, isSameEdge, maxBy, minBy, move, orientationToRotation, resize, unescape, isEventHandler, handlesFinalValidation, handlesGridChange, handlesGridResize, handlesSetGrid, handlesSymbolDisplay, handlesSymbolValidation, GridData, NEIGHBOR_OFFSETS, GridConnections, GridZones, Instruction, COMPARISONS, Color, Comparison, DIRECTIONS, Direction, MajorRule, Mode, ORIENTATIONS, Orientation, State, directionToggle, orientationToggle, MetadataSchema, PuzzleSchema, BanPatternRule, CellCountPerZoneRule, CellCountRule, CompletePatternRule, ConnectAllRule, CustomRule, ForesightRule, allRules, ControlLine, Row, MusicGridRule, MysteryRule, OffByXRule, PerfectionRule, RegionAreaRule, RegionShapeRule, Rule, SameShapeRule, SymbolsPerRegionRule, UndercluedRule, UniqueShapeRule, 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, Solver, UndercluedSolver, 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, };
|