@logic-pad/core 0.3.0 → 0.4.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 +47 -1
- package/dist/data/config.d.ts +7 -3
- package/dist/data/config.js +9 -0
- package/dist/data/dataHelper.d.ts +8 -1
- package/dist/data/dataHelper.js +10 -0
- package/dist/data/grid.d.ts +1 -0
- package/dist/data/grid.js +2 -5
- package/dist/data/gridConnections.js +1 -4
- package/dist/data/rules/cellCountPerZoneRule.d.ts +33 -0
- package/dist/data/rules/cellCountPerZoneRule.js +183 -0
- package/dist/data/rules/rules.gen.d.ts +1 -0
- package/dist/data/rules/rules.gen.js +1 -0
- package/dist/data/serializer/serializer_v0.js +21 -0
- package/dist/index.d.ts +4 -3
- package/dist/index.js +4 -3
- package/package.json +1 -1
|
@@ -188,6 +188,13 @@ declare global {
|
|
|
188
188
|
x: number;
|
|
189
189
|
y: number;
|
|
190
190
|
};
|
|
191
|
+
/**
|
|
192
|
+
* Check if two edges are the same, regardless of direction.
|
|
193
|
+
* @param a The first edge.
|
|
194
|
+
* @param b The second edge.
|
|
195
|
+
* @returns Whether the edges are the same.
|
|
196
|
+
*/
|
|
197
|
+
export declare function isSameEdge(a: Edge, b: Edge): boolean;
|
|
191
198
|
/**
|
|
192
199
|
* Convert the given direction to a rotation in degrees.
|
|
193
200
|
* @param direction The direction to convert.
|
|
@@ -577,6 +584,7 @@ declare global {
|
|
|
577
584
|
get validateWithSolution(): boolean;
|
|
578
585
|
get isSingleton(): boolean;
|
|
579
586
|
}
|
|
587
|
+
export declare const NEIGHBOR_OFFSETS: Position$1[];
|
|
580
588
|
export declare class GridData {
|
|
581
589
|
readonly width: number;
|
|
582
590
|
readonly height: number;
|
|
@@ -1031,6 +1039,7 @@ declare global {
|
|
|
1031
1039
|
ControlLines = 'controlLines',
|
|
1032
1040
|
NullableNote = 'nullableNote',
|
|
1033
1041
|
SolvePath = 'solvePath',
|
|
1042
|
+
Edges = 'edges',
|
|
1034
1043
|
}
|
|
1035
1044
|
export interface Config<T> {
|
|
1036
1045
|
readonly type: ConfigType;
|
|
@@ -1104,6 +1113,9 @@ declare global {
|
|
|
1104
1113
|
export interface SolvePathConfig extends Config<Position$1[]> {
|
|
1105
1114
|
readonly type: ConfigType.SolvePath;
|
|
1106
1115
|
}
|
|
1116
|
+
export interface EdgesConfig extends Config<Edge[]> {
|
|
1117
|
+
readonly type: ConfigType.Edges;
|
|
1118
|
+
}
|
|
1107
1119
|
export type AnyConfig =
|
|
1108
1120
|
| BooleanConfig
|
|
1109
1121
|
| NullableBooleanConfig
|
|
@@ -1122,7 +1134,8 @@ declare global {
|
|
|
1122
1134
|
| IconConfig
|
|
1123
1135
|
| ControlLinesConfig
|
|
1124
1136
|
| NullableNoteConfig
|
|
1125
|
-
| SolvePathConfig
|
|
1137
|
+
| SolvePathConfig
|
|
1138
|
+
| EdgesConfig;
|
|
1126
1139
|
/**
|
|
1127
1140
|
* Compare two config values for equality, using an appropriate method for the config type.
|
|
1128
1141
|
*
|
|
@@ -1332,6 +1345,39 @@ declare global {
|
|
|
1332
1345
|
copyWith({ pattern }: { pattern?: GridData }): this;
|
|
1333
1346
|
withPattern(pattern: GridData): this;
|
|
1334
1347
|
}
|
|
1348
|
+
export declare class CellCountPerZoneRule extends Rule {
|
|
1349
|
+
readonly color: Color;
|
|
1350
|
+
readonly edges: readonly Edge[];
|
|
1351
|
+
private static readonly CONFIGS;
|
|
1352
|
+
private static readonly EXAMPLE_GRID_LIGHT;
|
|
1353
|
+
private static readonly EXAMPLE_GRID_DARK;
|
|
1354
|
+
private static readonly EXAMPLE_GRID_GRAY;
|
|
1355
|
+
private static readonly SEARCH_VARIANTS;
|
|
1356
|
+
/**
|
|
1357
|
+
* **Every zone has the same number of <color> cells.**
|
|
1358
|
+
*
|
|
1359
|
+
* @param color - The color of the cells to count.
|
|
1360
|
+
* @param edges - The edges of the zones to count.
|
|
1361
|
+
*/
|
|
1362
|
+
constructor(color: Color, edges: readonly Edge[]);
|
|
1363
|
+
get id(): string;
|
|
1364
|
+
get explanation(): string;
|
|
1365
|
+
get configs(): readonly AnyConfig[] | null;
|
|
1366
|
+
createExampleGrid(): GridData;
|
|
1367
|
+
get searchVariants(): SearchVariant[];
|
|
1368
|
+
validateGrid(grid: GridData): RuleState;
|
|
1369
|
+
copyWith({
|
|
1370
|
+
color,
|
|
1371
|
+
edges,
|
|
1372
|
+
}: {
|
|
1373
|
+
color?: Color;
|
|
1374
|
+
edges?: readonly Edge[];
|
|
1375
|
+
}): this;
|
|
1376
|
+
withColor(color: Color): this;
|
|
1377
|
+
withEdges(
|
|
1378
|
+
edges: readonly Edge[] | ((edges: readonly Edge[]) => readonly Edge[])
|
|
1379
|
+
): this;
|
|
1380
|
+
}
|
|
1335
1381
|
export declare class CellCountRule extends Rule {
|
|
1336
1382
|
readonly color: Color;
|
|
1337
1383
|
readonly count: number;
|
package/dist/data/config.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import GridData from './grid.js';
|
|
2
|
-
import { Color, Comparison, Direction, DirectionToggle, Orientation, OrientationToggle, Position } from './primitives.js';
|
|
2
|
+
import { Color, Comparison, Direction, DirectionToggle, Edge, Orientation, OrientationToggle, Position } from './primitives.js';
|
|
3
3
|
import { ControlLine } from './rules/musicControlLine.js';
|
|
4
4
|
export declare enum ConfigType {
|
|
5
5
|
Boolean = "boolean",
|
|
@@ -19,7 +19,8 @@ export declare enum ConfigType {
|
|
|
19
19
|
Icon = "icon",
|
|
20
20
|
ControlLines = "controlLines",
|
|
21
21
|
NullableNote = "nullableNote",
|
|
22
|
-
SolvePath = "solvePath"
|
|
22
|
+
SolvePath = "solvePath",
|
|
23
|
+
Edges = "edges"
|
|
23
24
|
}
|
|
24
25
|
export interface Config<T> {
|
|
25
26
|
readonly type: ConfigType;
|
|
@@ -93,7 +94,10 @@ export interface NullableNoteConfig extends Config<string | null> {
|
|
|
93
94
|
export interface SolvePathConfig extends Config<Position[]> {
|
|
94
95
|
readonly type: ConfigType.SolvePath;
|
|
95
96
|
}
|
|
96
|
-
export
|
|
97
|
+
export interface EdgesConfig extends Config<Edge[]> {
|
|
98
|
+
readonly type: ConfigType.Edges;
|
|
99
|
+
}
|
|
100
|
+
export type AnyConfig = BooleanConfig | NullableBooleanConfig | NumberConfig | NullableNumberConfig | StringConfig | ColorConfig | ComparisonConfig | DirectionConfig | DirectionToggleConfig | OrientationConfig | OrientationToggleConfig | TileConfig | GridConfig | NullableGridConfig | IconConfig | ControlLinesConfig | NullableNoteConfig | SolvePathConfig | EdgesConfig;
|
|
97
101
|
/**
|
|
98
102
|
* Compare two config values for equality, using an appropriate method for the config type.
|
|
99
103
|
*
|
package/dist/data/config.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { isSameEdge } from './dataHelper.js';
|
|
1
2
|
import { DIRECTIONS, ORIENTATIONS, } from './primitives.js';
|
|
2
3
|
export var ConfigType;
|
|
3
4
|
(function (ConfigType) {
|
|
@@ -19,6 +20,7 @@ export var ConfigType;
|
|
|
19
20
|
ConfigType["ControlLines"] = "controlLines";
|
|
20
21
|
ConfigType["NullableNote"] = "nullableNote";
|
|
21
22
|
ConfigType["SolvePath"] = "solvePath";
|
|
23
|
+
ConfigType["Edges"] = "edges";
|
|
22
24
|
})(ConfigType || (ConfigType = {}));
|
|
23
25
|
/**
|
|
24
26
|
* Compare two config values for equality, using an appropriate method for the config type.
|
|
@@ -59,5 +61,12 @@ export function configEquals(type, a, b) {
|
|
|
59
61
|
return false;
|
|
60
62
|
return aPath.every((pos, i) => pos.x === bPath[i].x && pos.y === bPath[i].y);
|
|
61
63
|
}
|
|
64
|
+
if (type === ConfigType.Edges) {
|
|
65
|
+
const aEdges = a;
|
|
66
|
+
const bEdges = b;
|
|
67
|
+
if (aEdges.length !== bEdges.length)
|
|
68
|
+
return false;
|
|
69
|
+
return aEdges.every(aEdge => bEdges.some(bEdge => isSameEdge(aEdge, bEdge)));
|
|
70
|
+
}
|
|
62
71
|
return a === b;
|
|
63
72
|
}
|
|
@@ -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,6 +7,7 @@ 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
|
+
export declare const NEIGHBOR_OFFSETS: Position[];
|
|
10
11
|
export default class GridData {
|
|
11
12
|
readonly width: number;
|
|
12
13
|
readonly height: number;
|
package/dist/data/grid.js
CHANGED
|
@@ -5,7 +5,7 @@ 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
|
-
const NEIGHBOR_OFFSETS = [
|
|
8
|
+
export const NEIGHBOR_OFFSETS = [
|
|
9
9
|
{ x: -1, y: 0 },
|
|
10
10
|
{ x: 1, y: 0 },
|
|
11
11
|
{ x: 0, y: -1 },
|
|
@@ -573,10 +573,7 @@ export default class GridData {
|
|
|
573
573
|
return ret;
|
|
574
574
|
for (const offset of NEIGHBOR_OFFSETS) {
|
|
575
575
|
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) {
|
|
576
|
+
if (this.isPositionValid(next.x, next.y)) {
|
|
580
577
|
const nextTile = this.getTile(next.x, next.y);
|
|
581
578
|
if (nextTile.exists && predicate(nextTile))
|
|
582
579
|
stack.push(next);
|
|
@@ -1,8 +1,5 @@
|
|
|
1
|
+
import { isSameEdge } from './dataHelper.js';
|
|
1
2
|
import TileConnections from './tileConnections.js';
|
|
2
|
-
function isSameEdge(a, b) {
|
|
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
3
|
export default class GridConnections {
|
|
7
4
|
constructor(edges) {
|
|
8
5
|
Object.defineProperty(this, "edges", {
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { AnyConfig } from '../config.js';
|
|
2
|
+
import GridData from '../grid.js';
|
|
3
|
+
import { Color, Edge, RuleState } from '../primitives.js';
|
|
4
|
+
import Rule, { SearchVariant } from './rule.js';
|
|
5
|
+
export default class CellCountPerZoneRule extends Rule {
|
|
6
|
+
readonly color: Color;
|
|
7
|
+
readonly edges: readonly Edge[];
|
|
8
|
+
private static readonly CONFIGS;
|
|
9
|
+
private static readonly EXAMPLE_GRID_LIGHT;
|
|
10
|
+
private static readonly EXAMPLE_GRID_DARK;
|
|
11
|
+
private static readonly EXAMPLE_GRID_GRAY;
|
|
12
|
+
private static readonly SEARCH_VARIANTS;
|
|
13
|
+
/**
|
|
14
|
+
* **Every zone has the same number of <color> cells.**
|
|
15
|
+
*
|
|
16
|
+
* @param color - The color of the cells to count.
|
|
17
|
+
* @param edges - The edges of the zones to count.
|
|
18
|
+
*/
|
|
19
|
+
constructor(color: Color, edges: readonly Edge[]);
|
|
20
|
+
get id(): string;
|
|
21
|
+
get explanation(): string;
|
|
22
|
+
get configs(): readonly AnyConfig[] | null;
|
|
23
|
+
createExampleGrid(): GridData;
|
|
24
|
+
get searchVariants(): SearchVariant[];
|
|
25
|
+
validateGrid(grid: GridData): RuleState;
|
|
26
|
+
copyWith({ color, edges, }: {
|
|
27
|
+
color?: Color;
|
|
28
|
+
edges?: readonly Edge[];
|
|
29
|
+
}): this;
|
|
30
|
+
withColor(color: Color): this;
|
|
31
|
+
withEdges(edges: readonly Edge[] | ((edges: readonly Edge[]) => readonly Edge[])): this;
|
|
32
|
+
}
|
|
33
|
+
export declare const instance: CellCountPerZoneRule;
|
|
@@ -0,0 +1,183 @@
|
|
|
1
|
+
import { ConfigType } from '../config.js';
|
|
2
|
+
import { array } from '../dataHelper.js';
|
|
3
|
+
import GridData, { NEIGHBOR_OFFSETS } from '../grid.js';
|
|
4
|
+
import GridConnections from '../gridConnections.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
|
+
* @param edges - The edges of the zones to count.
|
|
13
|
+
*/
|
|
14
|
+
constructor(color, edges) {
|
|
15
|
+
super();
|
|
16
|
+
Object.defineProperty(this, "color", {
|
|
17
|
+
enumerable: true,
|
|
18
|
+
configurable: true,
|
|
19
|
+
writable: true,
|
|
20
|
+
value: color
|
|
21
|
+
});
|
|
22
|
+
Object.defineProperty(this, "edges", {
|
|
23
|
+
enumerable: true,
|
|
24
|
+
configurable: true,
|
|
25
|
+
writable: true,
|
|
26
|
+
value: edges
|
|
27
|
+
});
|
|
28
|
+
this.color = color;
|
|
29
|
+
this.edges = GridConnections.deduplicateEdges(edges);
|
|
30
|
+
}
|
|
31
|
+
get id() {
|
|
32
|
+
return `zone_cell_count`;
|
|
33
|
+
}
|
|
34
|
+
get explanation() {
|
|
35
|
+
return `Every zone has the same number of ${this.color} cells`;
|
|
36
|
+
}
|
|
37
|
+
get configs() {
|
|
38
|
+
return CellCountPerZoneRule.CONFIGS;
|
|
39
|
+
}
|
|
40
|
+
createExampleGrid() {
|
|
41
|
+
if (this.color === Color.Light) {
|
|
42
|
+
return CellCountPerZoneRule.EXAMPLE_GRID_LIGHT;
|
|
43
|
+
}
|
|
44
|
+
else if (this.color === Color.Dark) {
|
|
45
|
+
return CellCountPerZoneRule.EXAMPLE_GRID_DARK;
|
|
46
|
+
}
|
|
47
|
+
else {
|
|
48
|
+
return CellCountPerZoneRule.EXAMPLE_GRID_GRAY;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
get searchVariants() {
|
|
52
|
+
return CellCountPerZoneRule.SEARCH_VARIANTS;
|
|
53
|
+
}
|
|
54
|
+
validateGrid(grid) {
|
|
55
|
+
let complete = true;
|
|
56
|
+
const visited = array(grid.width, grid.height, (i, j) => !grid.getTile(i, j).exists);
|
|
57
|
+
const zones = [];
|
|
58
|
+
while (true) {
|
|
59
|
+
const seed = grid.find((_tile, x, y) => !visited[y][x]);
|
|
60
|
+
if (!seed)
|
|
61
|
+
break;
|
|
62
|
+
const zone = {
|
|
63
|
+
positions: [],
|
|
64
|
+
completed: 0,
|
|
65
|
+
possible: 0,
|
|
66
|
+
};
|
|
67
|
+
const stack = [seed];
|
|
68
|
+
while (stack.length > 0) {
|
|
69
|
+
const { x, y } = stack.pop();
|
|
70
|
+
if (visited[y][x])
|
|
71
|
+
continue;
|
|
72
|
+
visited[y][x] = true;
|
|
73
|
+
zone.positions.push({ x, y });
|
|
74
|
+
if (grid.getTile(x, y).color === this.color) {
|
|
75
|
+
zone.completed++;
|
|
76
|
+
}
|
|
77
|
+
else if (grid.getTile(x, y).color === Color.Gray) {
|
|
78
|
+
zone.possible++;
|
|
79
|
+
complete = false;
|
|
80
|
+
}
|
|
81
|
+
for (const offset of NEIGHBOR_OFFSETS) {
|
|
82
|
+
const next = { x: x + offset.x, y: y + offset.y };
|
|
83
|
+
if (!this.edges.some(e => (e.x1 === x &&
|
|
84
|
+
e.y1 === y &&
|
|
85
|
+
e.x2 === next.x &&
|
|
86
|
+
e.y2 === next.y) ||
|
|
87
|
+
(e.x1 === next.x && e.y1 === next.y && e.x2 === x && e.y2 === y))) {
|
|
88
|
+
const nextTile = grid.getTile(next.x, next.y);
|
|
89
|
+
if (nextTile.exists) {
|
|
90
|
+
stack.push(next);
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
zones.push(zone);
|
|
96
|
+
}
|
|
97
|
+
if (zones.length <= 1) {
|
|
98
|
+
return { state: complete ? State.Satisfied : State.Incomplete };
|
|
99
|
+
}
|
|
100
|
+
else {
|
|
101
|
+
const errorZone = zones.find(z => zones.some(zz => zz !== z &&
|
|
102
|
+
(zz.completed > z.completed + z.possible ||
|
|
103
|
+
zz.completed + zz.possible < z.completed)));
|
|
104
|
+
if (errorZone) {
|
|
105
|
+
return {
|
|
106
|
+
state: State.Error,
|
|
107
|
+
positions: errorZone.positions,
|
|
108
|
+
};
|
|
109
|
+
}
|
|
110
|
+
else {
|
|
111
|
+
return { state: complete ? State.Satisfied : State.Incomplete };
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
copyWith({ color, edges, }) {
|
|
116
|
+
return new CellCountPerZoneRule(color ?? this.color, edges ?? this.edges);
|
|
117
|
+
}
|
|
118
|
+
withColor(color) {
|
|
119
|
+
return this.copyWith({ color });
|
|
120
|
+
}
|
|
121
|
+
withEdges(edges) {
|
|
122
|
+
return this.copyWith({
|
|
123
|
+
edges: typeof edges === 'function' ? edges(this.edges) : edges,
|
|
124
|
+
});
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
Object.defineProperty(CellCountPerZoneRule, "CONFIGS", {
|
|
128
|
+
enumerable: true,
|
|
129
|
+
configurable: true,
|
|
130
|
+
writable: true,
|
|
131
|
+
value: Object.freeze([
|
|
132
|
+
{
|
|
133
|
+
type: ConfigType.Color,
|
|
134
|
+
default: Color.Light,
|
|
135
|
+
allowGray: true,
|
|
136
|
+
field: 'color',
|
|
137
|
+
description: 'Color',
|
|
138
|
+
configurable: true,
|
|
139
|
+
},
|
|
140
|
+
{
|
|
141
|
+
type: ConfigType.Edges,
|
|
142
|
+
default: [],
|
|
143
|
+
field: 'edges',
|
|
144
|
+
description: 'Edges',
|
|
145
|
+
configurable: false,
|
|
146
|
+
},
|
|
147
|
+
])
|
|
148
|
+
});
|
|
149
|
+
Object.defineProperty(CellCountPerZoneRule, "EXAMPLE_GRID_LIGHT", {
|
|
150
|
+
enumerable: true,
|
|
151
|
+
configurable: true,
|
|
152
|
+
writable: true,
|
|
153
|
+
value: Object.freeze(GridData.create(['bwbbb', 'wbbwb', 'bbbwb', 'bwbwb']).addRule(new CellCountPerZoneRule(Color.Light, [
|
|
154
|
+
{ x1: 0, y1: 1, x2: 0, y2: 2 },
|
|
155
|
+
{ x1: 1, y1: 1, x2: 1, y2: 2 },
|
|
156
|
+
{ x1: 2, y1: 1, x2: 2, y2: 2 },
|
|
157
|
+
{ x1: 3, y1: 1, x2: 3, y2: 2 },
|
|
158
|
+
{ x1: 4, y1: 1, x2: 4, y2: 2 },
|
|
159
|
+
])))
|
|
160
|
+
});
|
|
161
|
+
Object.defineProperty(CellCountPerZoneRule, "EXAMPLE_GRID_DARK", {
|
|
162
|
+
enumerable: true,
|
|
163
|
+
configurable: true,
|
|
164
|
+
writable: true,
|
|
165
|
+
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)))))
|
|
166
|
+
});
|
|
167
|
+
Object.defineProperty(CellCountPerZoneRule, "EXAMPLE_GRID_GRAY", {
|
|
168
|
+
enumerable: true,
|
|
169
|
+
configurable: true,
|
|
170
|
+
writable: true,
|
|
171
|
+
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)))))
|
|
172
|
+
});
|
|
173
|
+
Object.defineProperty(CellCountPerZoneRule, "SEARCH_VARIANTS", {
|
|
174
|
+
enumerable: true,
|
|
175
|
+
configurable: true,
|
|
176
|
+
writable: true,
|
|
177
|
+
value: [
|
|
178
|
+
new CellCountPerZoneRule(Color.Light, []).searchVariant(),
|
|
179
|
+
new CellCountPerZoneRule(Color.Dark, []).searchVariant(),
|
|
180
|
+
]
|
|
181
|
+
});
|
|
182
|
+
export default CellCountPerZoneRule;
|
|
183
|
+
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';
|
|
@@ -167,6 +167,12 @@ export default class SerializerV0 extends SerializerBase {
|
|
|
167
167
|
escape(instruction[config.field]
|
|
168
168
|
?.map(pos => `${pos.x}_${pos.y}`)
|
|
169
169
|
.join('/') ?? ''));
|
|
170
|
+
case ConfigType.Edges:
|
|
171
|
+
return (config.field +
|
|
172
|
+
'=' +
|
|
173
|
+
instruction[config.field]
|
|
174
|
+
.map(edge => `${edge.x1}_${edge.y1}_${edge.x2}_${edge.y2}`)
|
|
175
|
+
.join('/'));
|
|
170
176
|
}
|
|
171
177
|
}
|
|
172
178
|
parseConfig(configs, entry) {
|
|
@@ -235,6 +241,21 @@ export default class SerializerV0 extends SerializerBase {
|
|
|
235
241
|
return { x: Number(x), y: Number(y) };
|
|
236
242
|
}),
|
|
237
243
|
];
|
|
244
|
+
case ConfigType.Edges:
|
|
245
|
+
return [
|
|
246
|
+
config.field,
|
|
247
|
+
value === ''
|
|
248
|
+
? []
|
|
249
|
+
: value.split('/').map(edge => {
|
|
250
|
+
const [x1, y1, x2, y2] = edge.split('_');
|
|
251
|
+
return {
|
|
252
|
+
x1: Number(x1),
|
|
253
|
+
y1: Number(y1),
|
|
254
|
+
x2: Number(x2),
|
|
255
|
+
y2: Number(y2),
|
|
256
|
+
};
|
|
257
|
+
}),
|
|
258
|
+
];
|
|
238
259
|
}
|
|
239
260
|
}
|
|
240
261
|
stringifyInstruction(instruction) {
|
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,13 @@ 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
13
|
import Instruction from './data/instruction.js';
|
|
14
14
|
import { COMPARISONS, Color, Comparison, DIRECTIONS, Direction, MajorRule, Mode, ORIENTATIONS, Orientation, State, directionToggle, orientationToggle } from './data/primitives.js';
|
|
15
15
|
import { MetadataSchema, PuzzleSchema } from './data/puzzle.js';
|
|
16
16
|
import BanPatternRule from './data/rules/banPatternRule.js';
|
|
17
|
+
import CellCountPerZoneRule from './data/rules/cellCountPerZoneRule.js';
|
|
17
18
|
import CellCountRule from './data/rules/cellCountRule.js';
|
|
18
19
|
import CompletePatternRule from './data/rules/completePatternRule.js';
|
|
19
20
|
import ConnectAllRule from './data/rules/connectAllRule.js';
|
|
@@ -96,4 +97,4 @@ import ViewpointSymbol from './data/symbols/viewpointSymbol.js';
|
|
|
96
97
|
import TileData from './data/tile.js';
|
|
97
98
|
import TileConnections from './data/tileConnections.js';
|
|
98
99
|
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, };
|
|
100
|
+
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, 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,13 @@ 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
16
|
import Instruction from './data/instruction.js';
|
|
17
17
|
import { COMPARISONS, Color, Comparison, DIRECTIONS, Direction, MajorRule, Mode, ORIENTATIONS, Orientation, State, directionToggle, orientationToggle } from './data/primitives.js';
|
|
18
18
|
import { MetadataSchema, PuzzleSchema } from './data/puzzle.js';
|
|
19
19
|
import BanPatternRule from './data/rules/banPatternRule.js';
|
|
20
|
+
import CellCountPerZoneRule from './data/rules/cellCountPerZoneRule.js';
|
|
20
21
|
import CellCountRule from './data/rules/cellCountRule.js';
|
|
21
22
|
import CompletePatternRule from './data/rules/completePatternRule.js';
|
|
22
23
|
import ConnectAllRule from './data/rules/connectAllRule.js';
|
|
@@ -99,4 +100,4 @@ import ViewpointSymbol from './data/symbols/viewpointSymbol.js';
|
|
|
99
100
|
import TileData from './data/tile.js';
|
|
100
101
|
import TileConnections from './data/tileConnections.js';
|
|
101
102
|
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, };
|
|
103
|
+
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, 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, };
|