@logic-pad/core 0.26.2 → 0.27.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 +3263 -3264
- package/dist/benchmark/helper.d.ts +22 -0
- package/dist/benchmark/helper.js +46 -0
- package/dist/benchmark/prepareBench.d.ts +1 -0
- package/dist/benchmark/prepareBench.js +154 -0
- package/dist/benchmark/runBench.d.ts +1 -0
- package/dist/benchmark/runBench.js +224 -0
- package/dist/src/data/config.d.ts +119 -0
- package/dist/src/data/config.js +72 -0
- package/dist/src/data/configurable.d.ts +14 -0
- package/dist/src/data/configurable.js +26 -0
- package/dist/src/data/dataHelper.d.ts +92 -0
- package/dist/src/data/dataHelper.js +217 -0
- package/dist/src/data/events/eventHelper.d.ts +1 -0
- package/dist/src/data/events/eventHelper.js +6 -0
- package/dist/src/data/events/onFinalValidation.d.ts +14 -0
- package/dist/src/data/events/onFinalValidation.js +4 -0
- package/dist/src/data/events/onGetTile.d.ts +7 -0
- package/dist/src/data/events/onGetTile.js +4 -0
- package/dist/src/data/events/onGridChange.d.ts +6 -0
- package/dist/src/data/events/onGridChange.js +4 -0
- package/dist/src/data/events/onGridResize.d.ts +9 -0
- package/dist/src/data/events/onGridResize.js +4 -0
- package/dist/src/data/events/onSetGrid.d.ts +7 -0
- package/dist/src/data/events/onSetGrid.js +19 -0
- package/dist/src/data/events/onSymbolDisplay.d.ts +16 -0
- package/dist/src/data/events/onSymbolDisplay.js +4 -0
- package/dist/src/data/events/onSymbolMerge.d.ts +10 -0
- package/dist/src/data/events/onSymbolMerge.js +4 -0
- package/dist/src/data/events/onSymbolValidation.d.ts +18 -0
- package/dist/src/data/events/onSymbolValidation.js +4 -0
- package/dist/src/data/grid.d.ts +410 -0
- package/dist/src/data/grid.js +1106 -0
- package/dist/src/data/gridConnections.d.ts +25 -0
- package/dist/src/data/gridConnections.js +309 -0
- package/dist/src/data/gridZones.d.ts +26 -0
- package/dist/src/data/gridZones.js +117 -0
- package/dist/src/data/instruction.d.ts +26 -0
- package/dist/src/data/instruction.js +29 -0
- package/dist/src/data/primitives.d.ts +138 -0
- package/dist/src/data/primitives.js +177 -0
- package/dist/src/data/puzzle.d.ts +73 -0
- package/dist/src/data/puzzle.js +105 -0
- package/dist/src/data/rules/banPatternRule.d.ts +30 -0
- package/dist/src/data/rules/banPatternRule.js +125 -0
- package/dist/src/data/rules/cellCountPerZoneRule.d.ts +23 -0
- package/dist/src/data/rules/cellCountPerZoneRule.js +39 -0
- package/dist/src/data/rules/cellCountRule.d.ts +33 -0
- package/dist/src/data/rules/cellCountRule.js +138 -0
- package/dist/src/data/rules/completePatternRule.d.ts +24 -0
- package/dist/src/data/rules/completePatternRule.js +46 -0
- package/dist/src/data/rules/connectAllRule.d.ts +29 -0
- package/dist/src/data/rules/connectAllRule.js +88 -0
- package/dist/src/data/rules/connectZonesRule.d.ts +29 -0
- package/dist/src/data/rules/connectZonesRule.js +111 -0
- package/dist/src/data/rules/containsShapeRule.d.ts +34 -0
- package/dist/src/data/rules/containsShapeRule.js +125 -0
- package/dist/src/data/rules/customRule.d.ts +34 -0
- package/dist/src/data/rules/customRule.js +74 -0
- package/dist/src/data/rules/differentCountPerZoneRule.d.ts +30 -0
- package/dist/src/data/rules/differentCountPerZoneRule.js +96 -0
- package/dist/src/data/rules/exactCountPerZoneRule.d.ts +33 -0
- package/dist/src/data/rules/exactCountPerZoneRule.js +99 -0
- package/dist/src/data/rules/foresightRule.d.ts +36 -0
- package/dist/src/data/rules/foresightRule.js +107 -0
- package/dist/src/data/rules/index.d.ts +3 -0
- package/dist/src/data/rules/index.js +10 -0
- package/dist/src/data/rules/lyingSymbolRule.d.ts +31 -0
- package/dist/src/data/rules/lyingSymbolRule.js +207 -0
- package/dist/src/data/rules/musicControlLine.d.ts +82 -0
- package/dist/src/data/rules/musicControlLine.js +167 -0
- package/dist/src/data/rules/musicGridRule.d.ts +51 -0
- package/dist/src/data/rules/musicGridRule.js +212 -0
- package/dist/src/data/rules/mysteryRule.d.ts +39 -0
- package/dist/src/data/rules/mysteryRule.js +146 -0
- package/dist/src/data/rules/noLoopsRule.d.ts +29 -0
- package/dist/src/data/rules/noLoopsRule.js +218 -0
- package/dist/src/data/rules/offByXRule.d.ts +32 -0
- package/dist/src/data/rules/offByXRule.js +124 -0
- package/dist/src/data/rules/perfectionRule.d.ts +45 -0
- package/dist/src/data/rules/perfectionRule.js +158 -0
- package/dist/src/data/rules/regionAreaRule.d.ts +34 -0
- package/dist/src/data/rules/regionAreaRule.js +149 -0
- package/dist/src/data/rules/regionShapeRule.d.ts +22 -0
- package/dist/src/data/rules/regionShapeRule.js +58 -0
- package/dist/src/data/rules/rule.d.ts +18 -0
- package/dist/src/data/rules/rule.js +19 -0
- package/dist/src/data/rules/rules.gen.d.ts +23 -0
- package/dist/src/data/rules/rules.gen.js +27 -0
- package/dist/src/data/rules/sameCountPerZoneRule.d.ts +30 -0
- package/dist/src/data/rules/sameCountPerZoneRule.js +95 -0
- package/dist/src/data/rules/sameShapeRule.d.ts +28 -0
- package/dist/src/data/rules/sameShapeRule.js +68 -0
- package/dist/src/data/rules/symbolsPerRegionRule.d.ts +37 -0
- package/dist/src/data/rules/symbolsPerRegionRule.js +194 -0
- package/dist/src/data/rules/undercluedRule.d.ts +24 -0
- package/dist/src/data/rules/undercluedRule.js +53 -0
- package/dist/src/data/rules/uniqueShapeRule.d.ts +28 -0
- package/dist/src/data/rules/uniqueShapeRule.js +65 -0
- package/dist/src/data/rules/wrapAroundRule.d.ts +36 -0
- package/dist/src/data/rules/wrapAroundRule.js +241 -0
- package/dist/src/data/serializer/allSerializers.d.ts +35 -0
- package/dist/src/data/serializer/allSerializers.js +78 -0
- package/dist/src/data/serializer/compressor/allCompressors.d.ts +14 -0
- package/dist/src/data/serializer/compressor/allCompressors.js +43 -0
- package/dist/src/data/serializer/compressor/checksumCompressor.d.ts +6 -0
- package/dist/src/data/serializer/compressor/checksumCompressor.js +21 -0
- package/dist/src/data/serializer/compressor/compressorBase.d.ts +16 -0
- package/dist/src/data/serializer/compressor/compressorBase.js +2 -0
- package/dist/src/data/serializer/compressor/deflateCompressor.d.ts +7 -0
- package/dist/src/data/serializer/compressor/deflateCompressor.js +17 -0
- package/dist/src/data/serializer/compressor/gzipCompressor.d.ts +5 -0
- package/dist/src/data/serializer/compressor/gzipCompressor.js +9 -0
- package/dist/src/data/serializer/compressor/streamCompressor.d.ts +6 -0
- package/dist/src/data/serializer/compressor/streamCompressor.js +41 -0
- package/dist/src/data/serializer/serializerBase.d.ts +32 -0
- package/dist/src/data/serializer/serializerBase.js +2 -0
- package/dist/src/data/serializer/serializer_checksum.d.ts +35 -0
- package/dist/src/data/serializer/serializer_checksum.js +179 -0
- package/dist/src/data/serializer/serializer_v0.d.ts +55 -0
- package/dist/src/data/serializer/serializer_v0.js +484 -0
- package/dist/src/data/shapes.d.ts +19 -0
- package/dist/src/data/shapes.js +137 -0
- package/dist/src/data/solver/allSolvers.d.ts +3 -0
- package/dist/src/data/solver/allSolvers.js +13 -0
- package/dist/src/data/solver/auto/autoSolver.d.ts +18 -0
- package/dist/src/data/solver/auto/autoSolver.js +156 -0
- package/dist/src/data/solver/backtrack/backtrackSolver.d.ts +11 -0
- package/dist/src/data/solver/backtrack/backtrackSolver.js +54 -0
- package/dist/src/data/solver/backtrack/backtrackWorker.d.ts +1 -0
- package/dist/src/data/solver/backtrack/backtrackWorker.js +312 -0
- package/dist/src/data/solver/backtrack/data.d.ts +47 -0
- package/dist/src/data/solver/backtrack/data.js +151 -0
- package/dist/src/data/solver/backtrack/rules/banPattern.d.ts +9 -0
- package/dist/src/data/solver/backtrack/rules/banPattern.js +77 -0
- package/dist/src/data/solver/backtrack/rules/cellCount.d.ts +7 -0
- package/dist/src/data/solver/backtrack/rules/cellCount.js +25 -0
- package/dist/src/data/solver/backtrack/rules/connectAll.d.ts +7 -0
- package/dist/src/data/solver/backtrack/rules/connectAll.js +44 -0
- package/dist/src/data/solver/backtrack/rules/regionArea.d.ts +8 -0
- package/dist/src/data/solver/backtrack/rules/regionArea.js +71 -0
- package/dist/src/data/solver/backtrack/rules/regionShape.d.ts +8 -0
- package/dist/src/data/solver/backtrack/rules/regionShape.js +57 -0
- package/dist/src/data/solver/backtrack/rules/sameShape.d.ts +8 -0
- package/dist/src/data/solver/backtrack/rules/sameShape.js +14 -0
- package/dist/src/data/solver/backtrack/rules/symbolsPerRegion.d.ts +10 -0
- package/dist/src/data/solver/backtrack/rules/symbolsPerRegion.js +102 -0
- package/dist/src/data/solver/backtrack/rules/uniqueShape.d.ts +8 -0
- package/dist/src/data/solver/backtrack/rules/uniqueShape.js +14 -0
- package/dist/src/data/solver/backtrack/symbols/areaNumber.d.ts +9 -0
- package/dist/src/data/solver/backtrack/symbols/areaNumber.js +75 -0
- package/dist/src/data/solver/backtrack/symbols/dart.d.ts +8 -0
- package/dist/src/data/solver/backtrack/symbols/dart.js +45 -0
- package/dist/src/data/solver/backtrack/symbols/directionLinker.d.ts +11 -0
- package/dist/src/data/solver/backtrack/symbols/directionLinker.js +121 -0
- package/dist/src/data/solver/backtrack/symbols/focus.d.ts +9 -0
- package/dist/src/data/solver/backtrack/symbols/focus.js +48 -0
- package/dist/src/data/solver/backtrack/symbols/galaxy.d.ts +9 -0
- package/dist/src/data/solver/backtrack/symbols/galaxy.js +14 -0
- package/dist/src/data/solver/backtrack/symbols/letter.d.ts +9 -0
- package/dist/src/data/solver/backtrack/symbols/letter.js +95 -0
- package/dist/src/data/solver/backtrack/symbols/lotus.d.ts +11 -0
- package/dist/src/data/solver/backtrack/symbols/lotus.js +55 -0
- package/dist/src/data/solver/backtrack/symbols/minesweeper.d.ts +9 -0
- package/dist/src/data/solver/backtrack/symbols/minesweeper.js +44 -0
- package/dist/src/data/solver/backtrack/symbols/myopia.d.ts +7 -0
- package/dist/src/data/solver/backtrack/symbols/myopia.js +73 -0
- package/dist/src/data/solver/backtrack/symbols/viewpoint.d.ts +7 -0
- package/dist/src/data/solver/backtrack/symbols/viewpoint.js +51 -0
- package/dist/src/data/solver/cspuz/cspuzSolver.d.ts +13 -0
- package/dist/src/data/solver/cspuz/cspuzSolver.js +124 -0
- package/dist/src/data/solver/cspuz/cspuzWorker.d.ts +1 -0
- package/dist/src/data/solver/cspuz/cspuzWorker.js +82 -0
- package/dist/src/data/solver/cspuz/jsonify.d.ts +3 -0
- package/dist/src/data/solver/cspuz/jsonify.js +215 -0
- package/dist/src/data/solver/eventIteratingSolver.d.ts +8 -0
- package/dist/src/data/solver/eventIteratingSolver.js +54 -0
- package/dist/src/data/solver/solver.d.ts +77 -0
- package/dist/src/data/solver/solver.js +59 -0
- package/dist/src/data/solver/universal/universalSolver.d.ts +7 -0
- package/dist/src/data/solver/universal/universalSolver.js +13 -0
- package/dist/src/data/solver/universal/universalWorker.d.ts +1 -0
- package/dist/src/data/solver/universal/universalWorker.js +128 -0
- package/dist/src/data/symbols/areaNumberSymbol.d.ts +31 -0
- package/dist/src/data/symbols/areaNumberSymbol.js +80 -0
- package/dist/src/data/symbols/customIconSymbol.d.ts +35 -0
- package/dist/src/data/symbols/customIconSymbol.js +94 -0
- package/dist/src/data/symbols/customSymbol.d.ts +25 -0
- package/dist/src/data/symbols/customSymbol.js +45 -0
- package/dist/src/data/symbols/customTextSymbol.d.ts +35 -0
- package/dist/src/data/symbols/customTextSymbol.js +95 -0
- package/dist/src/data/symbols/dartSymbol.d.ts +36 -0
- package/dist/src/data/symbols/dartSymbol.js +96 -0
- package/dist/src/data/symbols/directionLinkerSymbol.d.ts +29 -0
- package/dist/src/data/symbols/directionLinkerSymbol.js +232 -0
- package/dist/src/data/symbols/everyLetterSymbol.d.ts +32 -0
- package/dist/src/data/symbols/everyLetterSymbol.js +119 -0
- package/dist/src/data/symbols/focusSymbol.d.ts +40 -0
- package/dist/src/data/symbols/focusSymbol.js +159 -0
- package/dist/src/data/symbols/galaxySymbol.d.ts +27 -0
- package/dist/src/data/symbols/galaxySymbol.js +61 -0
- package/dist/src/data/symbols/hiddenSymbol.d.ts +38 -0
- package/dist/src/data/symbols/hiddenSymbol.js +113 -0
- package/dist/src/data/symbols/houseSymbol.d.ts +33 -0
- package/dist/src/data/symbols/houseSymbol.js +104 -0
- package/dist/src/data/symbols/index.d.ts +3 -0
- package/dist/src/data/symbols/index.js +10 -0
- package/dist/src/data/symbols/letterSymbol.d.ts +32 -0
- package/dist/src/data/symbols/letterSymbol.js +118 -0
- package/dist/src/data/symbols/lotusSymbol.d.ts +30 -0
- package/dist/src/data/symbols/lotusSymbol.js +132 -0
- package/dist/src/data/symbols/minesweeperSymbol.d.ts +33 -0
- package/dist/src/data/symbols/minesweeperSymbol.js +106 -0
- package/dist/src/data/symbols/myopiaSymbol.d.ts +37 -0
- package/dist/src/data/symbols/myopiaSymbol.js +182 -0
- package/dist/src/data/symbols/numberSymbol.d.ts +19 -0
- package/dist/src/data/symbols/numberSymbol.js +32 -0
- package/dist/src/data/symbols/symbol.d.ts +29 -0
- package/dist/src/data/symbols/symbol.js +87 -0
- package/dist/src/data/symbols/symbols.gen.d.ts +15 -0
- package/dist/src/data/symbols/symbols.gen.js +19 -0
- package/dist/src/data/symbols/unsupportedSymbol.d.ts +23 -0
- package/dist/src/data/symbols/unsupportedSymbol.js +47 -0
- package/dist/src/data/symbols/viewpointSymbol.d.ts +32 -0
- package/dist/src/data/symbols/viewpointSymbol.js +95 -0
- package/dist/src/data/tile.d.ts +26 -0
- package/dist/src/data/tile.js +56 -0
- package/dist/src/data/tileConnections.d.ts +25 -0
- package/dist/src/data/tileConnections.js +74 -0
- package/dist/src/data/validate.d.ts +5 -0
- package/dist/src/data/validate.js +131 -0
- package/dist/src/data/validateAsync.d.ts +15 -0
- package/dist/src/data/validateAsync.js +71 -0
- package/dist/src/data/validateAsyncWorker.d.ts +1 -0
- package/dist/src/data/validateAsyncWorker.js +9 -0
- package/dist/src/index.d.ts +109 -0
- package/dist/src/index.js +112 -0
- package/dist/src/polyfill/streamPolyfill.d.ts +2 -0
- package/dist/src/polyfill/streamPolyfill.js +1 -0
- package/package.json +3 -1
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
import { ConfigType } from '../config.js';
|
|
2
|
+
import GridData from '../grid.js';
|
|
3
|
+
import { Color } from '../primitives.js';
|
|
4
|
+
import AreaNumberSymbol from './areaNumberSymbol.js';
|
|
5
|
+
import LetterSymbol from './letterSymbol.js';
|
|
6
|
+
import NumberSymbol from './numberSymbol.js';
|
|
7
|
+
const OFFSETS = [
|
|
8
|
+
[0, -1],
|
|
9
|
+
[1, 0],
|
|
10
|
+
[0, 1],
|
|
11
|
+
[-1, 0],
|
|
12
|
+
];
|
|
13
|
+
export default class FocusSymbol extends NumberSymbol {
|
|
14
|
+
deadEnd;
|
|
15
|
+
get title() {
|
|
16
|
+
if (this.deadEnd) {
|
|
17
|
+
return 'Dead End';
|
|
18
|
+
}
|
|
19
|
+
else {
|
|
20
|
+
return 'Focus Number';
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
static CONFIGS = Object.freeze([
|
|
24
|
+
{
|
|
25
|
+
type: ConfigType.Number,
|
|
26
|
+
default: 0,
|
|
27
|
+
field: 'x',
|
|
28
|
+
description: 'X',
|
|
29
|
+
configurable: false,
|
|
30
|
+
},
|
|
31
|
+
{
|
|
32
|
+
type: ConfigType.Number,
|
|
33
|
+
default: 0,
|
|
34
|
+
field: 'y',
|
|
35
|
+
description: 'Y',
|
|
36
|
+
configurable: false,
|
|
37
|
+
},
|
|
38
|
+
{
|
|
39
|
+
type: ConfigType.Boolean,
|
|
40
|
+
default: false,
|
|
41
|
+
field: 'deadEnd',
|
|
42
|
+
description: 'Dead End',
|
|
43
|
+
explanation: 'A Dead End is a Focus Number of 1 that can be stacked with other symbols.',
|
|
44
|
+
configurable: true,
|
|
45
|
+
},
|
|
46
|
+
{
|
|
47
|
+
type: ConfigType.Number,
|
|
48
|
+
default: 1,
|
|
49
|
+
field: 'number',
|
|
50
|
+
description: 'Number',
|
|
51
|
+
explanation: 'Must be 1 for Dead Ends. Between 0 and 4 for Focus Numbers.',
|
|
52
|
+
configurable: true,
|
|
53
|
+
},
|
|
54
|
+
]);
|
|
55
|
+
static EXAMPLE_GRID = Object.freeze(GridData.create(['wwwww', 'bbbbw', 'wwbbw', 'wwwww']).withSymbols([
|
|
56
|
+
new FocusSymbol(0, 0, false, 1),
|
|
57
|
+
new FocusSymbol(4, 1, false, 2),
|
|
58
|
+
new FocusSymbol(1, 3, false, 3),
|
|
59
|
+
]));
|
|
60
|
+
static EXAMPLE_GRID_DEAD_END = Object.freeze(GridData.create(['wwwww', 'bbbbw', 'wwwbw', 'bbbbw']).withSymbols([
|
|
61
|
+
new FocusSymbol(0, 0, true, 1),
|
|
62
|
+
new FocusSymbol(4, 3, true, 1),
|
|
63
|
+
new FocusSymbol(0, 2, true, 1),
|
|
64
|
+
new FocusSymbol(2, 2, true, 1),
|
|
65
|
+
new AreaNumberSymbol(0, 2, 3),
|
|
66
|
+
new LetterSymbol(0, 0, 'A'),
|
|
67
|
+
new LetterSymbol(4, 3, 'A'),
|
|
68
|
+
]));
|
|
69
|
+
/**
|
|
70
|
+
* **Focus Numbers count directly adjacent cells of the same color**
|
|
71
|
+
* @param x - The x-coordinate of the symbol.
|
|
72
|
+
* @param y - The y-coordinate of the symbol.
|
|
73
|
+
* @param deadEnd - Whether this Focus Number is a Dead End.
|
|
74
|
+
* @param number - The focus number.
|
|
75
|
+
*/
|
|
76
|
+
constructor(x, y, deadEnd, number) {
|
|
77
|
+
if (deadEnd) {
|
|
78
|
+
number = 1;
|
|
79
|
+
}
|
|
80
|
+
super(x, y, number);
|
|
81
|
+
this.deadEnd = deadEnd;
|
|
82
|
+
this.deadEnd = deadEnd;
|
|
83
|
+
}
|
|
84
|
+
get id() {
|
|
85
|
+
return `focus`;
|
|
86
|
+
}
|
|
87
|
+
get placementStep() {
|
|
88
|
+
return 1;
|
|
89
|
+
}
|
|
90
|
+
get explanation() {
|
|
91
|
+
if (this.deadEnd) {
|
|
92
|
+
return `*Dead Ends* connect to one adjacent cell of the same color`;
|
|
93
|
+
}
|
|
94
|
+
else {
|
|
95
|
+
return '*Focus Numbers* count directly adjacent cells of the same color';
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
get configs() {
|
|
99
|
+
return FocusSymbol.CONFIGS;
|
|
100
|
+
}
|
|
101
|
+
createExampleGrid() {
|
|
102
|
+
if (this.deadEnd) {
|
|
103
|
+
return FocusSymbol.EXAMPLE_GRID_DEAD_END;
|
|
104
|
+
}
|
|
105
|
+
else {
|
|
106
|
+
return FocusSymbol.EXAMPLE_GRID;
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
countForColor(grid, color) {
|
|
110
|
+
let gray = 0;
|
|
111
|
+
let same = 0;
|
|
112
|
+
const visited = [];
|
|
113
|
+
for (const [dx, dy] of OFFSETS) {
|
|
114
|
+
const x = this.x + dx;
|
|
115
|
+
const y = this.y + dy;
|
|
116
|
+
if (grid.wrapAround.value) {
|
|
117
|
+
const pos = grid.toArrayCoordinates(x, y);
|
|
118
|
+
if (visited.some(v => v.x === pos.x && v.y === pos.y))
|
|
119
|
+
continue;
|
|
120
|
+
visited.push(pos);
|
|
121
|
+
}
|
|
122
|
+
const tile = grid.getTile(x, y);
|
|
123
|
+
if (!tile.exists)
|
|
124
|
+
continue;
|
|
125
|
+
if (tile.color === Color.Gray)
|
|
126
|
+
gray++;
|
|
127
|
+
else if (tile.color === color)
|
|
128
|
+
same++;
|
|
129
|
+
}
|
|
130
|
+
return { completed: same, possible: same + gray };
|
|
131
|
+
}
|
|
132
|
+
countTiles(grid) {
|
|
133
|
+
if (Math.floor(this.x) !== this.x || Math.floor(this.y) !== this.y)
|
|
134
|
+
return { completed: 0, possible: Number.MAX_SAFE_INTEGER };
|
|
135
|
+
const color = grid.getTile(this.x, this.y).color;
|
|
136
|
+
if (color === Color.Gray) {
|
|
137
|
+
const dark = this.countForColor(grid, Color.Dark);
|
|
138
|
+
const light = this.countForColor(grid, Color.Light);
|
|
139
|
+
return {
|
|
140
|
+
completed: Math.min(dark.completed, light.completed),
|
|
141
|
+
possible: Math.max(dark.possible, light.possible),
|
|
142
|
+
};
|
|
143
|
+
}
|
|
144
|
+
return this.countForColor(grid, color);
|
|
145
|
+
}
|
|
146
|
+
descriptionEquals(other) {
|
|
147
|
+
return this.id === other.id && this.explanation === other.explanation;
|
|
148
|
+
}
|
|
149
|
+
copyWith({ x, y, deadEnd, number, }) {
|
|
150
|
+
return new FocusSymbol(x ?? this.x, y ?? this.y, deadEnd ?? this.deadEnd, number ?? this.number);
|
|
151
|
+
}
|
|
152
|
+
withNumber(number) {
|
|
153
|
+
return this.copyWith({ number });
|
|
154
|
+
}
|
|
155
|
+
withDeadEnd(deadEnd) {
|
|
156
|
+
return this.copyWith({ deadEnd });
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
export const instance = new FocusSymbol(0, 0, false, 1);
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { AnyConfig } from '../config.js';
|
|
2
|
+
import GridData from '../grid.js';
|
|
3
|
+
import { State } from '../primitives.js';
|
|
4
|
+
import DirectionLinkerSymbol from './directionLinkerSymbol.js';
|
|
5
|
+
export default class GalaxySymbol extends DirectionLinkerSymbol {
|
|
6
|
+
readonly x: number;
|
|
7
|
+
readonly y: number;
|
|
8
|
+
readonly title = "Galaxy";
|
|
9
|
+
private static readonly linkedDirections;
|
|
10
|
+
/**
|
|
11
|
+
* **Galaxies are centers of rotational symmetry**
|
|
12
|
+
*
|
|
13
|
+
* @param x - The x-coordinate of the symbol.
|
|
14
|
+
* @param y - The y-coordinate of the symbol.
|
|
15
|
+
*/
|
|
16
|
+
constructor(x: number, y: number);
|
|
17
|
+
get id(): string;
|
|
18
|
+
get explanation(): string;
|
|
19
|
+
get configs(): readonly AnyConfig[] | null;
|
|
20
|
+
createExampleGrid(): GridData;
|
|
21
|
+
validateSymbol(grid: GridData): State;
|
|
22
|
+
copyWith({ x, y }: {
|
|
23
|
+
x?: number;
|
|
24
|
+
y?: number;
|
|
25
|
+
}): this;
|
|
26
|
+
}
|
|
27
|
+
export declare const instance: GalaxySymbol;
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { ConfigType } from '../config.js';
|
|
2
|
+
import GridData from '../grid.js';
|
|
3
|
+
import { Direction } from '../primitives.js';
|
|
4
|
+
import DirectionLinkerSymbol from './directionLinkerSymbol.js';
|
|
5
|
+
export default class GalaxySymbol extends DirectionLinkerSymbol {
|
|
6
|
+
x;
|
|
7
|
+
y;
|
|
8
|
+
title = 'Galaxy';
|
|
9
|
+
static linkedDirections = {
|
|
10
|
+
[Direction.Left]: Direction.Right,
|
|
11
|
+
[Direction.Up]: Direction.Down,
|
|
12
|
+
[Direction.Right]: Direction.Left,
|
|
13
|
+
[Direction.Down]: Direction.Up,
|
|
14
|
+
};
|
|
15
|
+
/**
|
|
16
|
+
* **Galaxies are centers of rotational symmetry**
|
|
17
|
+
*
|
|
18
|
+
* @param x - The x-coordinate of the symbol.
|
|
19
|
+
* @param y - The y-coordinate of the symbol.
|
|
20
|
+
*/
|
|
21
|
+
constructor(x, y) {
|
|
22
|
+
super(x, y);
|
|
23
|
+
this.x = x;
|
|
24
|
+
this.y = y;
|
|
25
|
+
super.changeDirections(GalaxySymbol.linkedDirections);
|
|
26
|
+
}
|
|
27
|
+
get id() {
|
|
28
|
+
return `galaxy`;
|
|
29
|
+
}
|
|
30
|
+
get explanation() {
|
|
31
|
+
return `*Galaxies* are centers of rotational symmetry`;
|
|
32
|
+
}
|
|
33
|
+
get configs() {
|
|
34
|
+
return Object.freeze([
|
|
35
|
+
{
|
|
36
|
+
type: ConfigType.Number,
|
|
37
|
+
default: 0,
|
|
38
|
+
field: 'x',
|
|
39
|
+
description: 'X',
|
|
40
|
+
configurable: false,
|
|
41
|
+
},
|
|
42
|
+
{
|
|
43
|
+
type: ConfigType.Number,
|
|
44
|
+
default: 0,
|
|
45
|
+
field: 'y',
|
|
46
|
+
description: 'Y',
|
|
47
|
+
configurable: false,
|
|
48
|
+
},
|
|
49
|
+
]);
|
|
50
|
+
}
|
|
51
|
+
createExampleGrid() {
|
|
52
|
+
return Object.freeze(GridData.create(['wbbbb', 'wbwww', 'bbwbb', 'wwwbb']).addSymbol(new GalaxySymbol(2, 2)));
|
|
53
|
+
}
|
|
54
|
+
validateSymbol(grid) {
|
|
55
|
+
return super.validateSymbol(grid);
|
|
56
|
+
}
|
|
57
|
+
copyWith({ x, y }) {
|
|
58
|
+
return new GalaxySymbol(x ?? this.x, y ?? this.y);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
export const instance = new GalaxySymbol(0, 0);
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { AnyConfig } from '../config.js';
|
|
2
|
+
import { SymbolDisplayHandler } from '../events/onSymbolDisplay.js';
|
|
3
|
+
import GridData from '../grid.js';
|
|
4
|
+
import { State } from '../primitives.js';
|
|
5
|
+
import Symbol from './symbol.js';
|
|
6
|
+
export default class HiddenSymbol extends Symbol implements SymbolDisplayHandler {
|
|
7
|
+
readonly x: number;
|
|
8
|
+
readonly y: number;
|
|
9
|
+
readonly revealLocation: boolean;
|
|
10
|
+
readonly title = "Hidden Symbol Marker";
|
|
11
|
+
get configExplanation(): string;
|
|
12
|
+
private static readonly CONFIGS;
|
|
13
|
+
private static readonly EXAMPLE_GRID;
|
|
14
|
+
/**
|
|
15
|
+
* **Hidden Symbols: color cells correctly to reveal more clues**
|
|
16
|
+
*
|
|
17
|
+
* @param x - The x-coordinate of the symbol.
|
|
18
|
+
* @param y - The y-coordinate of the symbol.
|
|
19
|
+
* @param revealLocation - Whether to reveal the location of the symbol.
|
|
20
|
+
*/
|
|
21
|
+
constructor(x: number, y: number, revealLocation?: boolean);
|
|
22
|
+
get id(): string;
|
|
23
|
+
get explanation(): string;
|
|
24
|
+
get configs(): readonly AnyConfig[] | null;
|
|
25
|
+
createExampleGrid(): GridData;
|
|
26
|
+
get necessaryForCompletion(): boolean;
|
|
27
|
+
get visibleWhenSolving(): boolean;
|
|
28
|
+
get sortOrder(): number;
|
|
29
|
+
validateSymbol(grid: GridData, solution: GridData | null): State;
|
|
30
|
+
onSymbolDisplay(grid: GridData, solution: GridData | null, symbol: Symbol, editing: boolean): boolean;
|
|
31
|
+
copyWith({ x, y, revealLocation, }: {
|
|
32
|
+
x?: number;
|
|
33
|
+
y?: number;
|
|
34
|
+
revealLocation?: boolean;
|
|
35
|
+
}): this;
|
|
36
|
+
withRevealLocation(revealLocation: boolean): this;
|
|
37
|
+
}
|
|
38
|
+
export declare const instance: HiddenSymbol;
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
import { ConfigType } from '../config.js';
|
|
2
|
+
import GridData from '../grid.js';
|
|
3
|
+
import { Color, State } from '../primitives.js';
|
|
4
|
+
import CustomIconSymbol from './customIconSymbol.js';
|
|
5
|
+
import Symbol from './symbol.js';
|
|
6
|
+
export default class HiddenSymbol extends Symbol {
|
|
7
|
+
x;
|
|
8
|
+
y;
|
|
9
|
+
revealLocation;
|
|
10
|
+
title = 'Hidden Symbol Marker';
|
|
11
|
+
get configExplanation() {
|
|
12
|
+
return 'Other symbols in the same location will be hidden until this tile is colored correctly.';
|
|
13
|
+
}
|
|
14
|
+
static CONFIGS = Object.freeze([
|
|
15
|
+
{
|
|
16
|
+
type: ConfigType.Number,
|
|
17
|
+
default: 0,
|
|
18
|
+
field: 'x',
|
|
19
|
+
description: 'X',
|
|
20
|
+
configurable: false,
|
|
21
|
+
},
|
|
22
|
+
{
|
|
23
|
+
type: ConfigType.Number,
|
|
24
|
+
default: 0,
|
|
25
|
+
field: 'y',
|
|
26
|
+
description: 'Y',
|
|
27
|
+
configurable: false,
|
|
28
|
+
},
|
|
29
|
+
{
|
|
30
|
+
type: ConfigType.Boolean,
|
|
31
|
+
default: false,
|
|
32
|
+
field: 'revealLocation',
|
|
33
|
+
description: 'Reveal symbol location',
|
|
34
|
+
explanation: 'Whether to show this symbol when the tile is not yet colored correctly.',
|
|
35
|
+
configurable: true,
|
|
36
|
+
},
|
|
37
|
+
]);
|
|
38
|
+
static EXAMPLE_GRID = Object.freeze(GridData.create(['w']).addSymbol(new CustomIconSymbol('', GridData.create(['.']), 0, 0, 'MdHideSource') // Not using HiddenSymbol here because it is meant to be hidden in non-edit mode
|
|
39
|
+
));
|
|
40
|
+
/**
|
|
41
|
+
* **Hidden Symbols: color cells correctly to reveal more clues**
|
|
42
|
+
*
|
|
43
|
+
* @param x - The x-coordinate of the symbol.
|
|
44
|
+
* @param y - The y-coordinate of the symbol.
|
|
45
|
+
* @param revealLocation - Whether to reveal the location of the symbol.
|
|
46
|
+
*/
|
|
47
|
+
constructor(x, y, revealLocation = false) {
|
|
48
|
+
super(x, y);
|
|
49
|
+
this.x = x;
|
|
50
|
+
this.y = y;
|
|
51
|
+
this.revealLocation = revealLocation;
|
|
52
|
+
this.revealLocation = revealLocation;
|
|
53
|
+
}
|
|
54
|
+
get id() {
|
|
55
|
+
return `hidden`;
|
|
56
|
+
}
|
|
57
|
+
get explanation() {
|
|
58
|
+
return '*Hidden Symbols*: color cells correctly to reveal more clues';
|
|
59
|
+
}
|
|
60
|
+
get configs() {
|
|
61
|
+
return HiddenSymbol.CONFIGS;
|
|
62
|
+
}
|
|
63
|
+
createExampleGrid() {
|
|
64
|
+
return HiddenSymbol.EXAMPLE_GRID;
|
|
65
|
+
}
|
|
66
|
+
get necessaryForCompletion() {
|
|
67
|
+
return false;
|
|
68
|
+
}
|
|
69
|
+
get visibleWhenSolving() {
|
|
70
|
+
return this.revealLocation;
|
|
71
|
+
}
|
|
72
|
+
get sortOrder() {
|
|
73
|
+
return 0;
|
|
74
|
+
}
|
|
75
|
+
validateSymbol(grid, solution) {
|
|
76
|
+
const thisX = Math.floor(this.x);
|
|
77
|
+
const thisY = Math.floor(this.y);
|
|
78
|
+
const thisColor = grid.getTile(thisX, thisY).color;
|
|
79
|
+
if (solution) {
|
|
80
|
+
return thisColor === solution.getTile(thisX, thisY).color
|
|
81
|
+
? State.Satisfied
|
|
82
|
+
: State.Incomplete;
|
|
83
|
+
}
|
|
84
|
+
else {
|
|
85
|
+
return thisColor !== Color.Gray ? State.Satisfied : State.Incomplete;
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
onSymbolDisplay(grid, solution, symbol, editing) {
|
|
89
|
+
if (editing)
|
|
90
|
+
return true;
|
|
91
|
+
const thisX = Math.floor(this.x);
|
|
92
|
+
const thisY = Math.floor(this.y);
|
|
93
|
+
const symX = Math.floor(symbol.x);
|
|
94
|
+
const symY = Math.floor(symbol.y);
|
|
95
|
+
if (thisX !== symX || thisY !== symY)
|
|
96
|
+
return true;
|
|
97
|
+
const thisColor = grid.getTile(thisX, thisY).color;
|
|
98
|
+
const colorMatch = solution
|
|
99
|
+
? thisColor === solution.getTile(thisX, thisY).color
|
|
100
|
+
: thisColor !== Color.Gray;
|
|
101
|
+
if (symbol.id === this.id) {
|
|
102
|
+
return !colorMatch;
|
|
103
|
+
}
|
|
104
|
+
return colorMatch;
|
|
105
|
+
}
|
|
106
|
+
copyWith({ x, y, revealLocation, }) {
|
|
107
|
+
return new HiddenSymbol(x ?? this.x, y ?? this.y, revealLocation ?? this.revealLocation);
|
|
108
|
+
}
|
|
109
|
+
withRevealLocation(revealLocation) {
|
|
110
|
+
return this.copyWith({ revealLocation });
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
export const instance = new HiddenSymbol(0, 0);
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { AnyConfig } from '../config.js';
|
|
2
|
+
import GridData from '../grid.js';
|
|
3
|
+
import NumberSymbol from './numberSymbol.js';
|
|
4
|
+
export default class HouseSymbol extends NumberSymbol {
|
|
5
|
+
readonly x: number;
|
|
6
|
+
readonly y: number;
|
|
7
|
+
readonly number: number;
|
|
8
|
+
readonly title = "House";
|
|
9
|
+
private static readonly CONFIGS;
|
|
10
|
+
private static readonly EXAMPLE_GRID;
|
|
11
|
+
/**
|
|
12
|
+
* **Houses must connect to exactly one other house**
|
|
13
|
+
*
|
|
14
|
+
* @param x - The x-coordinate of the symbol.
|
|
15
|
+
* @param y - The y-coordinate of the symbol.
|
|
16
|
+
* @param number - The number of houses in this region.
|
|
17
|
+
*/
|
|
18
|
+
constructor(x: number, y: number, number: number);
|
|
19
|
+
get id(): string;
|
|
20
|
+
get explanation(): string;
|
|
21
|
+
get configs(): readonly AnyConfig[] | null;
|
|
22
|
+
createExampleGrid(): GridData;
|
|
23
|
+
countTiles(grid: GridData): {
|
|
24
|
+
completed: number;
|
|
25
|
+
possible: number;
|
|
26
|
+
} | null;
|
|
27
|
+
copyWith({ x, y, number, }: {
|
|
28
|
+
x?: number;
|
|
29
|
+
y?: number;
|
|
30
|
+
number?: number;
|
|
31
|
+
}): this;
|
|
32
|
+
}
|
|
33
|
+
export declare const instance: HouseSymbol;
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
import { ConfigType } from '../config.js';
|
|
2
|
+
import GridData from '../grid.js';
|
|
3
|
+
import { array } from '../dataHelper.js';
|
|
4
|
+
import { Color } from '../primitives.js';
|
|
5
|
+
import NumberSymbol from './numberSymbol.js';
|
|
6
|
+
export default class HouseSymbol extends NumberSymbol {
|
|
7
|
+
x;
|
|
8
|
+
y;
|
|
9
|
+
number;
|
|
10
|
+
title = 'House';
|
|
11
|
+
static CONFIGS = Object.freeze([
|
|
12
|
+
{
|
|
13
|
+
type: ConfigType.Number,
|
|
14
|
+
default: 0,
|
|
15
|
+
field: 'x',
|
|
16
|
+
description: 'X',
|
|
17
|
+
configurable: false,
|
|
18
|
+
},
|
|
19
|
+
{
|
|
20
|
+
type: ConfigType.Number,
|
|
21
|
+
default: 0,
|
|
22
|
+
field: 'y',
|
|
23
|
+
description: 'Y',
|
|
24
|
+
configurable: false,
|
|
25
|
+
},
|
|
26
|
+
{
|
|
27
|
+
type: ConfigType.Number,
|
|
28
|
+
default: 2,
|
|
29
|
+
field: 'number',
|
|
30
|
+
description: 'Number',
|
|
31
|
+
explanation: 'Number of houses in this region',
|
|
32
|
+
configurable: true,
|
|
33
|
+
},
|
|
34
|
+
]);
|
|
35
|
+
static EXAMPLE_GRID = Object.freeze(GridData.create(['bbbww', 'wwwbw', 'wbbbw', 'wwwww'])
|
|
36
|
+
.addSymbol(new HouseSymbol(0, 0, 2))
|
|
37
|
+
.addSymbol(new HouseSymbol(2, 0, 2))
|
|
38
|
+
.addSymbol(new HouseSymbol(3, 0, 2))
|
|
39
|
+
.addSymbol(new HouseSymbol(2, 1, 2))
|
|
40
|
+
.addSymbol(new HouseSymbol(3, 1, 2))
|
|
41
|
+
.addSymbol(new HouseSymbol(1, 2, 2)));
|
|
42
|
+
/**
|
|
43
|
+
* **Houses must connect to exactly one other house**
|
|
44
|
+
*
|
|
45
|
+
* @param x - The x-coordinate of the symbol.
|
|
46
|
+
* @param y - The y-coordinate of the symbol.
|
|
47
|
+
* @param number - The number of houses in this region.
|
|
48
|
+
*/
|
|
49
|
+
constructor(x, y, number) {
|
|
50
|
+
super(x, y, number);
|
|
51
|
+
this.x = x;
|
|
52
|
+
this.y = y;
|
|
53
|
+
this.number = number;
|
|
54
|
+
}
|
|
55
|
+
get id() {
|
|
56
|
+
return `house`;
|
|
57
|
+
}
|
|
58
|
+
get explanation() {
|
|
59
|
+
return '*House numbers* count the number of houses in the region';
|
|
60
|
+
}
|
|
61
|
+
get configs() {
|
|
62
|
+
return HouseSymbol.CONFIGS;
|
|
63
|
+
}
|
|
64
|
+
createExampleGrid() {
|
|
65
|
+
return HouseSymbol.EXAMPLE_GRID;
|
|
66
|
+
}
|
|
67
|
+
countTiles(grid) {
|
|
68
|
+
if (!this.validateSubtilePlacement(grid))
|
|
69
|
+
return null;
|
|
70
|
+
const thisX = Math.floor(this.x);
|
|
71
|
+
const thisY = Math.floor(this.y);
|
|
72
|
+
const visited = array(grid.width, grid.height, () => false);
|
|
73
|
+
const connected = array(grid.width, grid.height, () => false);
|
|
74
|
+
const color = grid.getTile(thisX, thisY).color;
|
|
75
|
+
if (color === Color.Gray)
|
|
76
|
+
return { completed: 0, possible: Number.MAX_SAFE_INTEGER };
|
|
77
|
+
grid.iterateArea({ x: thisX, y: thisY }, tile => tile.color === Color.Gray || tile.color === color, (_, x, y) => {
|
|
78
|
+
visited[y][x] = true;
|
|
79
|
+
});
|
|
80
|
+
grid.iterateArea({ x: thisX, y: thisY }, tile => tile.color === color, (_, x, y) => {
|
|
81
|
+
connected[y][x] = true;
|
|
82
|
+
});
|
|
83
|
+
let completedHouses = 0;
|
|
84
|
+
let possibleHouses = 0;
|
|
85
|
+
for (const symbol of grid.symbols.get(this.id) ?? []) {
|
|
86
|
+
if (symbol instanceof HouseSymbol) {
|
|
87
|
+
const symbolX = Math.floor(symbol.x);
|
|
88
|
+
const symbolY = Math.floor(symbol.y);
|
|
89
|
+
if (connected[symbolY][symbolX])
|
|
90
|
+
completedHouses++;
|
|
91
|
+
else if (visited[symbolY][symbolX])
|
|
92
|
+
possibleHouses++;
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
return {
|
|
96
|
+
completed: completedHouses,
|
|
97
|
+
possible: completedHouses + possibleHouses,
|
|
98
|
+
};
|
|
99
|
+
}
|
|
100
|
+
copyWith({ x, y, number, }) {
|
|
101
|
+
return new HouseSymbol(x ?? this.x, y ?? this.y, number ?? this.number);
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
export const instance = new HouseSymbol(0, 0, 2);
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import * as symbols from './symbols.gen.js';
|
|
2
|
+
const allSymbols = new Map();
|
|
3
|
+
function register(prototype) {
|
|
4
|
+
allSymbols.set(prototype.id, prototype);
|
|
5
|
+
}
|
|
6
|
+
Object.values(symbols).forEach(symbol => {
|
|
7
|
+
if (symbol)
|
|
8
|
+
register(symbol);
|
|
9
|
+
});
|
|
10
|
+
export { allSymbols };
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { AnyConfig } from '../config.js';
|
|
2
|
+
import GridData from '../grid.js';
|
|
3
|
+
import { State } from '../primitives.js';
|
|
4
|
+
import Symbol from './symbol.js';
|
|
5
|
+
export default class LetterSymbol extends Symbol {
|
|
6
|
+
readonly x: number;
|
|
7
|
+
readonly y: number;
|
|
8
|
+
readonly letter: string;
|
|
9
|
+
readonly title = "Letter";
|
|
10
|
+
private static readonly CONFIGS;
|
|
11
|
+
private static readonly EXAMPLE_GRID;
|
|
12
|
+
/**
|
|
13
|
+
* **Letters must be sorted into one type per area**
|
|
14
|
+
*
|
|
15
|
+
* @param x - The x-coordinate of the symbol.
|
|
16
|
+
* @param y - The y-coordinate of the symbol.
|
|
17
|
+
* @param letter - The letter of the symbol.
|
|
18
|
+
*/
|
|
19
|
+
constructor(x: number, y: number, letter: string);
|
|
20
|
+
get id(): string;
|
|
21
|
+
get explanation(): string;
|
|
22
|
+
get configs(): readonly AnyConfig[] | null;
|
|
23
|
+
createExampleGrid(): GridData;
|
|
24
|
+
validateSymbol(grid: GridData): State;
|
|
25
|
+
copyWith({ x, y, letter, }: {
|
|
26
|
+
x?: number;
|
|
27
|
+
y?: number;
|
|
28
|
+
letter?: string;
|
|
29
|
+
}): this;
|
|
30
|
+
withLetter(letter: string): this;
|
|
31
|
+
}
|
|
32
|
+
export declare const instance: LetterSymbol;
|