@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,30 @@
|
|
|
1
|
+
import BTModule, { BTTile, colorToBTTile, } from '../data';
|
|
2
|
+
export default class CellCountBTModule extends BTModule {
|
|
3
|
+
constructor(instr) {
|
|
4
|
+
super();
|
|
5
|
+
Object.defineProperty(this, "instr", {
|
|
6
|
+
enumerable: true,
|
|
7
|
+
configurable: true,
|
|
8
|
+
writable: true,
|
|
9
|
+
value: void 0
|
|
10
|
+
});
|
|
11
|
+
this.instr = instr;
|
|
12
|
+
}
|
|
13
|
+
checkGlobal(grid) {
|
|
14
|
+
const color = colorToBTTile(this.instr.color);
|
|
15
|
+
let colored = 0;
|
|
16
|
+
let possible = 0;
|
|
17
|
+
for (let y = 0; y < grid.height; y++) {
|
|
18
|
+
for (let x = 0; x < grid.width; x++) {
|
|
19
|
+
const tile = grid.getTile(x, y);
|
|
20
|
+
if (tile === color)
|
|
21
|
+
colored += 1;
|
|
22
|
+
else if (tile === BTTile.Empty)
|
|
23
|
+
possible += 1;
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
if (colored > this.instr.count || colored + possible < this.instr.count)
|
|
27
|
+
return false;
|
|
28
|
+
return { tilesNeedCheck: null, ratings: null };
|
|
29
|
+
}
|
|
30
|
+
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import ConnectAllRule from '../../../rules/connectAllRule';
|
|
2
|
+
import BTModule, { BTGridData, CheckResult } from '../data';
|
|
3
|
+
export default class ConnectAllBTModule extends BTModule {
|
|
4
|
+
instr: ConnectAllRule;
|
|
5
|
+
constructor(instr: ConnectAllRule);
|
|
6
|
+
checkGlobal(grid: BTGridData): CheckResult | false;
|
|
7
|
+
}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import BTModule, { IntArray2D, colorToBTTile, getOppositeColor, } from '../data';
|
|
2
|
+
export default class ConnectAllBTModule extends BTModule {
|
|
3
|
+
constructor(instr) {
|
|
4
|
+
super();
|
|
5
|
+
Object.defineProperty(this, "instr", {
|
|
6
|
+
enumerable: true,
|
|
7
|
+
configurable: true,
|
|
8
|
+
writable: true,
|
|
9
|
+
value: void 0
|
|
10
|
+
});
|
|
11
|
+
this.instr = instr;
|
|
12
|
+
}
|
|
13
|
+
checkGlobal(grid) {
|
|
14
|
+
const color = colorToBTTile(this.instr.color);
|
|
15
|
+
// Find all same cells
|
|
16
|
+
const sameCells = [];
|
|
17
|
+
for (let y = 0; y < grid.height; y++) {
|
|
18
|
+
for (let x = 0; x < grid.width; x++) {
|
|
19
|
+
if (grid.getTile(x, y) === color) {
|
|
20
|
+
sameCells.push({ x, y });
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
// If there are no same cells, return true
|
|
25
|
+
if (sameCells.length === 0)
|
|
26
|
+
return { tilesNeedCheck: null, ratings: null };
|
|
27
|
+
const queue = [sameCells[0]];
|
|
28
|
+
const visited = IntArray2D.create(grid.width, grid.height);
|
|
29
|
+
// Perform flood fill
|
|
30
|
+
visited.set(sameCells[0].x, sameCells[0].y, 1);
|
|
31
|
+
while (queue.length > 0) {
|
|
32
|
+
const curPos = queue.pop();
|
|
33
|
+
for (const edge of grid.getEdges(curPos)) {
|
|
34
|
+
if (visited.get(edge.x, edge.y) ||
|
|
35
|
+
grid.getTile(edge.x, edge.y) === getOppositeColor(color)) {
|
|
36
|
+
continue;
|
|
37
|
+
}
|
|
38
|
+
visited.set(edge.x, edge.y, 1);
|
|
39
|
+
queue.push(edge);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
// Check if any same cell is not reachable
|
|
43
|
+
for (const cell of sameCells) {
|
|
44
|
+
if (!visited.get(cell.x, cell.y))
|
|
45
|
+
return false;
|
|
46
|
+
}
|
|
47
|
+
return { tilesNeedCheck: null, ratings: null };
|
|
48
|
+
}
|
|
49
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import RegionAreaRule from '../../../rules/regionAreaRule';
|
|
2
|
+
import BTModule, { BTGridData, CheckResult } from '../data';
|
|
3
|
+
export default class RegionAreaBTModule extends BTModule {
|
|
4
|
+
instr: RegionAreaRule;
|
|
5
|
+
constructor(instr: RegionAreaRule);
|
|
6
|
+
checkGlobal(grid: BTGridData): CheckResult | false;
|
|
7
|
+
private visitArea;
|
|
8
|
+
}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import BTModule, { BTTile, IntArray2D, colorToBTTile, } from '../data';
|
|
2
|
+
export default class RegionAreaBTModule extends BTModule {
|
|
3
|
+
constructor(instr) {
|
|
4
|
+
super();
|
|
5
|
+
Object.defineProperty(this, "instr", {
|
|
6
|
+
enumerable: true,
|
|
7
|
+
configurable: true,
|
|
8
|
+
writable: true,
|
|
9
|
+
value: void 0
|
|
10
|
+
});
|
|
11
|
+
this.instr = instr;
|
|
12
|
+
}
|
|
13
|
+
checkGlobal(grid) {
|
|
14
|
+
const color = colorToBTTile(this.instr.color);
|
|
15
|
+
const visited = IntArray2D.create(grid.width, grid.height);
|
|
16
|
+
let id = 0;
|
|
17
|
+
for (let y = 0; y < grid.height; y++) {
|
|
18
|
+
for (let x = 0; x < grid.width; x++) {
|
|
19
|
+
if (visited.get(x, y) & 0b01111111)
|
|
20
|
+
continue;
|
|
21
|
+
if (grid.getTile(x, y) !== color)
|
|
22
|
+
continue;
|
|
23
|
+
id += 1;
|
|
24
|
+
if (id > 127)
|
|
25
|
+
throw new Error('Too many regions!');
|
|
26
|
+
if (!this.visitArea(grid, color, visited, { x, y }, id))
|
|
27
|
+
return false;
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
return { tilesNeedCheck: null, ratings: null };
|
|
31
|
+
}
|
|
32
|
+
visitArea(grid, tile, visited, pos, id) {
|
|
33
|
+
const sameTileQueue = [pos];
|
|
34
|
+
const usableTileQueue = [];
|
|
35
|
+
let sameCellCount = 0;
|
|
36
|
+
let usableCellCount = 0;
|
|
37
|
+
visited.set(pos.x, pos.y, id);
|
|
38
|
+
// Count same tile
|
|
39
|
+
while (sameTileQueue.length > 0) {
|
|
40
|
+
const curPos = sameTileQueue.pop();
|
|
41
|
+
sameCellCount += 1;
|
|
42
|
+
for (const edge of grid.getEdges(curPos)) {
|
|
43
|
+
if ((visited.get(edge.x, edge.y) & 0b01111111) === id)
|
|
44
|
+
continue;
|
|
45
|
+
const edgeTile = grid.getTile(edge.x, edge.y);
|
|
46
|
+
if (edgeTile === BTTile.Empty) {
|
|
47
|
+
usableTileQueue.push(edge);
|
|
48
|
+
visited.set(edge.x, edge.y, id | 0b10000000);
|
|
49
|
+
}
|
|
50
|
+
else if (edgeTile === tile) {
|
|
51
|
+
sameTileQueue.push(edge);
|
|
52
|
+
visited.set(edge.x, edge.y, id);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
if (sameCellCount > this.instr.size)
|
|
57
|
+
return false;
|
|
58
|
+
// Count usable tile
|
|
59
|
+
while (usableTileQueue.length > 0) {
|
|
60
|
+
const curPos = usableTileQueue.pop();
|
|
61
|
+
usableCellCount += 1;
|
|
62
|
+
if (sameCellCount + usableCellCount >= this.instr.size)
|
|
63
|
+
return true;
|
|
64
|
+
for (const edge of grid.getEdges(curPos)) {
|
|
65
|
+
if ((visited.get(edge.x, edge.y) & 0b01111111) === id)
|
|
66
|
+
continue;
|
|
67
|
+
const edgeTile = grid.getTile(edge.x, edge.y);
|
|
68
|
+
if (edgeTile === BTTile.Empty || edgeTile === tile) {
|
|
69
|
+
usableTileQueue.push(edge);
|
|
70
|
+
visited.set(edge.x, edge.y, id | 0b10000000);
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
return sameCellCount + usableCellCount >= this.instr.size;
|
|
75
|
+
}
|
|
76
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import RegionShapeRule, { ShapeRegions } from '../../../rules/regionShapeRule';
|
|
2
|
+
import BTModule, { BTGridData } from '../data';
|
|
3
|
+
export default abstract class RegionShapeBTModule extends BTModule {
|
|
4
|
+
instr: RegionShapeRule;
|
|
5
|
+
constructor(instr: RegionShapeRule);
|
|
6
|
+
protected getShapeRegions(grid: BTGridData): ShapeRegions['regions'];
|
|
7
|
+
private visitArea;
|
|
8
|
+
}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import { normalizeShape, positionsToShape, shapeEquals } from '../../../shapes';
|
|
2
|
+
import BTModule, { BTTile, IntArray2D, colorToBTTile, } from '../data';
|
|
3
|
+
export default class RegionShapeBTModule extends BTModule {
|
|
4
|
+
constructor(instr) {
|
|
5
|
+
super();
|
|
6
|
+
Object.defineProperty(this, "instr", {
|
|
7
|
+
enumerable: true,
|
|
8
|
+
configurable: true,
|
|
9
|
+
writable: true,
|
|
10
|
+
value: void 0
|
|
11
|
+
});
|
|
12
|
+
this.instr = instr;
|
|
13
|
+
}
|
|
14
|
+
getShapeRegions(grid) {
|
|
15
|
+
// TODO: This is extremely slow, because it doesn't check shapes when shapes are not fully enclosed
|
|
16
|
+
const visited = IntArray2D.create(grid.width, grid.height);
|
|
17
|
+
const regions = [];
|
|
18
|
+
for (let y = 0; y < grid.height; y++) {
|
|
19
|
+
for (let x = 0; x < grid.width; x++) {
|
|
20
|
+
const tile = grid.getTile(x, y);
|
|
21
|
+
if (tile !== colorToBTTile(this.instr.color) || visited.get(x, y))
|
|
22
|
+
continue;
|
|
23
|
+
const positions = this.visitArea(grid, tile, visited, { x, y });
|
|
24
|
+
if (!positions)
|
|
25
|
+
continue;
|
|
26
|
+
const shape = normalizeShape(positionsToShape(positions, this.instr.color));
|
|
27
|
+
const existing = regions.find(island => shapeEquals(island.shape, shape));
|
|
28
|
+
if (existing) {
|
|
29
|
+
existing.count++;
|
|
30
|
+
}
|
|
31
|
+
else {
|
|
32
|
+
regions.push({ positions, shape, count: 1 });
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
return regions;
|
|
37
|
+
}
|
|
38
|
+
visitArea(grid, tile, visited, pos) {
|
|
39
|
+
const positions = [pos];
|
|
40
|
+
const sameTileQueue = [pos];
|
|
41
|
+
let incomplete = false;
|
|
42
|
+
visited.set(pos.x, pos.y, 1);
|
|
43
|
+
// Count same tile
|
|
44
|
+
while (sameTileQueue.length > 0) {
|
|
45
|
+
const curPos = sameTileQueue.pop();
|
|
46
|
+
for (const edge of grid.getEdges(curPos)) {
|
|
47
|
+
if (visited.get(edge.x, edge.y))
|
|
48
|
+
continue;
|
|
49
|
+
const edgeTile = grid.getTile(edge.x, edge.y);
|
|
50
|
+
if (edgeTile === BTTile.Empty) {
|
|
51
|
+
incomplete = true;
|
|
52
|
+
}
|
|
53
|
+
else if (edgeTile === tile) {
|
|
54
|
+
positions.push(edge);
|
|
55
|
+
sameTileQueue.push(edge);
|
|
56
|
+
visited.set(edge.x, edge.y, 1);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
return incomplete ? null : positions;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import SameShapeRule from '../../../rules/sameShapeRule';
|
|
2
|
+
import { BTGridData, CheckResult } from '../data';
|
|
3
|
+
import RegionShapeBTModule from './regionShape';
|
|
4
|
+
export default class SameShapeBTModule extends RegionShapeBTModule {
|
|
5
|
+
instr: SameShapeRule;
|
|
6
|
+
constructor(instr: SameShapeRule);
|
|
7
|
+
checkGlobal(grid: BTGridData): CheckResult | false;
|
|
8
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import RegionShapeBTModule from './regionShape';
|
|
2
|
+
export default class SameShapeBTModule extends RegionShapeBTModule {
|
|
3
|
+
constructor(instr) {
|
|
4
|
+
super(instr);
|
|
5
|
+
Object.defineProperty(this, "instr", {
|
|
6
|
+
enumerable: true,
|
|
7
|
+
configurable: true,
|
|
8
|
+
writable: true,
|
|
9
|
+
value: void 0
|
|
10
|
+
});
|
|
11
|
+
this.instr = instr;
|
|
12
|
+
}
|
|
13
|
+
checkGlobal(grid) {
|
|
14
|
+
const regions = this.getShapeRegions(grid);
|
|
15
|
+
return regions.length <= 1
|
|
16
|
+
? { tilesNeedCheck: null, ratings: null }
|
|
17
|
+
: false;
|
|
18
|
+
}
|
|
19
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import SymbolsPerRegionRule from '../../../rules/symbolsPerRegionRule';
|
|
2
|
+
import Symbol from '../../../symbols/symbol';
|
|
3
|
+
import BTModule, { BTGridData, CheckResult } from '../data';
|
|
4
|
+
export default class SymbolsPerRegionBTModule extends BTModule {
|
|
5
|
+
instr: SymbolsPerRegionRule;
|
|
6
|
+
private symbolCount;
|
|
7
|
+
constructor(instr: SymbolsPerRegionRule, width: number, height: number, allSymbols: Symbol[]);
|
|
8
|
+
checkGlobal(grid: BTGridData): CheckResult | false;
|
|
9
|
+
private visitArea;
|
|
10
|
+
}
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
import { Comparison } from '../../../primitives';
|
|
2
|
+
import BTModule, { BTTile, IntArray2D, colorToBTTile, } from '../data';
|
|
3
|
+
export default class SymbolsPerRegionBTModule extends BTModule {
|
|
4
|
+
constructor(instr, width, height, allSymbols) {
|
|
5
|
+
super();
|
|
6
|
+
Object.defineProperty(this, "instr", {
|
|
7
|
+
enumerable: true,
|
|
8
|
+
configurable: true,
|
|
9
|
+
writable: true,
|
|
10
|
+
value: void 0
|
|
11
|
+
});
|
|
12
|
+
Object.defineProperty(this, "symbolCount", {
|
|
13
|
+
enumerable: true,
|
|
14
|
+
configurable: true,
|
|
15
|
+
writable: true,
|
|
16
|
+
value: void 0
|
|
17
|
+
});
|
|
18
|
+
this.instr = instr;
|
|
19
|
+
this.symbolCount = IntArray2D.create(width, height);
|
|
20
|
+
for (const symbol of allSymbols) {
|
|
21
|
+
const symbolX = Math.floor(symbol.x);
|
|
22
|
+
const symbolY = Math.floor(symbol.y);
|
|
23
|
+
this.symbolCount.set(symbolX, symbolY, this.symbolCount.get(symbolX, symbolY) + 1);
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
checkGlobal(grid) {
|
|
27
|
+
const color = colorToBTTile(this.instr.color);
|
|
28
|
+
const visited = IntArray2D.create(grid.width, grid.height);
|
|
29
|
+
let id = 0;
|
|
30
|
+
for (let y = 0; y < grid.height; y++) {
|
|
31
|
+
for (let x = 0; x < grid.width; x++) {
|
|
32
|
+
if (visited.get(x, y) & 0b01111111)
|
|
33
|
+
continue;
|
|
34
|
+
if (grid.getTile(x, y) !== color)
|
|
35
|
+
continue;
|
|
36
|
+
id += 1;
|
|
37
|
+
if (id > 127)
|
|
38
|
+
throw new Error('Too many regions!');
|
|
39
|
+
if (!this.visitArea(grid, color, visited, { x, y }, id))
|
|
40
|
+
return false;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
return { tilesNeedCheck: null, ratings: null };
|
|
44
|
+
}
|
|
45
|
+
visitArea(grid, tile, visited, pos, id) {
|
|
46
|
+
const sameTileQueue = [pos];
|
|
47
|
+
const usableTileQueue = [];
|
|
48
|
+
let completed = 0;
|
|
49
|
+
let possible = 0;
|
|
50
|
+
visited.set(pos.x, pos.y, id);
|
|
51
|
+
// Count same tile
|
|
52
|
+
while (sameTileQueue.length > 0) {
|
|
53
|
+
const curPos = sameTileQueue.pop();
|
|
54
|
+
completed += this.symbolCount.get(curPos.x, curPos.y);
|
|
55
|
+
for (const edge of grid.getEdges(curPos)) {
|
|
56
|
+
if ((visited.get(edge.x, edge.y) & 0b01111111) === id)
|
|
57
|
+
continue;
|
|
58
|
+
const edgeTile = grid.getTile(edge.x, edge.y);
|
|
59
|
+
if (edgeTile === BTTile.Empty) {
|
|
60
|
+
usableTileQueue.push(edge);
|
|
61
|
+
visited.set(edge.x, edge.y, id | 0b10000000);
|
|
62
|
+
}
|
|
63
|
+
else if (edgeTile === tile) {
|
|
64
|
+
sameTileQueue.push(edge);
|
|
65
|
+
visited.set(edge.x, edge.y, id);
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
if (completed > this.instr.count) {
|
|
70
|
+
return this.instr.comparison === Comparison.AtLeast;
|
|
71
|
+
}
|
|
72
|
+
if (this.instr.comparison === Comparison.AtMost)
|
|
73
|
+
return true;
|
|
74
|
+
// Count usable tile
|
|
75
|
+
while (usableTileQueue.length > 0) {
|
|
76
|
+
const curPos = usableTileQueue.pop();
|
|
77
|
+
possible += this.symbolCount.get(curPos.x, curPos.y);
|
|
78
|
+
if (completed + possible >= this.instr.count)
|
|
79
|
+
return true;
|
|
80
|
+
for (const edge of grid.getEdges(curPos)) {
|
|
81
|
+
if ((visited.get(edge.x, edge.y) & 0b01111111) === id)
|
|
82
|
+
continue;
|
|
83
|
+
const edgeTile = grid.getTile(edge.x, edge.y);
|
|
84
|
+
if (edgeTile === BTTile.Empty || edgeTile === tile) {
|
|
85
|
+
usableTileQueue.push(edge);
|
|
86
|
+
visited.set(edge.x, edge.y, id | 0b10000000);
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
return completed + possible >= this.instr.count;
|
|
91
|
+
}
|
|
92
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import UniqueShapeRule from '../../../rules/uniqueShapeRule';
|
|
2
|
+
import { BTGridData, CheckResult } from '../data';
|
|
3
|
+
import RegionShapeBTModule from './regionShape';
|
|
4
|
+
export default class UniqueShapeBTModule extends RegionShapeBTModule {
|
|
5
|
+
instr: UniqueShapeRule;
|
|
6
|
+
constructor(instr: UniqueShapeRule);
|
|
7
|
+
checkGlobal(grid: BTGridData): CheckResult | false;
|
|
8
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import RegionShapeBTModule from './regionShape';
|
|
2
|
+
export default class UniqueShapeBTModule extends RegionShapeBTModule {
|
|
3
|
+
constructor(instr) {
|
|
4
|
+
super(instr);
|
|
5
|
+
Object.defineProperty(this, "instr", {
|
|
6
|
+
enumerable: true,
|
|
7
|
+
configurable: true,
|
|
8
|
+
writable: true,
|
|
9
|
+
value: void 0
|
|
10
|
+
});
|
|
11
|
+
this.instr = instr;
|
|
12
|
+
}
|
|
13
|
+
checkGlobal(grid) {
|
|
14
|
+
const regions = this.getShapeRegions(grid);
|
|
15
|
+
return regions.every(r => r.count === 1)
|
|
16
|
+
? { tilesNeedCheck: null, ratings: null }
|
|
17
|
+
: false;
|
|
18
|
+
}
|
|
19
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { Position } from '../../../primitives';
|
|
2
|
+
import AreaNumberSymbol from '../../../symbols/areaNumberSymbol';
|
|
3
|
+
import BTModule, { BTGridData, CheckResult } from '../data';
|
|
4
|
+
export default class AreaNumberBTModule extends BTModule {
|
|
5
|
+
instr: AreaNumberSymbol;
|
|
6
|
+
constructor(instr: AreaNumberSymbol);
|
|
7
|
+
checkGlobal(grid: BTGridData): CheckResult | false;
|
|
8
|
+
checkLocal(grid: BTGridData, positions: Position[]): CheckResult | boolean;
|
|
9
|
+
}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import BTModule, { BTTile, IntArray2D, createOneTileResult, } from '../data';
|
|
2
|
+
export default class AreaNumberBTModule extends BTModule {
|
|
3
|
+
constructor(instr) {
|
|
4
|
+
super();
|
|
5
|
+
Object.defineProperty(this, "instr", {
|
|
6
|
+
enumerable: true,
|
|
7
|
+
configurable: true,
|
|
8
|
+
writable: true,
|
|
9
|
+
value: void 0
|
|
10
|
+
});
|
|
11
|
+
this.instr = instr;
|
|
12
|
+
}
|
|
13
|
+
checkGlobal(grid) {
|
|
14
|
+
const thisX = Math.floor(this.instr.x);
|
|
15
|
+
const thisY = Math.floor(this.instr.y);
|
|
16
|
+
const tile = grid.getTile(thisX, thisY);
|
|
17
|
+
if (tile === BTTile.Empty)
|
|
18
|
+
return createOneTileResult(grid, { x: thisX, y: thisY });
|
|
19
|
+
const visited = IntArray2D.create(grid.width, grid.height);
|
|
20
|
+
const sameTileQueue = [{ x: thisX, y: thisY }];
|
|
21
|
+
const usableTileQueue = [];
|
|
22
|
+
let sameCellCount = 0;
|
|
23
|
+
let usableCellCount = 0;
|
|
24
|
+
visited.set(thisX, thisY, 1);
|
|
25
|
+
// Count same tile
|
|
26
|
+
while (sameTileQueue.length > 0) {
|
|
27
|
+
const curPos = sameTileQueue.pop();
|
|
28
|
+
sameCellCount += 1;
|
|
29
|
+
for (const edge of grid.getEdges(curPos)) {
|
|
30
|
+
if (visited.get(edge.x, edge.y))
|
|
31
|
+
continue;
|
|
32
|
+
const edgeTile = grid.getTile(edge.x, edge.y);
|
|
33
|
+
if (edgeTile === BTTile.Empty) {
|
|
34
|
+
usableTileQueue.push(edge);
|
|
35
|
+
}
|
|
36
|
+
else if (edgeTile === tile) {
|
|
37
|
+
sameTileQueue.push(edge);
|
|
38
|
+
}
|
|
39
|
+
visited.set(edge.x, edge.y, 1);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
if (sameCellCount > this.instr.number)
|
|
43
|
+
return false;
|
|
44
|
+
const ratings = [];
|
|
45
|
+
for (const pos of usableTileQueue) {
|
|
46
|
+
ratings.push({ pos, score: 1 });
|
|
47
|
+
}
|
|
48
|
+
// Count usable tile
|
|
49
|
+
while (usableTileQueue.length > 0) {
|
|
50
|
+
const curPos = usableTileQueue.pop();
|
|
51
|
+
usableCellCount += 1;
|
|
52
|
+
if (sameCellCount + usableCellCount >= this.instr.number)
|
|
53
|
+
return { tilesNeedCheck: null, ratings };
|
|
54
|
+
for (const edge of grid.getEdges(curPos)) {
|
|
55
|
+
if (visited.get(edge.x, edge.y))
|
|
56
|
+
continue;
|
|
57
|
+
const edgeTile = grid.getTile(edge.x, edge.y);
|
|
58
|
+
if (edgeTile === BTTile.Empty || edgeTile === tile) {
|
|
59
|
+
usableTileQueue.push(edge);
|
|
60
|
+
visited.set(edge.x, edge.y, 1);
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
return sameCellCount + usableCellCount >= this.instr.number
|
|
65
|
+
? { tilesNeedCheck: null, ratings }
|
|
66
|
+
: false;
|
|
67
|
+
}
|
|
68
|
+
checkLocal(grid, positions) {
|
|
69
|
+
// TODO: Also skip checks if color is the same and within the zone but not directly affectin
|
|
70
|
+
const thisX = Math.floor(this.instr.x);
|
|
71
|
+
const thisY = Math.floor(this.instr.y);
|
|
72
|
+
// Skip checks if it is too far to affect the symbol
|
|
73
|
+
if (positions.every(pos => Math.abs(pos.x - thisX) + Math.abs(pos.y - thisY) > this.instr.number))
|
|
74
|
+
return true;
|
|
75
|
+
return this.checkGlobal(grid);
|
|
76
|
+
}
|
|
77
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import DartSymbol from '../../../symbols/dartSymbol';
|
|
2
|
+
import BTModule, { BTGridData, CheckResult } from '../data';
|
|
3
|
+
export default class DartBTModule extends BTModule {
|
|
4
|
+
instr: DartSymbol;
|
|
5
|
+
private cachedCheckResult?;
|
|
6
|
+
constructor(instr: DartSymbol);
|
|
7
|
+
checkGlobal(grid: BTGridData): CheckResult | false;
|
|
8
|
+
private buildCheckAndRating;
|
|
9
|
+
}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { move } from '../../../dataHelper';
|
|
2
|
+
import BTModule, { BTTile, IntArray2D, createOneTileResult, getOppositeColor, } from '../data';
|
|
3
|
+
export default class DartBTModule extends BTModule {
|
|
4
|
+
constructor(instr) {
|
|
5
|
+
super();
|
|
6
|
+
Object.defineProperty(this, "instr", {
|
|
7
|
+
enumerable: true,
|
|
8
|
+
configurable: true,
|
|
9
|
+
writable: true,
|
|
10
|
+
value: void 0
|
|
11
|
+
});
|
|
12
|
+
Object.defineProperty(this, "cachedCheckResult", {
|
|
13
|
+
enumerable: true,
|
|
14
|
+
configurable: true,
|
|
15
|
+
writable: true,
|
|
16
|
+
value: void 0
|
|
17
|
+
});
|
|
18
|
+
this.instr = instr;
|
|
19
|
+
}
|
|
20
|
+
checkGlobal(grid) {
|
|
21
|
+
const tile = grid.getTile(this.instr.x, this.instr.y);
|
|
22
|
+
if (tile === BTTile.Empty)
|
|
23
|
+
return createOneTileResult(grid, { x: this.instr.x, y: this.instr.y });
|
|
24
|
+
let pos = move({ x: this.instr.x, y: this.instr.y }, this.instr.orientation);
|
|
25
|
+
let completed = 0;
|
|
26
|
+
let empty = 0;
|
|
27
|
+
while (grid.isInBound(pos.x, pos.y)) {
|
|
28
|
+
// Opposite tiles
|
|
29
|
+
if (grid.getTile(pos.x, pos.y) === getOppositeColor(tile)) {
|
|
30
|
+
completed += 1;
|
|
31
|
+
if (completed > this.instr.number)
|
|
32
|
+
return false;
|
|
33
|
+
}
|
|
34
|
+
// Empty tiles
|
|
35
|
+
if (grid.getTile(pos.x, pos.y) === BTTile.Empty)
|
|
36
|
+
empty += 1;
|
|
37
|
+
pos = move(pos, this.instr.orientation);
|
|
38
|
+
}
|
|
39
|
+
if (completed + empty < this.instr.number)
|
|
40
|
+
return false;
|
|
41
|
+
if (!this.cachedCheckResult)
|
|
42
|
+
this.cachedCheckResult = this.buildCheckAndRating(grid);
|
|
43
|
+
return this.cachedCheckResult;
|
|
44
|
+
}
|
|
45
|
+
buildCheckAndRating(grid) {
|
|
46
|
+
const tilesNeedCheck = IntArray2D.create(grid.width, grid.height);
|
|
47
|
+
const ratings = [];
|
|
48
|
+
let pos = { x: this.instr.x, y: this.instr.y };
|
|
49
|
+
while (grid.isInBound(pos.x, pos.y)) {
|
|
50
|
+
if (grid.getTile(pos.x, pos.y) === BTTile.Empty) {
|
|
51
|
+
tilesNeedCheck.set(pos.x, pos.y, 1);
|
|
52
|
+
ratings.push({ pos, score: 1 });
|
|
53
|
+
}
|
|
54
|
+
pos = move(pos, this.instr.orientation);
|
|
55
|
+
}
|
|
56
|
+
return { tilesNeedCheck, ratings };
|
|
57
|
+
}
|
|
58
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { Position } from '../../../primitives';
|
|
2
|
+
import DirectionLinkerSymbol from '../../../symbols/directionLinkerSymbol';
|
|
3
|
+
import BTModule, { BTGridData, CheckResult } from '../data';
|
|
4
|
+
export default abstract class DirectionLinkerBTModule extends BTModule {
|
|
5
|
+
instr: DirectionLinkerSymbol;
|
|
6
|
+
constructor(instr: DirectionLinkerSymbol);
|
|
7
|
+
checkGlobal(grid: BTGridData): CheckResult | false;
|
|
8
|
+
protected abstract movePos(grid: BTGridData, x: number, y: number): Position | null;
|
|
9
|
+
}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import BTModule, { BTTile, IntArray2D, createOneTileResult, } from '../data';
|
|
2
|
+
export default class DirectionLinkerBTModule extends BTModule {
|
|
3
|
+
constructor(instr) {
|
|
4
|
+
super();
|
|
5
|
+
Object.defineProperty(this, "instr", {
|
|
6
|
+
enumerable: true,
|
|
7
|
+
configurable: true,
|
|
8
|
+
writable: true,
|
|
9
|
+
value: void 0
|
|
10
|
+
});
|
|
11
|
+
this.instr = instr;
|
|
12
|
+
}
|
|
13
|
+
checkGlobal(grid) {
|
|
14
|
+
const thisX = Math.floor(this.instr.x);
|
|
15
|
+
const thisY = Math.floor(this.instr.y);
|
|
16
|
+
const tile = grid.getTile(thisX, thisY);
|
|
17
|
+
if (tile === BTTile.Empty)
|
|
18
|
+
return createOneTileResult(grid, { x: thisX, y: thisY });
|
|
19
|
+
const tilesNeedCheck = IntArray2D.create(grid.width, grid.height);
|
|
20
|
+
const ratings = [];
|
|
21
|
+
const queue = [{ x: thisX, y: thisY }];
|
|
22
|
+
const visited = IntArray2D.create(grid.width, grid.height);
|
|
23
|
+
// Visit all connected tiles
|
|
24
|
+
while (queue.length > 0) {
|
|
25
|
+
const curPos = queue.pop();
|
|
26
|
+
if (visited.get(curPos.x, curPos.y))
|
|
27
|
+
continue;
|
|
28
|
+
visited.set(curPos.x, curPos.y, 1);
|
|
29
|
+
const oppoPos = this.movePos(grid, curPos.x, curPos.y);
|
|
30
|
+
if (oppoPos === null)
|
|
31
|
+
return false;
|
|
32
|
+
const oppoTile = grid.getTile(oppoPos.x, oppoPos.y);
|
|
33
|
+
if (!(oppoTile === BTTile.Empty || oppoTile === tile))
|
|
34
|
+
return false;
|
|
35
|
+
for (const edge of grid.getEdges(curPos)) {
|
|
36
|
+
if (visited.get(edge.x, edge.y))
|
|
37
|
+
continue;
|
|
38
|
+
const edgeTile = grid.getTile(edge.x, edge.y);
|
|
39
|
+
if (edgeTile === BTTile.Empty) {
|
|
40
|
+
tilesNeedCheck.set(edge.x, edge.y, 1);
|
|
41
|
+
ratings.push({ pos: edge, score: 1 });
|
|
42
|
+
}
|
|
43
|
+
else if (edgeTile === tile) {
|
|
44
|
+
queue.push(edge);
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
return { tilesNeedCheck, ratings };
|
|
49
|
+
}
|
|
50
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { Position } from '../../../primitives';
|
|
2
|
+
import GalaxySymbol from '../../../symbols/galaxySymbol';
|
|
3
|
+
import { BTGridData } from '../data';
|
|
4
|
+
import DirectionLinkerBTModule from './directionLinker';
|
|
5
|
+
export default class GalaxyBTModule extends DirectionLinkerBTModule {
|
|
6
|
+
instr: GalaxySymbol;
|
|
7
|
+
constructor(instr: GalaxySymbol);
|
|
8
|
+
protected movePos(grid: BTGridData, x: number, y: number): Position | null;
|
|
9
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import DirectionLinkerBTModule from './directionLinker';
|
|
2
|
+
export default class GalaxyBTModule extends DirectionLinkerBTModule {
|
|
3
|
+
constructor(instr) {
|
|
4
|
+
super(instr);
|
|
5
|
+
Object.defineProperty(this, "instr", {
|
|
6
|
+
enumerable: true,
|
|
7
|
+
configurable: true,
|
|
8
|
+
writable: true,
|
|
9
|
+
value: void 0
|
|
10
|
+
});
|
|
11
|
+
this.instr = instr;
|
|
12
|
+
}
|
|
13
|
+
// Translate a position in relative to a galaxy symbol
|
|
14
|
+
movePos(grid, x, y) {
|
|
15
|
+
const symbol = this.instr;
|
|
16
|
+
const pos = { x: 2 * symbol.x - x, y: 2 * symbol.y - y };
|
|
17
|
+
return grid.isInBound(pos.x, pos.y) ? pos : null;
|
|
18
|
+
}
|
|
19
|
+
}
|