@logic-pad/core 0.17.1 → 0.19.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 +41 -46
- package/dist/data/grid.d.ts +2 -18
- package/dist/data/grid.js +54 -30
- package/dist/data/solver/backtrack/backtrackWorker.js +6 -6
- package/dist/data/solver/universal/universalWorker.js +8 -8
- package/dist/data/symbols/houseSymbol.d.ts +11 -6
- package/dist/data/symbols/houseSymbol.js +41 -32
- package/package.json +1 -1
|
@@ -773,54 +773,36 @@ declare global {
|
|
|
773
773
|
connections?: GridConnections,
|
|
774
774
|
zones?: GridZones,
|
|
775
775
|
symbols?: ReadonlyMap<string, readonly Symbol$1[]>,
|
|
776
|
-
rules?: readonly Rule[]
|
|
776
|
+
rules?: readonly Rule[],
|
|
777
|
+
sanitize?: boolean,
|
|
778
|
+
triggerEvents?: boolean
|
|
777
779
|
): GridData;
|
|
778
780
|
/**
|
|
779
781
|
* Copy the current grid while modifying the provided properties.
|
|
780
782
|
* @param param0 The properties to modify.
|
|
781
783
|
* @returns The new grid with the modified properties.
|
|
782
784
|
*/
|
|
783
|
-
copyWith(
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
* @param param0 The properties to modify.
|
|
805
|
-
* @returns The new grid with the modified properties.
|
|
806
|
-
*/
|
|
807
|
-
fastCopyWith({
|
|
808
|
-
width,
|
|
809
|
-
height,
|
|
810
|
-
tiles,
|
|
811
|
-
connections,
|
|
812
|
-
zones,
|
|
813
|
-
symbols,
|
|
814
|
-
rules,
|
|
815
|
-
}: {
|
|
816
|
-
width?: number;
|
|
817
|
-
height?: number;
|
|
818
|
-
tiles?: readonly (readonly TileData[])[];
|
|
819
|
-
connections?: GridConnections;
|
|
820
|
-
zones?: GridZones;
|
|
821
|
-
symbols?: ReadonlyMap<string, readonly Symbol$1[]>;
|
|
822
|
-
rules?: readonly Rule[];
|
|
823
|
-
}): GridData;
|
|
785
|
+
copyWith(
|
|
786
|
+
{
|
|
787
|
+
width,
|
|
788
|
+
height,
|
|
789
|
+
tiles,
|
|
790
|
+
connections,
|
|
791
|
+
zones,
|
|
792
|
+
symbols,
|
|
793
|
+
rules,
|
|
794
|
+
}: {
|
|
795
|
+
width?: number;
|
|
796
|
+
height?: number;
|
|
797
|
+
tiles?: readonly (readonly TileData[])[];
|
|
798
|
+
connections?: GridConnections;
|
|
799
|
+
zones?: GridZones;
|
|
800
|
+
symbols?: ReadonlyMap<string, readonly Symbol$1[]>;
|
|
801
|
+
rules?: readonly Rule[];
|
|
802
|
+
},
|
|
803
|
+
sanitize?: boolean,
|
|
804
|
+
triggerEvents?: boolean
|
|
805
|
+
): GridData;
|
|
824
806
|
toArrayCoordinates(x: number, y: number): Position$1;
|
|
825
807
|
isPositionValid(x: number, y: number): boolean;
|
|
826
808
|
/**
|
|
@@ -3083,9 +3065,10 @@ declare global {
|
|
|
3083
3065
|
}): this;
|
|
3084
3066
|
withRevealLocation(revealLocation: boolean): this;
|
|
3085
3067
|
}
|
|
3086
|
-
export declare class HouseSymbol extends
|
|
3068
|
+
export declare class HouseSymbol extends NumberSymbol {
|
|
3087
3069
|
readonly x: number;
|
|
3088
3070
|
readonly y: number;
|
|
3071
|
+
readonly number: number;
|
|
3089
3072
|
readonly title = 'House';
|
|
3090
3073
|
private static readonly CONFIGS;
|
|
3091
3074
|
private static readonly EXAMPLE_GRID;
|
|
@@ -3094,14 +3077,26 @@ declare global {
|
|
|
3094
3077
|
*
|
|
3095
3078
|
* @param x - The x-coordinate of the symbol.
|
|
3096
3079
|
* @param y - The y-coordinate of the symbol.
|
|
3080
|
+
* @param number - The number of houses in this region.
|
|
3097
3081
|
*/
|
|
3098
|
-
constructor(x: number, y: number);
|
|
3082
|
+
constructor(x: number, y: number, number: number);
|
|
3099
3083
|
get id(): string;
|
|
3100
3084
|
get explanation(): string;
|
|
3101
3085
|
get configs(): readonly AnyConfig[] | null;
|
|
3102
3086
|
createExampleGrid(): GridData;
|
|
3103
|
-
|
|
3104
|
-
|
|
3087
|
+
countTiles(grid: GridData): {
|
|
3088
|
+
completed: number;
|
|
3089
|
+
possible: number;
|
|
3090
|
+
};
|
|
3091
|
+
copyWith({
|
|
3092
|
+
x,
|
|
3093
|
+
y,
|
|
3094
|
+
number,
|
|
3095
|
+
}: {
|
|
3096
|
+
x?: number;
|
|
3097
|
+
y?: number;
|
|
3098
|
+
number?: number;
|
|
3099
|
+
}): this;
|
|
3105
3100
|
}
|
|
3106
3101
|
export declare const allSymbols: Map<string, Symbol$1>;
|
|
3107
3102
|
export declare function aggregateState(
|
package/dist/data/grid.d.ts
CHANGED
|
@@ -57,7 +57,7 @@ export default class GridData {
|
|
|
57
57
|
* @param symbols The symbols in the grid.
|
|
58
58
|
* @param rules The rules of the grid.
|
|
59
59
|
*/
|
|
60
|
-
static create(width: number, height: number, tiles?: readonly (readonly TileData[])[], connections?: GridConnections, zones?: GridZones, symbols?: ReadonlyMap<string, readonly Symbol[]>, rules?: readonly Rule[]): GridData;
|
|
60
|
+
static create(width: number, height: number, tiles?: readonly (readonly TileData[])[], connections?: GridConnections, zones?: GridZones, symbols?: ReadonlyMap<string, readonly Symbol[]>, rules?: readonly Rule[], sanitize?: boolean, triggerEvents?: boolean): GridData;
|
|
61
61
|
/**
|
|
62
62
|
* Copy the current grid while modifying the provided properties.
|
|
63
63
|
* @param param0 The properties to modify.
|
|
@@ -71,23 +71,7 @@ export default class GridData {
|
|
|
71
71
|
zones?: GridZones;
|
|
72
72
|
symbols?: ReadonlyMap<string, readonly Symbol[]>;
|
|
73
73
|
rules?: readonly Rule[];
|
|
74
|
-
}): GridData;
|
|
75
|
-
/**
|
|
76
|
-
* Copy the current grid while modifying the provided properties.
|
|
77
|
-
* Skip sanitization and event triggering for performance.
|
|
78
|
-
*
|
|
79
|
-
* @param param0 The properties to modify.
|
|
80
|
-
* @returns The new grid with the modified properties.
|
|
81
|
-
*/
|
|
82
|
-
fastCopyWith({ width, height, tiles, connections, zones, symbols, rules, }: {
|
|
83
|
-
width?: number;
|
|
84
|
-
height?: number;
|
|
85
|
-
tiles?: readonly (readonly TileData[])[];
|
|
86
|
-
connections?: GridConnections;
|
|
87
|
-
zones?: GridZones;
|
|
88
|
-
symbols?: ReadonlyMap<string, readonly Symbol[]>;
|
|
89
|
-
rules?: readonly Rule[];
|
|
90
|
-
}): GridData;
|
|
74
|
+
}, sanitize?: boolean, triggerEvents?: boolean): GridData;
|
|
91
75
|
toArrayCoordinates(x: number, y: number): Position;
|
|
92
76
|
isPositionValid(x: number, y: number): boolean;
|
|
93
77
|
/**
|
package/dist/data/grid.js
CHANGED
|
@@ -102,28 +102,62 @@ export default class GridData {
|
|
|
102
102
|
this.symbols = symbols ?? new Map();
|
|
103
103
|
this.rules = rules ?? [];
|
|
104
104
|
}
|
|
105
|
-
static create(arrayOrWidth, height, tiles, connections, zones, symbols, rules) {
|
|
105
|
+
static create(arrayOrWidth, height, tiles, connections, zones, symbols, rules, sanitize, triggerEvents) {
|
|
106
106
|
if (typeof arrayOrWidth === 'number') {
|
|
107
|
+
let hasGridChangeSymbols = false;
|
|
108
|
+
let hasGridChangeRules = false;
|
|
109
|
+
if (triggerEvents) {
|
|
110
|
+
symbols?.forEach(list => {
|
|
111
|
+
list.forEach(sym => {
|
|
112
|
+
if (handlesGridChange(sym)) {
|
|
113
|
+
hasGridChangeSymbols = true;
|
|
114
|
+
}
|
|
115
|
+
});
|
|
116
|
+
});
|
|
117
|
+
rules?.forEach(rule => {
|
|
118
|
+
if (handlesGridChange(rule)) {
|
|
119
|
+
hasGridChangeRules = true;
|
|
120
|
+
}
|
|
121
|
+
});
|
|
122
|
+
}
|
|
107
123
|
const newSymbols = symbols
|
|
108
|
-
?
|
|
124
|
+
? sanitize
|
|
125
|
+
? GridData.deduplicateSymbols(symbols)
|
|
126
|
+
: triggerEvents && hasGridChangeSymbols
|
|
127
|
+
? new Map([...symbols.entries()].map(([id, list]) => [id, list.slice()]))
|
|
128
|
+
: symbols
|
|
109
129
|
: new Map();
|
|
110
130
|
// do not deduplicate all rules because it makes for bad editor experience
|
|
111
|
-
const newRules = rules
|
|
131
|
+
const newRules = rules
|
|
132
|
+
? sanitize
|
|
133
|
+
? GridData.deduplicateSingletonRules(rules)
|
|
134
|
+
: triggerEvents && hasGridChangeRules
|
|
135
|
+
? rules.slice()
|
|
136
|
+
: rules
|
|
137
|
+
: [];
|
|
112
138
|
const newGrid = new GridData(arrayOrWidth, height, tiles, connections
|
|
113
|
-
?
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
139
|
+
? sanitize
|
|
140
|
+
? GridConnections.validateEdges(connections, arrayOrWidth, height)
|
|
141
|
+
: connections
|
|
142
|
+
: undefined, zones
|
|
143
|
+
? sanitize
|
|
144
|
+
? GridZones.validateEdges(zones, arrayOrWidth, height)
|
|
145
|
+
: zones
|
|
146
|
+
: undefined, newSymbols, newRules);
|
|
147
|
+
if (triggerEvents) {
|
|
148
|
+
newSymbols.forEach(list => {
|
|
149
|
+
list.forEach((sym, i) => {
|
|
150
|
+
if (handlesGridChange(sym)) {
|
|
151
|
+
list[i] = sym.onGridChange(newGrid);
|
|
152
|
+
}
|
|
153
|
+
});
|
|
154
|
+
});
|
|
155
|
+
newRules.forEach((rule, i) => {
|
|
156
|
+
if (handlesGridChange(rule)) {
|
|
157
|
+
newRules[i] = rule.onGridChange(newGrid);
|
|
119
158
|
}
|
|
120
159
|
});
|
|
121
|
-
}
|
|
122
|
-
newRules.forEach((rule, i) => {
|
|
123
|
-
if (handlesGridChange(rule)) {
|
|
124
|
-
newRules[i] = rule.onGridChange(newGrid);
|
|
125
|
-
}
|
|
126
|
-
});
|
|
160
|
+
}
|
|
127
161
|
return newGrid;
|
|
128
162
|
}
|
|
129
163
|
else {
|
|
@@ -136,18 +170,8 @@ export default class GridData {
|
|
|
136
170
|
* @param param0 The properties to modify.
|
|
137
171
|
* @returns The new grid with the modified properties.
|
|
138
172
|
*/
|
|
139
|
-
copyWith({ width, height, tiles, connections, zones, symbols, rules, }) {
|
|
140
|
-
return GridData.create(width ?? this.width, height ?? this.height, tiles ?? this.tiles, connections ?? this.connections, zones ?? this.zones, symbols ?? this.symbols, rules ?? this.rules);
|
|
141
|
-
}
|
|
142
|
-
/**
|
|
143
|
-
* Copy the current grid while modifying the provided properties.
|
|
144
|
-
* Skip sanitization and event triggering for performance.
|
|
145
|
-
*
|
|
146
|
-
* @param param0 The properties to modify.
|
|
147
|
-
* @returns The new grid with the modified properties.
|
|
148
|
-
*/
|
|
149
|
-
fastCopyWith({ width, height, tiles, connections, zones, symbols, rules, }) {
|
|
150
|
-
return new GridData(width ?? this.width, height ?? this.height, tiles ?? this.tiles, connections ?? this.connections, zones ?? this.zones, symbols ?? this.symbols, rules ?? this.rules);
|
|
173
|
+
copyWith({ width, height, tiles, connections, zones, symbols, rules, }, sanitize = true, triggerEvents = true) {
|
|
174
|
+
return GridData.create(width ?? this.width, height ?? this.height, tiles ?? this.tiles, connections ?? this.connections, zones ?? this.zones, symbols ?? this.symbols, rules ?? this.rules, sanitize, triggerEvents);
|
|
151
175
|
}
|
|
152
176
|
toArrayCoordinates(x, y) {
|
|
153
177
|
// // This is the preferred way to compute tile coordinates, but for performance reasons we will just access the
|
|
@@ -733,7 +757,7 @@ export default class GridData {
|
|
|
733
757
|
this.iterateArea(position, t => t.color === from && (allowFixed || !t.fixed), (tile, x, y) => {
|
|
734
758
|
tiles[y][x] = tile.withColor(to);
|
|
735
759
|
});
|
|
736
|
-
return this.copyWith({ tiles });
|
|
760
|
+
return this.copyWith({ tiles }, false);
|
|
737
761
|
}
|
|
738
762
|
/**
|
|
739
763
|
* Flood fill all tiles with the given color to a new color, even if they are not connected.
|
|
@@ -748,7 +772,7 @@ export default class GridData {
|
|
|
748
772
|
tiles: this.tiles.map(row => row.map(tile => tile.color === from && (allowFixed || !tile.fixed)
|
|
749
773
|
? tile.withColor(to)
|
|
750
774
|
: tile)),
|
|
751
|
-
});
|
|
775
|
+
}, false);
|
|
752
776
|
}
|
|
753
777
|
/**
|
|
754
778
|
* Check if the grid has any instructions that require a custom solution.
|
|
@@ -778,7 +802,7 @@ export default class GridData {
|
|
|
778
802
|
});
|
|
779
803
|
if (!changed)
|
|
780
804
|
return this;
|
|
781
|
-
let newGrid = this.copyWith({ tiles: newTiles });
|
|
805
|
+
let newGrid = this.copyWith({ tiles: newTiles }, false);
|
|
782
806
|
this.symbols.forEach(list => {
|
|
783
807
|
list.forEach(symbol => {
|
|
784
808
|
if (handlesSetGrid(symbol)) {
|
|
@@ -231,9 +231,9 @@ function solveUnderclued(input) {
|
|
|
231
231
|
function search(x, y, tile, color) {
|
|
232
232
|
// count++;
|
|
233
233
|
// console.log(`Trying (${x}, ${y}) with ${color}`);
|
|
234
|
-
const newGrid = grid.
|
|
234
|
+
const newGrid = grid.copyWith({
|
|
235
235
|
tiles: grid.setTile(x, y, tile.withColor(color)),
|
|
236
|
-
});
|
|
236
|
+
}, false, false);
|
|
237
237
|
// Solve
|
|
238
238
|
let solution;
|
|
239
239
|
solveNormal(newGrid, sol => {
|
|
@@ -265,13 +265,13 @@ function solveUnderclued(input) {
|
|
|
265
265
|
if (!darkPossible && !lightPossible)
|
|
266
266
|
return null;
|
|
267
267
|
if (darkPossible && !lightPossible)
|
|
268
|
-
grid = grid.
|
|
268
|
+
grid = grid.copyWith({
|
|
269
269
|
tiles: grid.setTile(x, y, tile.withColor(Color.Dark)),
|
|
270
|
-
});
|
|
270
|
+
}, false, false);
|
|
271
271
|
if (!darkPossible && lightPossible)
|
|
272
|
-
grid = grid.
|
|
272
|
+
grid = grid.copyWith({
|
|
273
273
|
tiles: grid.setTile(x, y, tile.withColor(Color.Light)),
|
|
274
|
-
});
|
|
274
|
+
}, false, false);
|
|
275
275
|
}
|
|
276
276
|
}
|
|
277
277
|
// console.log(`Solve count: ${count}`);
|
|
@@ -7,9 +7,9 @@ function gridToRawTiles(grid) {
|
|
|
7
7
|
return array(grid.width, grid.height, (x, y) => grid.getTile(x, y).color);
|
|
8
8
|
}
|
|
9
9
|
function rawTilesToGrid(rawTiles, grid) {
|
|
10
|
-
return grid.
|
|
10
|
+
return grid.copyWith({
|
|
11
11
|
tiles: array(grid.width, grid.height, (x, y) => grid.getTile(x, y).withColor(rawTiles[y][x])),
|
|
12
|
-
});
|
|
12
|
+
}, false, false);
|
|
13
13
|
}
|
|
14
14
|
function getNextTile(grid, rawTiles) {
|
|
15
15
|
for (let y = 0; y < grid.height; y++) {
|
|
@@ -58,9 +58,9 @@ function solveUnderclued(input) {
|
|
|
58
58
|
light: false,
|
|
59
59
|
}));
|
|
60
60
|
function search(x, y, tile, color) {
|
|
61
|
-
const newGrid = grid.
|
|
61
|
+
const newGrid = grid.copyWith({
|
|
62
62
|
tiles: grid.setTile(x, y, tile.withColor(color)),
|
|
63
|
-
});
|
|
63
|
+
}, false, false);
|
|
64
64
|
// Solve
|
|
65
65
|
let solution;
|
|
66
66
|
solveNormal(newGrid, sol => {
|
|
@@ -92,13 +92,13 @@ function solveUnderclued(input) {
|
|
|
92
92
|
if (!darkPossible && !lightPossible)
|
|
93
93
|
return null;
|
|
94
94
|
if (darkPossible && !lightPossible)
|
|
95
|
-
grid = grid.
|
|
95
|
+
grid = grid.copyWith({
|
|
96
96
|
tiles: grid.setTile(x, y, tile.withColor(Color.Dark)),
|
|
97
|
-
});
|
|
97
|
+
}, false, false);
|
|
98
98
|
if (!darkPossible && lightPossible)
|
|
99
|
-
grid = grid.
|
|
99
|
+
grid = grid.copyWith({
|
|
100
100
|
tiles: grid.setTile(x, y, tile.withColor(Color.Light)),
|
|
101
|
-
});
|
|
101
|
+
}, false, false);
|
|
102
102
|
}
|
|
103
103
|
}
|
|
104
104
|
return grid;
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { AnyConfig } from '../config.js';
|
|
2
2
|
import GridData from '../grid.js';
|
|
3
|
-
import
|
|
4
|
-
|
|
5
|
-
export default class HouseSymbol extends Symbol {
|
|
3
|
+
import NumberSymbol from './numberSymbol.js';
|
|
4
|
+
export default class HouseSymbol extends NumberSymbol {
|
|
6
5
|
readonly x: number;
|
|
7
6
|
readonly y: number;
|
|
7
|
+
readonly number: number;
|
|
8
8
|
readonly title = "House";
|
|
9
9
|
private static readonly CONFIGS;
|
|
10
10
|
private static readonly EXAMPLE_GRID;
|
|
@@ -13,16 +13,21 @@ export default class HouseSymbol extends Symbol {
|
|
|
13
13
|
*
|
|
14
14
|
* @param x - The x-coordinate of the symbol.
|
|
15
15
|
* @param y - The y-coordinate of the symbol.
|
|
16
|
+
* @param number - The number of houses in this region.
|
|
16
17
|
*/
|
|
17
|
-
constructor(x: number, y: number);
|
|
18
|
+
constructor(x: number, y: number, number: number);
|
|
18
19
|
get id(): string;
|
|
19
20
|
get explanation(): string;
|
|
20
21
|
get configs(): readonly AnyConfig[] | null;
|
|
21
22
|
createExampleGrid(): GridData;
|
|
22
|
-
|
|
23
|
-
|
|
23
|
+
countTiles(grid: GridData): {
|
|
24
|
+
completed: number;
|
|
25
|
+
possible: number;
|
|
26
|
+
};
|
|
27
|
+
copyWith({ x, y, number, }: {
|
|
24
28
|
x?: number;
|
|
25
29
|
y?: number;
|
|
30
|
+
number?: number;
|
|
26
31
|
}): this;
|
|
27
32
|
}
|
|
28
33
|
export declare const instance: HouseSymbol;
|
|
@@ -1,17 +1,18 @@
|
|
|
1
1
|
import { ConfigType } from '../config.js';
|
|
2
2
|
import GridData from '../grid.js';
|
|
3
3
|
import { array } from '../dataHelper.js';
|
|
4
|
-
import { Color
|
|
5
|
-
import
|
|
6
|
-
class HouseSymbol extends
|
|
4
|
+
import { Color } from '../primitives.js';
|
|
5
|
+
import NumberSymbol from './numberSymbol.js';
|
|
6
|
+
class HouseSymbol extends NumberSymbol {
|
|
7
7
|
/**
|
|
8
8
|
* **Houses must connect to exactly one other house**
|
|
9
9
|
*
|
|
10
10
|
* @param x - The x-coordinate of the symbol.
|
|
11
11
|
* @param y - The y-coordinate of the symbol.
|
|
12
|
+
* @param number - The number of houses in this region.
|
|
12
13
|
*/
|
|
13
|
-
constructor(x, y) {
|
|
14
|
-
super(x, y);
|
|
14
|
+
constructor(x, y, number) {
|
|
15
|
+
super(x, y, number);
|
|
15
16
|
Object.defineProperty(this, "x", {
|
|
16
17
|
enumerable: true,
|
|
17
18
|
configurable: true,
|
|
@@ -24,6 +25,12 @@ class HouseSymbol extends Symbol {
|
|
|
24
25
|
writable: true,
|
|
25
26
|
value: y
|
|
26
27
|
});
|
|
28
|
+
Object.defineProperty(this, "number", {
|
|
29
|
+
enumerable: true,
|
|
30
|
+
configurable: true,
|
|
31
|
+
writable: true,
|
|
32
|
+
value: number
|
|
33
|
+
});
|
|
27
34
|
Object.defineProperty(this, "title", {
|
|
28
35
|
enumerable: true,
|
|
29
36
|
configurable: true,
|
|
@@ -35,7 +42,7 @@ class HouseSymbol extends Symbol {
|
|
|
35
42
|
return `house`;
|
|
36
43
|
}
|
|
37
44
|
get explanation() {
|
|
38
|
-
return '*
|
|
45
|
+
return '*House numbers* count the number of houses in the region';
|
|
39
46
|
}
|
|
40
47
|
get configs() {
|
|
41
48
|
return HouseSymbol.CONFIGS;
|
|
@@ -43,45 +50,39 @@ class HouseSymbol extends Symbol {
|
|
|
43
50
|
createExampleGrid() {
|
|
44
51
|
return HouseSymbol.EXAMPLE_GRID;
|
|
45
52
|
}
|
|
46
|
-
|
|
53
|
+
countTiles(grid) {
|
|
47
54
|
const thisX = Math.floor(this.x);
|
|
48
55
|
const thisY = Math.floor(this.y);
|
|
49
|
-
let complete = true;
|
|
50
56
|
const visited = array(grid.width, grid.height, () => false);
|
|
51
57
|
const connected = array(grid.width, grid.height, () => false);
|
|
52
58
|
const color = grid.getTile(thisX, thisY).color;
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
59
|
+
if (color === Color.Gray)
|
|
60
|
+
return { completed: 0, possible: Number.MAX_SAFE_INTEGER };
|
|
61
|
+
grid.iterateArea({ x: thisX, y: thisY }, tile => tile.color === Color.Gray || tile.color === color, (_, x, y) => {
|
|
56
62
|
visited[y][x] = true;
|
|
57
|
-
if (tile.color === Color.Gray)
|
|
58
|
-
complete = false;
|
|
59
63
|
});
|
|
60
64
|
grid.iterateArea({ x: thisX, y: thisY }, tile => tile.color === color, (_, x, y) => {
|
|
61
65
|
connected[y][x] = true;
|
|
62
66
|
});
|
|
63
|
-
let
|
|
67
|
+
let completedHouses = 0;
|
|
64
68
|
let possibleHouses = 0;
|
|
65
69
|
for (const symbol of grid.symbols.get(this.id) ?? []) {
|
|
66
|
-
if (symbol
|
|
70
|
+
if (symbol instanceof HouseSymbol) {
|
|
67
71
|
const symbolX = Math.floor(symbol.x);
|
|
68
72
|
const symbolY = Math.floor(symbol.y);
|
|
69
73
|
if (connected[symbolY][symbolX])
|
|
70
|
-
|
|
74
|
+
completedHouses++;
|
|
71
75
|
else if (visited[symbolY][symbolX])
|
|
72
76
|
possibleHouses++;
|
|
73
77
|
}
|
|
74
78
|
}
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
}
|
|
79
|
-
return complete || (connectedHouses === 1 && possibleHouses === 0)
|
|
80
|
-
? State.Satisfied
|
|
81
|
-
: State.Incomplete;
|
|
79
|
+
return {
|
|
80
|
+
completed: completedHouses,
|
|
81
|
+
possible: completedHouses + possibleHouses,
|
|
82
|
+
};
|
|
82
83
|
}
|
|
83
|
-
copyWith({ x, y }) {
|
|
84
|
-
return new HouseSymbol(x ?? this.x, y ?? this.y);
|
|
84
|
+
copyWith({ x, y, number, }) {
|
|
85
|
+
return new HouseSymbol(x ?? this.x, y ?? this.y, number ?? this.number);
|
|
85
86
|
}
|
|
86
87
|
}
|
|
87
88
|
Object.defineProperty(HouseSymbol, "CONFIGS", {
|
|
@@ -103,6 +104,14 @@ Object.defineProperty(HouseSymbol, "CONFIGS", {
|
|
|
103
104
|
description: 'Y',
|
|
104
105
|
configurable: false,
|
|
105
106
|
},
|
|
107
|
+
{
|
|
108
|
+
type: ConfigType.Number,
|
|
109
|
+
default: 2,
|
|
110
|
+
field: 'number',
|
|
111
|
+
description: 'Number',
|
|
112
|
+
explanation: 'Number of houses in this region',
|
|
113
|
+
configurable: true,
|
|
114
|
+
},
|
|
106
115
|
])
|
|
107
116
|
});
|
|
108
117
|
Object.defineProperty(HouseSymbol, "EXAMPLE_GRID", {
|
|
@@ -110,12 +119,12 @@ Object.defineProperty(HouseSymbol, "EXAMPLE_GRID", {
|
|
|
110
119
|
configurable: true,
|
|
111
120
|
writable: true,
|
|
112
121
|
value: Object.freeze(GridData.create(['bbbww', 'wwwbw', 'wbbbw', 'wwwww'])
|
|
113
|
-
.addSymbol(new HouseSymbol(0, 0))
|
|
114
|
-
.addSymbol(new HouseSymbol(2, 0))
|
|
115
|
-
.addSymbol(new HouseSymbol(3, 0))
|
|
116
|
-
.addSymbol(new HouseSymbol(2, 1))
|
|
117
|
-
.addSymbol(new HouseSymbol(3, 1))
|
|
118
|
-
.addSymbol(new HouseSymbol(1, 2)))
|
|
122
|
+
.addSymbol(new HouseSymbol(0, 0, 2))
|
|
123
|
+
.addSymbol(new HouseSymbol(2, 0, 2))
|
|
124
|
+
.addSymbol(new HouseSymbol(3, 0, 2))
|
|
125
|
+
.addSymbol(new HouseSymbol(2, 1, 2))
|
|
126
|
+
.addSymbol(new HouseSymbol(3, 1, 2))
|
|
127
|
+
.addSymbol(new HouseSymbol(1, 2, 2)))
|
|
119
128
|
});
|
|
120
129
|
export default HouseSymbol;
|
|
121
|
-
export const instance = new HouseSymbol(0, 0);
|
|
130
|
+
export const instance = new HouseSymbol(0, 0, 2);
|