@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.
@@ -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 &lt;color&gt; 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;
@@ -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 type AnyConfig = BooleanConfig | NullableBooleanConfig | NumberConfig | NullableNumberConfig | StringConfig | ColorConfig | ComparisonConfig | DirectionConfig | DirectionToggleConfig | OrientationConfig | OrientationToggleConfig | TileConfig | GridConfig | NullableGridConfig | IconConfig | ControlLinesConfig | NullableNoteConfig | SolvePathConfig;
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
  *
@@ -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.
@@ -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.
@@ -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 >= 0 &&
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 &lt;color&gt; 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 &lt;color&gt; 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, };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@logic-pad/core",
3
- "version": "0.3.0",
3
+ "version": "0.4.0",
4
4
  "type": "module",
5
5
  "files": [
6
6
  "dist",