@logic-pad/core 0.1.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/LICENSE +661 -0
- package/README.md +19 -0
- package/assets/logic-core.global.d.ts +5865 -0
- package/assets/z3-built.js +14723 -0
- package/assets/z3-built.wasm +0 -0
- package/assets/z3-built.worker.js +206 -0
- package/dist/data/config.d.ts +101 -0
- package/dist/data/config.js +55 -0
- package/dist/data/configurable.d.ts +12 -0
- package/dist/data/configurable.js +26 -0
- package/dist/data/dataHelper.d.ts +77 -0
- package/dist/data/dataHelper.js +190 -0
- package/dist/data/events/eventHelper.d.ts +1 -0
- package/dist/data/events/eventHelper.js +6 -0
- package/dist/data/events/onFinalValidation.d.ts +14 -0
- package/dist/data/events/onFinalValidation.js +4 -0
- package/dist/data/events/onGridChange.d.ts +6 -0
- package/dist/data/events/onGridChange.js +4 -0
- package/dist/data/events/onGridResize.d.ts +9 -0
- package/dist/data/events/onGridResize.js +4 -0
- package/dist/data/events/onSetGrid.d.ts +6 -0
- package/dist/data/events/onSetGrid.js +4 -0
- package/dist/data/events/onSymbolValidation.d.ts +18 -0
- package/dist/data/events/onSymbolValidation.js +4 -0
- package/dist/data/grid.d.ts +362 -0
- package/dist/data/grid.js +886 -0
- package/dist/data/gridConnections.d.ts +38 -0
- package/dist/data/gridConnections.js +328 -0
- package/dist/data/instruction.d.ts +19 -0
- package/dist/data/instruction.js +23 -0
- package/dist/data/primitives.d.ts +85 -0
- package/dist/data/primitives.js +90 -0
- package/dist/data/puzzle.d.ts +86 -0
- package/dist/data/puzzle.js +22 -0
- package/dist/data/rules/banPatternRule.d.ts +29 -0
- package/dist/data/rules/banPatternRule.js +133 -0
- package/dist/data/rules/cellCountRule.d.ts +32 -0
- package/dist/data/rules/cellCountRule.js +166 -0
- package/dist/data/rules/completePatternRule.d.ts +22 -0
- package/dist/data/rules/completePatternRule.js +53 -0
- package/dist/data/rules/connectAllRule.d.ts +28 -0
- package/dist/data/rules/connectAllRule.js +113 -0
- package/dist/data/rules/customRule.d.ts +32 -0
- package/dist/data/rules/customRule.js +92 -0
- package/dist/data/rules/foresightRule.d.ts +30 -0
- package/dist/data/rules/foresightRule.js +107 -0
- package/dist/data/rules/index.d.ts +3 -0
- package/dist/data/rules/index.js +10 -0
- package/dist/data/rules/musicControlLine.d.ts +64 -0
- package/dist/data/rules/musicControlLine.js +178 -0
- package/dist/data/rules/musicGridRule.d.ts +46 -0
- package/dist/data/rules/musicGridRule.js +211 -0
- package/dist/data/rules/mysteryRule.d.ts +37 -0
- package/dist/data/rules/mysteryRule.js +164 -0
- package/dist/data/rules/offByXRule.d.ts +30 -0
- package/dist/data/rules/offByXRule.js +134 -0
- package/dist/data/rules/regionAreaRule.d.ts +33 -0
- package/dist/data/rules/regionAreaRule.js +182 -0
- package/dist/data/rules/regionShapeRule.d.ts +22 -0
- package/dist/data/rules/regionShapeRule.js +58 -0
- package/dist/data/rules/rule.d.ts +18 -0
- package/dist/data/rules/rule.js +19 -0
- package/dist/data/rules/rules.gen.d.ts +14 -0
- package/dist/data/rules/rules.gen.js +18 -0
- package/dist/data/rules/sameShapeRule.d.ts +27 -0
- package/dist/data/rules/sameShapeRule.js +88 -0
- package/dist/data/rules/symbolsPerRegionRule.d.ts +37 -0
- package/dist/data/rules/symbolsPerRegionRule.js +211 -0
- package/dist/data/rules/undercluedRule.d.ts +22 -0
- package/dist/data/rules/undercluedRule.js +60 -0
- package/dist/data/rules/uniqueShapeRule.d.ts +27 -0
- package/dist/data/rules/uniqueShapeRule.js +85 -0
- package/dist/data/serializer/allSerializers.d.ts +30 -0
- package/dist/data/serializer/allSerializers.js +64 -0
- package/dist/data/serializer/compressor/allCompressors.d.ts +14 -0
- package/dist/data/serializer/compressor/allCompressors.js +43 -0
- package/dist/data/serializer/compressor/compressorBase.d.ts +16 -0
- package/dist/data/serializer/compressor/compressorBase.js +2 -0
- package/dist/data/serializer/compressor/deflateCompressor.d.ts +7 -0
- package/dist/data/serializer/compressor/deflateCompressor.js +17 -0
- package/dist/data/serializer/compressor/gzipCompressor.d.ts +5 -0
- package/dist/data/serializer/compressor/gzipCompressor.js +9 -0
- package/dist/data/serializer/compressor/streamCompressor.d.ts +6 -0
- package/dist/data/serializer/compressor/streamCompressor.js +36 -0
- package/dist/data/serializer/serializerBase.d.ts +27 -0
- package/dist/data/serializer/serializerBase.js +2 -0
- package/dist/data/serializer/serializer_v0.d.ts +36 -0
- package/dist/data/serializer/serializer_v0.js +426 -0
- package/dist/data/shapes.d.ts +17 -0
- package/dist/data/shapes.js +117 -0
- package/dist/data/solver/allSolvers.d.ts +3 -0
- package/dist/data/solver/allSolvers.js +11 -0
- package/dist/data/solver/backtrack/backtrackSolver.d.ts +9 -0
- package/dist/data/solver/backtrack/backtrackSolver.js +92 -0
- package/dist/data/solver/backtrack/backtrackWorker.d.ts +2 -0
- package/dist/data/solver/backtrack/backtrackWorker.js +295 -0
- package/dist/data/solver/backtrack/data.d.ts +46 -0
- package/dist/data/solver/backtrack/data.js +140 -0
- package/dist/data/solver/backtrack/rules/banPattern.d.ts +9 -0
- package/dist/data/solver/backtrack/rules/banPattern.js +66 -0
- package/dist/data/solver/backtrack/rules/cellCount.d.ts +7 -0
- package/dist/data/solver/backtrack/rules/cellCount.js +30 -0
- package/dist/data/solver/backtrack/rules/connectAll.d.ts +7 -0
- package/dist/data/solver/backtrack/rules/connectAll.js +49 -0
- package/dist/data/solver/backtrack/rules/regionArea.d.ts +8 -0
- package/dist/data/solver/backtrack/rules/regionArea.js +76 -0
- package/dist/data/solver/backtrack/rules/regionShape.d.ts +8 -0
- package/dist/data/solver/backtrack/rules/regionShape.js +62 -0
- package/dist/data/solver/backtrack/rules/sameShape.d.ts +8 -0
- package/dist/data/solver/backtrack/rules/sameShape.js +19 -0
- package/dist/data/solver/backtrack/rules/symbolsPerRegion.d.ts +10 -0
- package/dist/data/solver/backtrack/rules/symbolsPerRegion.js +92 -0
- package/dist/data/solver/backtrack/rules/uniqueShape.d.ts +8 -0
- package/dist/data/solver/backtrack/rules/uniqueShape.js +19 -0
- package/dist/data/solver/backtrack/symbols/areaNumber.d.ts +9 -0
- package/dist/data/solver/backtrack/symbols/areaNumber.js +77 -0
- package/dist/data/solver/backtrack/symbols/dart.d.ts +9 -0
- package/dist/data/solver/backtrack/symbols/dart.js +58 -0
- package/dist/data/solver/backtrack/symbols/directionLinker.d.ts +9 -0
- package/dist/data/solver/backtrack/symbols/directionLinker.js +50 -0
- package/dist/data/solver/backtrack/symbols/galaxy.d.ts +9 -0
- package/dist/data/solver/backtrack/symbols/galaxy.js +19 -0
- package/dist/data/solver/backtrack/symbols/letter.d.ts +9 -0
- package/dist/data/solver/backtrack/symbols/letter.js +100 -0
- package/dist/data/solver/backtrack/symbols/lotus.d.ts +9 -0
- package/dist/data/solver/backtrack/symbols/lotus.js +36 -0
- package/dist/data/solver/backtrack/symbols/minesweeper.d.ts +9 -0
- package/dist/data/solver/backtrack/symbols/minesweeper.js +55 -0
- package/dist/data/solver/backtrack/symbols/myopia.d.ts +7 -0
- package/dist/data/solver/backtrack/symbols/myopia.js +79 -0
- package/dist/data/solver/backtrack/symbols/viewpoint.d.ts +7 -0
- package/dist/data/solver/backtrack/symbols/viewpoint.js +56 -0
- package/dist/data/solver/solver.d.ts +61 -0
- package/dist/data/solver/solver.js +55 -0
- package/dist/data/solver/underclued/undercluedSolver.d.ts +8 -0
- package/dist/data/solver/underclued/undercluedSolver.js +55 -0
- package/dist/data/solver/underclued/undercluedWorker.d.ts +2 -0
- package/dist/data/solver/underclued/undercluedWorker.js +131 -0
- package/dist/data/solver/z3/modules/areaNumberModule.d.ts +9 -0
- package/dist/data/solver/z3/modules/areaNumberModule.js +35 -0
- package/dist/data/solver/z3/modules/cellCountModule.d.ts +9 -0
- package/dist/data/solver/z3/modules/cellCountModule.js +59 -0
- package/dist/data/solver/z3/modules/connectAllModule.d.ts +9 -0
- package/dist/data/solver/z3/modules/connectAllModule.js +32 -0
- package/dist/data/solver/z3/modules/dartModule.d.ts +9 -0
- package/dist/data/solver/z3/modules/dartModule.js +69 -0
- package/dist/data/solver/z3/modules/index.d.ts +3 -0
- package/dist/data/solver/z3/modules/index.js +10 -0
- package/dist/data/solver/z3/modules/letterModule.d.ts +9 -0
- package/dist/data/solver/z3/modules/letterModule.js +41 -0
- package/dist/data/solver/z3/modules/modules.gen.d.ts +8 -0
- package/dist/data/solver/z3/modules/modules.gen.js +12 -0
- package/dist/data/solver/z3/modules/myopiaModule.d.ts +9 -0
- package/dist/data/solver/z3/modules/myopiaModule.js +64 -0
- package/dist/data/solver/z3/modules/regionAreaModule.d.ts +9 -0
- package/dist/data/solver/z3/modules/regionAreaModule.js +48 -0
- package/dist/data/solver/z3/modules/viewpointModule.d.ts +9 -0
- package/dist/data/solver/z3/modules/viewpointModule.js +37 -0
- package/dist/data/solver/z3/modules/z3Module.d.ts +7 -0
- package/dist/data/solver/z3/modules/z3Module.js +3 -0
- package/dist/data/solver/z3/utils.d.ts +2 -0
- package/dist/data/solver/z3/utils.js +26 -0
- package/dist/data/solver/z3/z3Solver.d.ts +10 -0
- package/dist/data/solver/z3/z3Solver.js +134 -0
- package/dist/data/solver/z3/z3SolverContext.d.ts +808 -0
- package/dist/data/solver/z3/z3SolverContext.js +49 -0
- package/dist/data/symbols/areaNumberSymbol.d.ts +30 -0
- package/dist/data/symbols/areaNumberSymbol.js +88 -0
- package/dist/data/symbols/customIconSymbol.d.ts +35 -0
- package/dist/data/symbols/customIconSymbol.js +105 -0
- package/dist/data/symbols/customSymbol.d.ts +23 -0
- package/dist/data/symbols/customSymbol.js +48 -0
- package/dist/data/symbols/customTextSymbol.d.ts +33 -0
- package/dist/data/symbols/customTextSymbol.js +106 -0
- package/dist/data/symbols/dartSymbol.d.ts +35 -0
- package/dist/data/symbols/dartSymbol.js +110 -0
- package/dist/data/symbols/directionLinkerSymbol.d.ts +36 -0
- package/dist/data/symbols/directionLinkerSymbol.js +259 -0
- package/dist/data/symbols/galaxySymbol.d.ts +26 -0
- package/dist/data/symbols/galaxySymbol.js +74 -0
- package/dist/data/symbols/index.d.ts +3 -0
- package/dist/data/symbols/index.js +10 -0
- package/dist/data/symbols/letterSymbol.d.ts +31 -0
- package/dist/data/symbols/letterSymbol.js +137 -0
- package/dist/data/symbols/lotusSymbol.d.ts +29 -0
- package/dist/data/symbols/lotusSymbol.js +132 -0
- package/dist/data/symbols/minesweeperSymbol.d.ts +31 -0
- package/dist/data/symbols/minesweeperSymbol.js +100 -0
- package/dist/data/symbols/multiEntrySymbol.d.ts +11 -0
- package/dist/data/symbols/multiEntrySymbol.js +14 -0
- package/dist/data/symbols/myopiaSymbol.d.ts +34 -0
- package/dist/data/symbols/myopiaSymbol.js +187 -0
- package/dist/data/symbols/numberSymbol.d.ts +19 -0
- package/dist/data/symbols/numberSymbol.js +41 -0
- package/dist/data/symbols/symbol.d.ts +16 -0
- package/dist/data/symbols/symbol.js +51 -0
- package/dist/data/symbols/symbols.gen.d.ts +10 -0
- package/dist/data/symbols/symbols.gen.js +14 -0
- package/dist/data/symbols/viewpointSymbol.d.ts +31 -0
- package/dist/data/symbols/viewpointSymbol.js +106 -0
- package/dist/data/tile.d.ts +26 -0
- package/dist/data/tile.js +68 -0
- package/dist/data/tileConnections.d.ts +25 -0
- package/dist/data/tileConnections.js +74 -0
- package/dist/data/validate.d.ts +5 -0
- package/dist/data/validate.js +131 -0
- package/dist/index.d.ts +96 -0
- package/dist/index.js +100 -0
- package/dist/polyfill/streamPolyfill.d.ts +2 -0
- package/dist/polyfill/streamPolyfill.js +1 -0
- package/package.json +75 -0
|
@@ -0,0 +1,182 @@
|
|
|
1
|
+
import { ConfigType } from '../config';
|
|
2
|
+
import GridData from '../grid';
|
|
3
|
+
import { array } from '../dataHelper';
|
|
4
|
+
import { Color, State } from '../primitives';
|
|
5
|
+
import TileData from '../tile';
|
|
6
|
+
import Rule from './rule';
|
|
7
|
+
class RegionAreaRule extends Rule {
|
|
8
|
+
/**
|
|
9
|
+
* **All <color> regions have area <size>**
|
|
10
|
+
*
|
|
11
|
+
* @param color - The color of the regions.
|
|
12
|
+
* @param size - The area of the regions.
|
|
13
|
+
*/
|
|
14
|
+
constructor(color, size) {
|
|
15
|
+
super();
|
|
16
|
+
Object.defineProperty(this, "color", {
|
|
17
|
+
enumerable: true,
|
|
18
|
+
configurable: true,
|
|
19
|
+
writable: true,
|
|
20
|
+
value: color
|
|
21
|
+
});
|
|
22
|
+
Object.defineProperty(this, "size", {
|
|
23
|
+
enumerable: true,
|
|
24
|
+
configurable: true,
|
|
25
|
+
writable: true,
|
|
26
|
+
value: size
|
|
27
|
+
});
|
|
28
|
+
this.color = color;
|
|
29
|
+
this.size = size;
|
|
30
|
+
}
|
|
31
|
+
get id() {
|
|
32
|
+
return `region_area`;
|
|
33
|
+
}
|
|
34
|
+
get explanation() {
|
|
35
|
+
return `All ${this.color} regions have area ${this.size}`;
|
|
36
|
+
}
|
|
37
|
+
get configs() {
|
|
38
|
+
return RegionAreaRule.CONFIGS;
|
|
39
|
+
}
|
|
40
|
+
createExampleGrid() {
|
|
41
|
+
if (this.size < RegionAreaRule.EXAMPLE_GRID_DARK.length) {
|
|
42
|
+
switch (this.color) {
|
|
43
|
+
case Color.Dark:
|
|
44
|
+
return RegionAreaRule.EXAMPLE_GRID_DARK[this.size];
|
|
45
|
+
case Color.Light:
|
|
46
|
+
return RegionAreaRule.EXAMPLE_GRID_LIGHT[this.size];
|
|
47
|
+
case Color.Gray:
|
|
48
|
+
return RegionAreaRule.EXAMPLE_GRID_GRAY[this.size];
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
else {
|
|
52
|
+
let count = this.size;
|
|
53
|
+
const tiles = array(5, 4, (x, y) => {
|
|
54
|
+
count--;
|
|
55
|
+
return new TileData(true, false, count >= 0
|
|
56
|
+
? this.color
|
|
57
|
+
: this.color === Color.Gray
|
|
58
|
+
? x % 2 !== y % 2
|
|
59
|
+
? Color.Dark
|
|
60
|
+
: Color.Light
|
|
61
|
+
: this.color === Color.Light
|
|
62
|
+
? Color.Dark
|
|
63
|
+
: Color.Light);
|
|
64
|
+
});
|
|
65
|
+
return new GridData(5, 4, tiles);
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
get searchVariants() {
|
|
69
|
+
return RegionAreaRule.SEARCH_VARIANTS;
|
|
70
|
+
}
|
|
71
|
+
validateGrid(grid) {
|
|
72
|
+
const visited = array(grid.width, grid.height, (i, j) => !(grid.getTile(i, j).exists && grid.getTile(i, j).color === this.color));
|
|
73
|
+
let complete = true;
|
|
74
|
+
while (true) {
|
|
75
|
+
const seed = grid.find((_tile, x, y) => !visited[y][x]);
|
|
76
|
+
if (!seed)
|
|
77
|
+
break;
|
|
78
|
+
const completed = [];
|
|
79
|
+
const gray = [];
|
|
80
|
+
grid.iterateArea({ x: seed.x, y: seed.y }, tile => tile.color === this.color, (_, x, y) => {
|
|
81
|
+
completed.push({ x, y });
|
|
82
|
+
visited[y][x] = true;
|
|
83
|
+
});
|
|
84
|
+
if (this.color === Color.Gray) {
|
|
85
|
+
gray.push(...completed);
|
|
86
|
+
}
|
|
87
|
+
else {
|
|
88
|
+
grid.iterateArea({ x: seed.x, y: seed.y }, tile => tile.color === Color.Gray || tile.color === this.color, (_, x, y) => {
|
|
89
|
+
gray.push({ x, y });
|
|
90
|
+
});
|
|
91
|
+
}
|
|
92
|
+
if (completed.length > this.size) {
|
|
93
|
+
return { state: State.Error, positions: completed };
|
|
94
|
+
}
|
|
95
|
+
else if (gray.length < this.size) {
|
|
96
|
+
return { state: State.Error, positions: gray };
|
|
97
|
+
}
|
|
98
|
+
else if (completed.length !== this.size ||
|
|
99
|
+
completed.length !== gray.length) {
|
|
100
|
+
complete = false;
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
return complete ? { state: State.Satisfied } : { state: State.Incomplete };
|
|
104
|
+
}
|
|
105
|
+
copyWith({ color, size }) {
|
|
106
|
+
return new RegionAreaRule(color ?? this.color, size ?? this.size);
|
|
107
|
+
}
|
|
108
|
+
withColor(color) {
|
|
109
|
+
return this.copyWith({ color });
|
|
110
|
+
}
|
|
111
|
+
withSize(size) {
|
|
112
|
+
return this.copyWith({ size });
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
Object.defineProperty(RegionAreaRule, "CONFIGS", {
|
|
116
|
+
enumerable: true,
|
|
117
|
+
configurable: true,
|
|
118
|
+
writable: true,
|
|
119
|
+
value: Object.freeze([
|
|
120
|
+
{
|
|
121
|
+
type: ConfigType.Color,
|
|
122
|
+
default: Color.Dark,
|
|
123
|
+
allowGray: false,
|
|
124
|
+
field: 'color',
|
|
125
|
+
description: 'Color',
|
|
126
|
+
configurable: true,
|
|
127
|
+
},
|
|
128
|
+
{
|
|
129
|
+
type: ConfigType.Number,
|
|
130
|
+
default: 2,
|
|
131
|
+
min: 0,
|
|
132
|
+
field: 'size',
|
|
133
|
+
description: 'Region Size',
|
|
134
|
+
configurable: true,
|
|
135
|
+
},
|
|
136
|
+
])
|
|
137
|
+
});
|
|
138
|
+
Object.defineProperty(RegionAreaRule, "EXAMPLE_GRID_DARK", {
|
|
139
|
+
enumerable: true,
|
|
140
|
+
configurable: true,
|
|
141
|
+
writable: true,
|
|
142
|
+
value: Object.freeze([
|
|
143
|
+
GridData.create(['wwwww', 'wwwww', 'wwwww', 'wwwww']),
|
|
144
|
+
GridData.create(['bwwbw', 'wbwwb', 'bwbww', 'wbwwb']),
|
|
145
|
+
GridData.create(['bbwbb', 'wwbww', 'wwbww', 'wwwbb']),
|
|
146
|
+
GridData.create(['bbwww', 'bwbwb', 'wbbwb', 'wwwwb']),
|
|
147
|
+
GridData.create(['bwbbb', 'bbwwb', 'bwbbw', 'wwbbw']),
|
|
148
|
+
GridData.create(['bbbww', 'bbwbw', 'wwbbb', 'wwwbw']),
|
|
149
|
+
GridData.create(['bbbww', 'bbbwb', 'wwwbb', 'wwbbb']),
|
|
150
|
+
GridData.create(['bbbbb', 'bbwww', 'wwwbb', 'bbbbb']),
|
|
151
|
+
GridData.create(['bbbbw', 'bbbww', 'bwwww', 'wwwww']),
|
|
152
|
+
GridData.create(['wwwww', 'bbbbb', 'bbwbb', 'wwwww']),
|
|
153
|
+
GridData.create(['bbbbb', 'bbbww', 'bbwww', 'wwwww']),
|
|
154
|
+
])
|
|
155
|
+
});
|
|
156
|
+
Object.defineProperty(RegionAreaRule, "EXAMPLE_GRID_LIGHT", {
|
|
157
|
+
enumerable: true,
|
|
158
|
+
configurable: true,
|
|
159
|
+
writable: true,
|
|
160
|
+
value: Object.freeze(RegionAreaRule.EXAMPLE_GRID_DARK.map(grid => new GridData(grid.width, grid.height, grid.tiles.map(row => row.map(tile => tile.withColor(tile.color === Color.Dark ? Color.Light : Color.Dark))))))
|
|
161
|
+
});
|
|
162
|
+
Object.defineProperty(RegionAreaRule, "EXAMPLE_GRID_GRAY", {
|
|
163
|
+
enumerable: true,
|
|
164
|
+
configurable: true,
|
|
165
|
+
writable: true,
|
|
166
|
+
value: Object.freeze(RegionAreaRule.EXAMPLE_GRID_DARK.map(grid => new GridData(grid.width, grid.height, grid.tiles.map((row, y) => row.map((tile, x) => tile.withColor(tile.color === Color.Dark
|
|
167
|
+
? Color.Gray
|
|
168
|
+
: x % 2 !== y % 2
|
|
169
|
+
? Color.Dark
|
|
170
|
+
: Color.Light))))))
|
|
171
|
+
});
|
|
172
|
+
Object.defineProperty(RegionAreaRule, "SEARCH_VARIANTS", {
|
|
173
|
+
enumerable: true,
|
|
174
|
+
configurable: true,
|
|
175
|
+
writable: true,
|
|
176
|
+
value: [
|
|
177
|
+
new RegionAreaRule(Color.Dark, 2).searchVariant(),
|
|
178
|
+
new RegionAreaRule(Color.Light, 2).searchVariant(),
|
|
179
|
+
]
|
|
180
|
+
});
|
|
181
|
+
export default RegionAreaRule;
|
|
182
|
+
export const instance = new RegionAreaRule(Color.Dark, 2);
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import GridData from '../grid';
|
|
2
|
+
import { Color, Position } from '../primitives';
|
|
3
|
+
import { Shape } from '../shapes';
|
|
4
|
+
import Rule from './rule';
|
|
5
|
+
export type ShapeRegions = {
|
|
6
|
+
regions: {
|
|
7
|
+
positions: Position[];
|
|
8
|
+
shape: Shape;
|
|
9
|
+
count: number;
|
|
10
|
+
}[];
|
|
11
|
+
complete: boolean;
|
|
12
|
+
};
|
|
13
|
+
export default abstract class RegionShapeRule extends Rule {
|
|
14
|
+
readonly color: Color;
|
|
15
|
+
/**
|
|
16
|
+
* @param color - The color of the regions to compare.
|
|
17
|
+
*/
|
|
18
|
+
constructor(color: Color);
|
|
19
|
+
protected getShapeRegions(grid: GridData): ShapeRegions;
|
|
20
|
+
withColor(color: Color): this;
|
|
21
|
+
}
|
|
22
|
+
export declare const instance: undefined;
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { array } from '../dataHelper';
|
|
2
|
+
import { Color } from '../primitives';
|
|
3
|
+
import { normalizeShape, positionsToShape, shapeEquals, } from '../shapes';
|
|
4
|
+
import Rule from './rule';
|
|
5
|
+
export default class RegionShapeRule extends Rule {
|
|
6
|
+
/**
|
|
7
|
+
* @param color - The color of the regions to compare.
|
|
8
|
+
*/
|
|
9
|
+
constructor(color) {
|
|
10
|
+
super();
|
|
11
|
+
Object.defineProperty(this, "color", {
|
|
12
|
+
enumerable: true,
|
|
13
|
+
configurable: true,
|
|
14
|
+
writable: true,
|
|
15
|
+
value: color
|
|
16
|
+
});
|
|
17
|
+
this.color = color;
|
|
18
|
+
}
|
|
19
|
+
getShapeRegions(grid) {
|
|
20
|
+
let complete = true;
|
|
21
|
+
const visited = array(grid.width, grid.height, (i, j) => {
|
|
22
|
+
const tile = grid.getTile(i, j);
|
|
23
|
+
if (tile.exists && tile.color === Color.Gray)
|
|
24
|
+
complete = false;
|
|
25
|
+
return !(tile.exists && tile.color === this.color);
|
|
26
|
+
});
|
|
27
|
+
const regions = [];
|
|
28
|
+
while (true) {
|
|
29
|
+
const seed = grid.find((_tile, x, y) => !visited[y][x]);
|
|
30
|
+
if (!seed)
|
|
31
|
+
break;
|
|
32
|
+
const positions = [];
|
|
33
|
+
grid.iterateArea(seed, tile => tile.color === this.color, (_, x, y) => {
|
|
34
|
+
visited[y][x] = true;
|
|
35
|
+
positions.push({ x, y });
|
|
36
|
+
});
|
|
37
|
+
const incomplete = grid.iterateArea(seed, tile => tile.color === this.color || tile.color === Color.Gray, tile => {
|
|
38
|
+
if (tile.color === Color.Gray)
|
|
39
|
+
return true;
|
|
40
|
+
});
|
|
41
|
+
if (incomplete)
|
|
42
|
+
continue;
|
|
43
|
+
const shape = normalizeShape(positionsToShape(positions, this.color));
|
|
44
|
+
const existing = regions.find(island => shapeEquals(island.shape, shape));
|
|
45
|
+
if (existing) {
|
|
46
|
+
existing.count++;
|
|
47
|
+
}
|
|
48
|
+
else {
|
|
49
|
+
regions.push({ positions, shape, count: 1 });
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
return { regions, complete };
|
|
53
|
+
}
|
|
54
|
+
withColor(color) {
|
|
55
|
+
return this.copyWith({ color });
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
export const instance = undefined;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import GridData from '../grid';
|
|
2
|
+
import { RuleState } from '../primitives';
|
|
3
|
+
import Instruction from '../instruction';
|
|
4
|
+
export interface SearchVariant {
|
|
5
|
+
description: string;
|
|
6
|
+
rule: Rule;
|
|
7
|
+
}
|
|
8
|
+
export default abstract class Rule extends Instruction {
|
|
9
|
+
abstract validateGrid(grid: GridData): RuleState;
|
|
10
|
+
abstract get searchVariants(): SearchVariant[];
|
|
11
|
+
searchVariant(): SearchVariant;
|
|
12
|
+
get visibleWhenSolving(): boolean;
|
|
13
|
+
/**
|
|
14
|
+
* Whether only one instance of this rule is allowed in a grid.
|
|
15
|
+
*/
|
|
16
|
+
get isSingleton(): boolean;
|
|
17
|
+
}
|
|
18
|
+
export declare const instance: undefined;
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import Instruction from '../instruction';
|
|
2
|
+
export default class Rule extends Instruction {
|
|
3
|
+
searchVariant() {
|
|
4
|
+
return {
|
|
5
|
+
description: this.explanation,
|
|
6
|
+
rule: this,
|
|
7
|
+
};
|
|
8
|
+
}
|
|
9
|
+
get visibleWhenSolving() {
|
|
10
|
+
return true;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Whether only one instance of this rule is allowed in a grid.
|
|
14
|
+
*/
|
|
15
|
+
get isSingleton() {
|
|
16
|
+
return false;
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
export const instance = undefined;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export { instance as BanPatternRule } from './banPatternRule';
|
|
2
|
+
export { instance as CellCountRule } from './cellCountRule';
|
|
3
|
+
export { instance as CompletePatternRule } from './completePatternRule';
|
|
4
|
+
export { instance as ConnectAllRule } from './connectAllRule';
|
|
5
|
+
export { instance as CustomRule } from './customRule';
|
|
6
|
+
export { instance as ForesightRule } from './foresightRule';
|
|
7
|
+
export { instance as MusicGridRule } from './musicGridRule';
|
|
8
|
+
export { instance as MysteryRule } from './mysteryRule';
|
|
9
|
+
export { instance as OffByXRule } from './offByXRule';
|
|
10
|
+
export { instance as RegionAreaRule } from './regionAreaRule';
|
|
11
|
+
export { instance as SameShapeRule } from './sameShapeRule';
|
|
12
|
+
export { instance as SymbolsPerRegionRule } from './symbolsPerRegionRule';
|
|
13
|
+
export { instance as UndercluedRule } from './undercluedRule';
|
|
14
|
+
export { instance as UniqueShapeRule } from './uniqueShapeRule';
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/* prettier-ignore-start */
|
|
2
|
+
/* eslint-disable */
|
|
3
|
+
// @ts-nocheck
|
|
4
|
+
// noinspection JSUnusedGlobalSymbols
|
|
5
|
+
export { instance as BanPatternRule } from './banPatternRule';
|
|
6
|
+
export { instance as CellCountRule } from './cellCountRule';
|
|
7
|
+
export { instance as CompletePatternRule } from './completePatternRule';
|
|
8
|
+
export { instance as ConnectAllRule } from './connectAllRule';
|
|
9
|
+
export { instance as CustomRule } from './customRule';
|
|
10
|
+
export { instance as ForesightRule } from './foresightRule';
|
|
11
|
+
export { instance as MusicGridRule } from './musicGridRule';
|
|
12
|
+
export { instance as MysteryRule } from './mysteryRule';
|
|
13
|
+
export { instance as OffByXRule } from './offByXRule';
|
|
14
|
+
export { instance as RegionAreaRule } from './regionAreaRule';
|
|
15
|
+
export { instance as SameShapeRule } from './sameShapeRule';
|
|
16
|
+
export { instance as SymbolsPerRegionRule } from './symbolsPerRegionRule';
|
|
17
|
+
export { instance as UndercluedRule } from './undercluedRule';
|
|
18
|
+
export { instance as UniqueShapeRule } from './uniqueShapeRule';
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { AnyConfig } from '../config';
|
|
2
|
+
import GridData from '../grid';
|
|
3
|
+
import { Color, RuleState } from '../primitives';
|
|
4
|
+
import RegionShapeRule from './regionShapeRule';
|
|
5
|
+
import { SearchVariant } from './rule';
|
|
6
|
+
export default class SameShapeRule extends RegionShapeRule {
|
|
7
|
+
private static readonly CONFIGS;
|
|
8
|
+
private static readonly EXAMPLE_GRID_LIGHT;
|
|
9
|
+
private static readonly EXAMPLE_GRID_DARK;
|
|
10
|
+
private static readonly SEARCH_VARIANTS;
|
|
11
|
+
/**
|
|
12
|
+
* **All <color> areas have the same shape and size**
|
|
13
|
+
*
|
|
14
|
+
* @param color - The color of the regions to compare.
|
|
15
|
+
*/
|
|
16
|
+
constructor(color: Color);
|
|
17
|
+
get id(): string;
|
|
18
|
+
get explanation(): string;
|
|
19
|
+
get configs(): readonly AnyConfig[] | null;
|
|
20
|
+
createExampleGrid(): GridData;
|
|
21
|
+
get searchVariants(): SearchVariant[];
|
|
22
|
+
validateGrid(grid: GridData): RuleState;
|
|
23
|
+
copyWith({ color }: {
|
|
24
|
+
color?: Color;
|
|
25
|
+
}): this;
|
|
26
|
+
}
|
|
27
|
+
export declare const instance: SameShapeRule;
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
import { ConfigType } from '../config';
|
|
2
|
+
import GridData from '../grid';
|
|
3
|
+
import { minBy } from '../dataHelper';
|
|
4
|
+
import { Color, State } from '../primitives';
|
|
5
|
+
import RegionShapeRule from './regionShapeRule';
|
|
6
|
+
class SameShapeRule extends RegionShapeRule {
|
|
7
|
+
/**
|
|
8
|
+
* **All <color> areas have the same shape and size**
|
|
9
|
+
*
|
|
10
|
+
* @param color - The color of the regions to compare.
|
|
11
|
+
*/
|
|
12
|
+
constructor(color) {
|
|
13
|
+
super(color);
|
|
14
|
+
}
|
|
15
|
+
get id() {
|
|
16
|
+
return `same_shape`;
|
|
17
|
+
}
|
|
18
|
+
get explanation() {
|
|
19
|
+
return `All ${this.color} areas have the same shape and size`;
|
|
20
|
+
}
|
|
21
|
+
get configs() {
|
|
22
|
+
return SameShapeRule.CONFIGS;
|
|
23
|
+
}
|
|
24
|
+
createExampleGrid() {
|
|
25
|
+
return this.color === Color.Light
|
|
26
|
+
? SameShapeRule.EXAMPLE_GRID_LIGHT
|
|
27
|
+
: SameShapeRule.EXAMPLE_GRID_DARK;
|
|
28
|
+
}
|
|
29
|
+
get searchVariants() {
|
|
30
|
+
return SameShapeRule.SEARCH_VARIANTS;
|
|
31
|
+
}
|
|
32
|
+
validateGrid(grid) {
|
|
33
|
+
const { regions, complete } = this.getShapeRegions(grid);
|
|
34
|
+
if (regions.length > 1) {
|
|
35
|
+
return {
|
|
36
|
+
state: State.Error,
|
|
37
|
+
positions: minBy(regions, island => island.count).positions,
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
else if (regions.length <= 1) {
|
|
41
|
+
return { state: complete ? State.Satisfied : State.Incomplete };
|
|
42
|
+
}
|
|
43
|
+
else {
|
|
44
|
+
return { state: State.Incomplete }; // not reachable but the TS is not happy
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
copyWith({ color }) {
|
|
48
|
+
return new SameShapeRule(color ?? this.color);
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
Object.defineProperty(SameShapeRule, "CONFIGS", {
|
|
52
|
+
enumerable: true,
|
|
53
|
+
configurable: true,
|
|
54
|
+
writable: true,
|
|
55
|
+
value: Object.freeze([
|
|
56
|
+
{
|
|
57
|
+
type: ConfigType.Color,
|
|
58
|
+
default: Color.Light,
|
|
59
|
+
allowGray: false,
|
|
60
|
+
field: 'color',
|
|
61
|
+
description: 'Color',
|
|
62
|
+
configurable: true,
|
|
63
|
+
},
|
|
64
|
+
])
|
|
65
|
+
});
|
|
66
|
+
Object.defineProperty(SameShapeRule, "EXAMPLE_GRID_LIGHT", {
|
|
67
|
+
enumerable: true,
|
|
68
|
+
configurable: true,
|
|
69
|
+
writable: true,
|
|
70
|
+
value: Object.freeze(GridData.create(['wwbww', 'wbwbw', 'wbwbw', 'bwwbb']))
|
|
71
|
+
});
|
|
72
|
+
Object.defineProperty(SameShapeRule, "EXAMPLE_GRID_DARK", {
|
|
73
|
+
enumerable: true,
|
|
74
|
+
configurable: true,
|
|
75
|
+
writable: true,
|
|
76
|
+
value: Object.freeze(GridData.create(['bbwbb', 'bwbwb', 'bwbwb', 'wbbww']))
|
|
77
|
+
});
|
|
78
|
+
Object.defineProperty(SameShapeRule, "SEARCH_VARIANTS", {
|
|
79
|
+
enumerable: true,
|
|
80
|
+
configurable: true,
|
|
81
|
+
writable: true,
|
|
82
|
+
value: [
|
|
83
|
+
new SameShapeRule(Color.Light).searchVariant(),
|
|
84
|
+
new SameShapeRule(Color.Dark).searchVariant(),
|
|
85
|
+
]
|
|
86
|
+
});
|
|
87
|
+
export default SameShapeRule;
|
|
88
|
+
export const instance = new SameShapeRule(Color.Dark);
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import Rule, { SearchVariant } from './rule';
|
|
2
|
+
import GridData from '../grid';
|
|
3
|
+
import { AnyConfig } from '../config';
|
|
4
|
+
import { Color, Comparison, RuleState } from '../primitives';
|
|
5
|
+
export default class SymbolsPerRegionRule extends Rule {
|
|
6
|
+
readonly color: Color;
|
|
7
|
+
readonly count: number;
|
|
8
|
+
readonly comparison: Comparison;
|
|
9
|
+
private static readonly SYMBOL_POSITIONS;
|
|
10
|
+
private static readonly CONFIGS;
|
|
11
|
+
private static readonly EXAMPLE_GRIDS;
|
|
12
|
+
private static readonly SEARCH_VARIANTS;
|
|
13
|
+
/**
|
|
14
|
+
* **Exactly <count> symbols per <color> area**
|
|
15
|
+
*
|
|
16
|
+
* @param color - Color of the region affected by the rule
|
|
17
|
+
* @param count - Number of symbols to have in each region
|
|
18
|
+
* @param comparison - Comparison to use when checking the number of symbols
|
|
19
|
+
*/
|
|
20
|
+
constructor(color: Color, count: number, comparison?: Comparison);
|
|
21
|
+
get id(): string;
|
|
22
|
+
get explanation(): string;
|
|
23
|
+
get configs(): readonly AnyConfig[] | null;
|
|
24
|
+
createExampleGrid(): GridData;
|
|
25
|
+
get searchVariants(): SearchVariant[];
|
|
26
|
+
validateGrid(grid: GridData): RuleState;
|
|
27
|
+
copyWith({ count, color, comparison, }: {
|
|
28
|
+
count?: number;
|
|
29
|
+
color?: Color;
|
|
30
|
+
comparison?: Comparison;
|
|
31
|
+
}): this;
|
|
32
|
+
withColor(color: Color): this;
|
|
33
|
+
withCount(count: number): this;
|
|
34
|
+
withComparison(comparison: Comparison): this;
|
|
35
|
+
private static countAllSymbolsOfPosition;
|
|
36
|
+
}
|
|
37
|
+
export declare const instance: SymbolsPerRegionRule;
|