@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,36 @@
|
|
|
1
|
+
import { AnyConfig } from '../config';
|
|
2
|
+
import GridData from '../grid';
|
|
3
|
+
import { Direction, State } from '../primitives';
|
|
4
|
+
import Symbol from './symbol';
|
|
5
|
+
export type DirectionLinkerMap = {
|
|
6
|
+
[key in Direction]: Direction;
|
|
7
|
+
};
|
|
8
|
+
export default class DirectionLinkerSymbol extends Symbol {
|
|
9
|
+
readonly x: number;
|
|
10
|
+
readonly y: number;
|
|
11
|
+
private static readonly CONFIGS;
|
|
12
|
+
private static readonly EXAMPLE_GRID;
|
|
13
|
+
private static readonly directionDeltas;
|
|
14
|
+
private linkedDirections;
|
|
15
|
+
/**
|
|
16
|
+
* **Darts count opposite color cells in that direction**
|
|
17
|
+
*
|
|
18
|
+
* @param x - The x-coordinate of the symbol.
|
|
19
|
+
* @param y - The y-coordinate of the symbol.
|
|
20
|
+
*/
|
|
21
|
+
constructor(x: number, y: number);
|
|
22
|
+
changeDirections(linkedDirections: DirectionLinkerMap): this;
|
|
23
|
+
get id(): string;
|
|
24
|
+
get explanation(): string;
|
|
25
|
+
get configs(): readonly AnyConfig[] | null;
|
|
26
|
+
createExampleGrid(): GridData;
|
|
27
|
+
private getColor;
|
|
28
|
+
private deltaCoordinate;
|
|
29
|
+
validateSymbol(grid: GridData): State;
|
|
30
|
+
copyWith({ x, y }: {
|
|
31
|
+
x?: number;
|
|
32
|
+
y?: number;
|
|
33
|
+
}): this;
|
|
34
|
+
private getInitialCheckedCouples;
|
|
35
|
+
}
|
|
36
|
+
export declare const instance: undefined;
|
|
@@ -0,0 +1,259 @@
|
|
|
1
|
+
import { ConfigType } from '../config';
|
|
2
|
+
import GridData from '../grid';
|
|
3
|
+
import { Color, Direction, State } from '../primitives';
|
|
4
|
+
import Symbol from './symbol';
|
|
5
|
+
class DirectionLinkerSymbol extends Symbol {
|
|
6
|
+
/**
|
|
7
|
+
* **Darts count opposite color cells in that direction**
|
|
8
|
+
*
|
|
9
|
+
* @param x - The x-coordinate of the symbol.
|
|
10
|
+
* @param y - The y-coordinate of the symbol.
|
|
11
|
+
*/
|
|
12
|
+
constructor(x, y) {
|
|
13
|
+
super(x, y);
|
|
14
|
+
Object.defineProperty(this, "x", {
|
|
15
|
+
enumerable: true,
|
|
16
|
+
configurable: true,
|
|
17
|
+
writable: true,
|
|
18
|
+
value: x
|
|
19
|
+
});
|
|
20
|
+
Object.defineProperty(this, "y", {
|
|
21
|
+
enumerable: true,
|
|
22
|
+
configurable: true,
|
|
23
|
+
writable: true,
|
|
24
|
+
value: y
|
|
25
|
+
});
|
|
26
|
+
Object.defineProperty(this, "linkedDirections", {
|
|
27
|
+
enumerable: true,
|
|
28
|
+
configurable: true,
|
|
29
|
+
writable: true,
|
|
30
|
+
value: {
|
|
31
|
+
[Direction.Left]: Direction.Left,
|
|
32
|
+
[Direction.Up]: Direction.Up,
|
|
33
|
+
[Direction.Right]: Direction.Right,
|
|
34
|
+
[Direction.Down]: Direction.Down,
|
|
35
|
+
}
|
|
36
|
+
});
|
|
37
|
+
}
|
|
38
|
+
changeDirections(linkedDirections) {
|
|
39
|
+
this.linkedDirections = linkedDirections;
|
|
40
|
+
return this;
|
|
41
|
+
}
|
|
42
|
+
get id() {
|
|
43
|
+
return `linkedDirection`;
|
|
44
|
+
}
|
|
45
|
+
get explanation() {
|
|
46
|
+
return `Direction pointed by this symbol should *behave* the same.`;
|
|
47
|
+
}
|
|
48
|
+
get configs() {
|
|
49
|
+
return DirectionLinkerSymbol.CONFIGS;
|
|
50
|
+
}
|
|
51
|
+
createExampleGrid() {
|
|
52
|
+
return DirectionLinkerSymbol.EXAMPLE_GRID;
|
|
53
|
+
}
|
|
54
|
+
getColor(c, grid) {
|
|
55
|
+
if (!grid.isPositionValid(c.x, c.y) || !grid.getTile(c.x, c.y).exists) {
|
|
56
|
+
return null;
|
|
57
|
+
}
|
|
58
|
+
return grid.getTile(c.x, c.y).color;
|
|
59
|
+
}
|
|
60
|
+
deltaCoordinate(c, direction) {
|
|
61
|
+
return {
|
|
62
|
+
x: c.x + DirectionLinkerSymbol.directionDeltas[direction].dx,
|
|
63
|
+
y: c.y + DirectionLinkerSymbol.directionDeltas[direction].dy,
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
validateSymbol(grid) {
|
|
67
|
+
// A turtle is an object which have 2 coordinates
|
|
68
|
+
// This turtle when activated will check the color of both the cells it is pointing to
|
|
69
|
+
// If the color of one of the cell is gray, the turtle doesn't fire any other turtle
|
|
70
|
+
// If one of the turtle's coordinate is out of the grid, consider it's color as opposite of the base color
|
|
71
|
+
// If the color of both cells are different, return a State.Error
|
|
72
|
+
// If the color of both are the same as the color of the turtle, the turtle fires another turtle in all the directions according to the linked directions except the one it came from and the directions where a turtle has already been fired
|
|
73
|
+
// If the color of both are the opposite of the turtle, the turtle doesn't fire any other turtle
|
|
74
|
+
// If no turtle remains, go to final state
|
|
75
|
+
// Final state is State.Satisfied if no gray cell is found, State.Incomplete otherwise
|
|
76
|
+
const baseColor = grid.getTile(Math.round(this.x), Math.round(this.y)).color;
|
|
77
|
+
if (baseColor === Color.Gray) {
|
|
78
|
+
return State.Incomplete;
|
|
79
|
+
}
|
|
80
|
+
const checkedCouples = this.getInitialCheckedCouples(this.x, this.y);
|
|
81
|
+
const queue = checkedCouples.map(([p1, p2]) => [
|
|
82
|
+
{ ...p1 },
|
|
83
|
+
{ ...p2 },
|
|
84
|
+
]);
|
|
85
|
+
let grayFound = false;
|
|
86
|
+
while (queue.length > 0) {
|
|
87
|
+
const turtle = queue.shift();
|
|
88
|
+
const [c1, c2] = turtle;
|
|
89
|
+
const color1 = this.getColor(c1, grid);
|
|
90
|
+
const color2 = this.getColor(c2, grid);
|
|
91
|
+
const colorSet = new Set([color1, color2]);
|
|
92
|
+
if (colorSet.has(null) && !colorSet.has(baseColor)) {
|
|
93
|
+
colorSet.delete(null);
|
|
94
|
+
}
|
|
95
|
+
if (colorSet.size === 2 && !colorSet.has(Color.Gray)) {
|
|
96
|
+
return State.Error;
|
|
97
|
+
}
|
|
98
|
+
if (colorSet.has(Color.Gray)) {
|
|
99
|
+
grayFound = true;
|
|
100
|
+
}
|
|
101
|
+
if (color1 === baseColor) {
|
|
102
|
+
const directions = Object.keys(this.linkedDirections);
|
|
103
|
+
for (const direction of directions) {
|
|
104
|
+
const newTurtle = [
|
|
105
|
+
this.deltaCoordinate(c1, direction),
|
|
106
|
+
this.deltaCoordinate(c2, this.linkedDirections[direction]),
|
|
107
|
+
];
|
|
108
|
+
if (checkedCouples.some(([c1, c2]) => c1.x === newTurtle[0].x &&
|
|
109
|
+
c1.y === newTurtle[0].y &&
|
|
110
|
+
c2.x === newTurtle[1].x &&
|
|
111
|
+
c2.y === newTurtle[1].y) ||
|
|
112
|
+
(c1.x === newTurtle[1].x &&
|
|
113
|
+
c1.y === newTurtle[1].y &&
|
|
114
|
+
c2.x === newTurtle[0].x &&
|
|
115
|
+
c2.y === newTurtle[0].y)) {
|
|
116
|
+
continue;
|
|
117
|
+
}
|
|
118
|
+
checkedCouples.push([newTurtle[0], newTurtle[1]]);
|
|
119
|
+
queue.push(newTurtle);
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
return grayFound ? State.Incomplete : State.Satisfied;
|
|
124
|
+
}
|
|
125
|
+
copyWith({ x, y }) {
|
|
126
|
+
return new DirectionLinkerSymbol(x ?? this.x, y ?? this.y);
|
|
127
|
+
}
|
|
128
|
+
getInitialCheckedCouples(x, y) {
|
|
129
|
+
// 1x1
|
|
130
|
+
if (x % 1 === 0 && y % 1 === 0) {
|
|
131
|
+
return [
|
|
132
|
+
[
|
|
133
|
+
{ x, y },
|
|
134
|
+
{ x, y },
|
|
135
|
+
],
|
|
136
|
+
];
|
|
137
|
+
}
|
|
138
|
+
// 1x2
|
|
139
|
+
if (x % 1 === 0) {
|
|
140
|
+
return [
|
|
141
|
+
[
|
|
142
|
+
{ x, y: y - 0.5 },
|
|
143
|
+
{
|
|
144
|
+
x,
|
|
145
|
+
y: y +
|
|
146
|
+
(this.linkedDirections[Direction.Up] === Direction.Up &&
|
|
147
|
+
this.linkedDirections[Direction.Down] === Direction.Down
|
|
148
|
+
? -0.5
|
|
149
|
+
: 0.5),
|
|
150
|
+
},
|
|
151
|
+
],
|
|
152
|
+
];
|
|
153
|
+
}
|
|
154
|
+
// 2x1
|
|
155
|
+
if (y % 1 === 0) {
|
|
156
|
+
return [
|
|
157
|
+
[
|
|
158
|
+
{ x: x - 0.5, y },
|
|
159
|
+
{
|
|
160
|
+
x: x +
|
|
161
|
+
(this.linkedDirections[Direction.Left] === Direction.Left &&
|
|
162
|
+
this.linkedDirections[Direction.Right] === Direction.Right
|
|
163
|
+
? -0.5
|
|
164
|
+
: 0.5),
|
|
165
|
+
y,
|
|
166
|
+
},
|
|
167
|
+
],
|
|
168
|
+
];
|
|
169
|
+
}
|
|
170
|
+
// 2x2
|
|
171
|
+
if (this.linkedDirections[Direction.Left] === Direction.Left &&
|
|
172
|
+
this.linkedDirections[Direction.Right] === Direction.Right) {
|
|
173
|
+
return [
|
|
174
|
+
[
|
|
175
|
+
{ x: x - 0.5, y: y - 0.5 },
|
|
176
|
+
{ x: x - 0.5, y: y + 0.5 },
|
|
177
|
+
],
|
|
178
|
+
[
|
|
179
|
+
{ x: x + 0.5, y: y - 0.5 },
|
|
180
|
+
{ x: x + 0.5, y: y + 0.5 },
|
|
181
|
+
],
|
|
182
|
+
];
|
|
183
|
+
}
|
|
184
|
+
if (this.linkedDirections[Direction.Up] === Direction.Up &&
|
|
185
|
+
this.linkedDirections[Direction.Down] === Direction.Down) {
|
|
186
|
+
return [
|
|
187
|
+
[
|
|
188
|
+
{ x: x - 0.5, y: y - 0.5 },
|
|
189
|
+
{ x: x + 0.5, y: y - 0.5 },
|
|
190
|
+
],
|
|
191
|
+
[
|
|
192
|
+
{ x: x - 0.5, y: y + 0.5 },
|
|
193
|
+
{ x: x + 0.5, y: y + 0.5 },
|
|
194
|
+
],
|
|
195
|
+
];
|
|
196
|
+
}
|
|
197
|
+
else if ((this.linkedDirections[Direction.Up] === Direction.Left &&
|
|
198
|
+
this.linkedDirections[Direction.Left] === Direction.Up) ||
|
|
199
|
+
(this.linkedDirections[Direction.Up] === Direction.Right &&
|
|
200
|
+
this.linkedDirections[Direction.Right] === Direction.Up)) {
|
|
201
|
+
return [
|
|
202
|
+
[
|
|
203
|
+
{ x: x - 0.5, y: y - 0.5 },
|
|
204
|
+
{ x: x - 0.5, y: y - 0.5 },
|
|
205
|
+
],
|
|
206
|
+
];
|
|
207
|
+
}
|
|
208
|
+
return [
|
|
209
|
+
[
|
|
210
|
+
{ x: x - 0.5, y: y - 0.5 },
|
|
211
|
+
{ x: x + 0.5, y: y + 0.5 },
|
|
212
|
+
],
|
|
213
|
+
[
|
|
214
|
+
{ x: x - 0.5, y: y + 0.5 },
|
|
215
|
+
{ x: x + 0.5, y: y - 0.5 },
|
|
216
|
+
],
|
|
217
|
+
];
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
Object.defineProperty(DirectionLinkerSymbol, "CONFIGS", {
|
|
221
|
+
enumerable: true,
|
|
222
|
+
configurable: true,
|
|
223
|
+
writable: true,
|
|
224
|
+
value: Object.freeze([
|
|
225
|
+
{
|
|
226
|
+
type: ConfigType.Number,
|
|
227
|
+
default: 0,
|
|
228
|
+
field: 'x',
|
|
229
|
+
description: 'X',
|
|
230
|
+
configurable: false,
|
|
231
|
+
},
|
|
232
|
+
{
|
|
233
|
+
type: ConfigType.Number,
|
|
234
|
+
default: 0,
|
|
235
|
+
field: 'y',
|
|
236
|
+
description: 'Y',
|
|
237
|
+
configurable: false,
|
|
238
|
+
},
|
|
239
|
+
])
|
|
240
|
+
});
|
|
241
|
+
Object.defineProperty(DirectionLinkerSymbol, "EXAMPLE_GRID", {
|
|
242
|
+
enumerable: true,
|
|
243
|
+
configurable: true,
|
|
244
|
+
writable: true,
|
|
245
|
+
value: Object.freeze(GridData.create(['wwbbw', 'wwwww', 'wwwww', 'wwwww']))
|
|
246
|
+
});
|
|
247
|
+
Object.defineProperty(DirectionLinkerSymbol, "directionDeltas", {
|
|
248
|
+
enumerable: true,
|
|
249
|
+
configurable: true,
|
|
250
|
+
writable: true,
|
|
251
|
+
value: {
|
|
252
|
+
[Direction.Up]: { dx: 0, dy: -1 },
|
|
253
|
+
[Direction.Down]: { dx: 0, dy: 1 },
|
|
254
|
+
[Direction.Left]: { dx: -1, dy: 0 },
|
|
255
|
+
[Direction.Right]: { dx: 1, dy: 0 },
|
|
256
|
+
}
|
|
257
|
+
});
|
|
258
|
+
export default DirectionLinkerSymbol;
|
|
259
|
+
export const instance = undefined;
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { AnyConfig } from '../config';
|
|
2
|
+
import GridData from '../grid';
|
|
3
|
+
import { State } from '../primitives';
|
|
4
|
+
import DirectionLinkerSymbol from './directionLinkerSymbol';
|
|
5
|
+
export default class GalaxySymbol extends DirectionLinkerSymbol {
|
|
6
|
+
readonly x: number;
|
|
7
|
+
readonly y: number;
|
|
8
|
+
private static readonly linkedDirections;
|
|
9
|
+
/**
|
|
10
|
+
* **Galaxies are centers of rotational symmetry**
|
|
11
|
+
*
|
|
12
|
+
* @param x - The x-coordinate of the symbol.
|
|
13
|
+
* @param y - The y-coordinate of the symbol.
|
|
14
|
+
*/
|
|
15
|
+
constructor(x: number, y: number);
|
|
16
|
+
get id(): string;
|
|
17
|
+
get explanation(): string;
|
|
18
|
+
get configs(): readonly AnyConfig[] | null;
|
|
19
|
+
createExampleGrid(): GridData;
|
|
20
|
+
validateSymbol(grid: GridData): State;
|
|
21
|
+
copyWith({ x, y }: {
|
|
22
|
+
x?: number;
|
|
23
|
+
y?: number;
|
|
24
|
+
}): this;
|
|
25
|
+
}
|
|
26
|
+
export declare const instance: GalaxySymbol;
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import { ConfigType } from '../config';
|
|
2
|
+
import GridData from '../grid';
|
|
3
|
+
import { Direction } from '../primitives';
|
|
4
|
+
import DirectionLinkerSymbol from './directionLinkerSymbol';
|
|
5
|
+
class GalaxySymbol extends DirectionLinkerSymbol {
|
|
6
|
+
/**
|
|
7
|
+
* **Galaxies are centers of rotational symmetry**
|
|
8
|
+
*
|
|
9
|
+
* @param x - The x-coordinate of the symbol.
|
|
10
|
+
* @param y - The y-coordinate of the symbol.
|
|
11
|
+
*/
|
|
12
|
+
constructor(x, y) {
|
|
13
|
+
super(x, y);
|
|
14
|
+
Object.defineProperty(this, "x", {
|
|
15
|
+
enumerable: true,
|
|
16
|
+
configurable: true,
|
|
17
|
+
writable: true,
|
|
18
|
+
value: x
|
|
19
|
+
});
|
|
20
|
+
Object.defineProperty(this, "y", {
|
|
21
|
+
enumerable: true,
|
|
22
|
+
configurable: true,
|
|
23
|
+
writable: true,
|
|
24
|
+
value: y
|
|
25
|
+
});
|
|
26
|
+
super.changeDirections(GalaxySymbol.linkedDirections);
|
|
27
|
+
}
|
|
28
|
+
get id() {
|
|
29
|
+
return `galaxy`;
|
|
30
|
+
}
|
|
31
|
+
get explanation() {
|
|
32
|
+
return `*Galaxies* are centers of rotational symmetry`;
|
|
33
|
+
}
|
|
34
|
+
get configs() {
|
|
35
|
+
return Object.freeze([
|
|
36
|
+
{
|
|
37
|
+
type: ConfigType.Number,
|
|
38
|
+
default: 0,
|
|
39
|
+
field: 'x',
|
|
40
|
+
description: 'X',
|
|
41
|
+
configurable: false,
|
|
42
|
+
},
|
|
43
|
+
{
|
|
44
|
+
type: ConfigType.Number,
|
|
45
|
+
default: 0,
|
|
46
|
+
field: 'y',
|
|
47
|
+
description: 'Y',
|
|
48
|
+
configurable: false,
|
|
49
|
+
},
|
|
50
|
+
]);
|
|
51
|
+
}
|
|
52
|
+
createExampleGrid() {
|
|
53
|
+
return Object.freeze(GridData.create(['wbbbb', 'wbwww', 'bbwbb', 'wwwbb']).addSymbol(new GalaxySymbol(2, 2)));
|
|
54
|
+
}
|
|
55
|
+
validateSymbol(grid) {
|
|
56
|
+
return super.validateSymbol(grid);
|
|
57
|
+
}
|
|
58
|
+
copyWith({ x, y }) {
|
|
59
|
+
return new GalaxySymbol(x ?? this.x, y ?? this.y);
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
Object.defineProperty(GalaxySymbol, "linkedDirections", {
|
|
63
|
+
enumerable: true,
|
|
64
|
+
configurable: true,
|
|
65
|
+
writable: true,
|
|
66
|
+
value: {
|
|
67
|
+
[Direction.Left]: Direction.Right,
|
|
68
|
+
[Direction.Up]: Direction.Down,
|
|
69
|
+
[Direction.Right]: Direction.Left,
|
|
70
|
+
[Direction.Down]: Direction.Up,
|
|
71
|
+
}
|
|
72
|
+
});
|
|
73
|
+
export default GalaxySymbol;
|
|
74
|
+
export const instance = new GalaxySymbol(0, 0);
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import * as symbols from './symbols.gen';
|
|
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,31 @@
|
|
|
1
|
+
import { AnyConfig } from '../config';
|
|
2
|
+
import GridData from '../grid';
|
|
3
|
+
import { State } from '../primitives';
|
|
4
|
+
import Symbol from './symbol';
|
|
5
|
+
export default class LetterSymbol extends Symbol {
|
|
6
|
+
readonly x: number;
|
|
7
|
+
readonly y: number;
|
|
8
|
+
readonly letter: string;
|
|
9
|
+
private static readonly CONFIGS;
|
|
10
|
+
private static readonly EXAMPLE_GRID;
|
|
11
|
+
/**
|
|
12
|
+
* **Letters must be sorted into one type per area**
|
|
13
|
+
*
|
|
14
|
+
* @param x - The x-coordinate of the symbol.
|
|
15
|
+
* @param y - The y-coordinate of the symbol.
|
|
16
|
+
* @param letter - The letter of the symbol.
|
|
17
|
+
*/
|
|
18
|
+
constructor(x: number, y: number, letter: string);
|
|
19
|
+
get id(): string;
|
|
20
|
+
get explanation(): string;
|
|
21
|
+
get configs(): readonly AnyConfig[] | null;
|
|
22
|
+
createExampleGrid(): GridData;
|
|
23
|
+
validateSymbol(grid: GridData): State;
|
|
24
|
+
copyWith({ x, y, letter, }: {
|
|
25
|
+
x?: number;
|
|
26
|
+
y?: number;
|
|
27
|
+
letter?: string;
|
|
28
|
+
}): this;
|
|
29
|
+
withLetter(letter: string): this;
|
|
30
|
+
}
|
|
31
|
+
export declare const instance: LetterSymbol;
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
import { ConfigType } from '../config';
|
|
2
|
+
import GridData from '../grid';
|
|
3
|
+
import { array } from '../dataHelper';
|
|
4
|
+
import { Color, State } from '../primitives';
|
|
5
|
+
import Symbol from './symbol';
|
|
6
|
+
class LetterSymbol extends Symbol {
|
|
7
|
+
/**
|
|
8
|
+
* **Letters must be sorted into one type per area**
|
|
9
|
+
*
|
|
10
|
+
* @param x - The x-coordinate of the symbol.
|
|
11
|
+
* @param y - The y-coordinate of the symbol.
|
|
12
|
+
* @param letter - The letter of the symbol.
|
|
13
|
+
*/
|
|
14
|
+
constructor(x, y, letter) {
|
|
15
|
+
super(x, y);
|
|
16
|
+
Object.defineProperty(this, "x", {
|
|
17
|
+
enumerable: true,
|
|
18
|
+
configurable: true,
|
|
19
|
+
writable: true,
|
|
20
|
+
value: x
|
|
21
|
+
});
|
|
22
|
+
Object.defineProperty(this, "y", {
|
|
23
|
+
enumerable: true,
|
|
24
|
+
configurable: true,
|
|
25
|
+
writable: true,
|
|
26
|
+
value: y
|
|
27
|
+
});
|
|
28
|
+
Object.defineProperty(this, "letter", {
|
|
29
|
+
enumerable: true,
|
|
30
|
+
configurable: true,
|
|
31
|
+
writable: true,
|
|
32
|
+
value: letter
|
|
33
|
+
});
|
|
34
|
+
this.letter = letter;
|
|
35
|
+
}
|
|
36
|
+
get id() {
|
|
37
|
+
return `letter`;
|
|
38
|
+
}
|
|
39
|
+
get explanation() {
|
|
40
|
+
return '*Letters* must be sorted into one type per area';
|
|
41
|
+
}
|
|
42
|
+
get configs() {
|
|
43
|
+
return LetterSymbol.CONFIGS;
|
|
44
|
+
}
|
|
45
|
+
createExampleGrid() {
|
|
46
|
+
return LetterSymbol.EXAMPLE_GRID;
|
|
47
|
+
}
|
|
48
|
+
validateSymbol(grid) {
|
|
49
|
+
const thisX = Math.floor(this.x);
|
|
50
|
+
const thisY = Math.floor(this.y);
|
|
51
|
+
let complete = true;
|
|
52
|
+
const visited = array(grid.width, grid.height, () => false);
|
|
53
|
+
const connected = array(grid.width, grid.height, () => false);
|
|
54
|
+
const color = grid.getTile(thisX, thisY).color;
|
|
55
|
+
if (color !== Color.Gray) {
|
|
56
|
+
grid.iterateArea({ x: thisX, y: thisY }, tile => tile.color === Color.Gray || tile.color === color, (tile, x, y) => {
|
|
57
|
+
visited[y][x] = true;
|
|
58
|
+
if (tile.color === Color.Gray)
|
|
59
|
+
complete = false;
|
|
60
|
+
});
|
|
61
|
+
grid.iterateArea({ x: thisX, y: thisY }, tile => tile.color === color, (_, x, y) => {
|
|
62
|
+
connected[y][x] = true;
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
else {
|
|
66
|
+
complete = false;
|
|
67
|
+
}
|
|
68
|
+
for (const symbol of grid.symbols.get(this.id) ?? []) {
|
|
69
|
+
if (symbol !== this && symbol instanceof LetterSymbol) {
|
|
70
|
+
const symbolX = Math.floor(symbol.x);
|
|
71
|
+
const symbolY = Math.floor(symbol.y);
|
|
72
|
+
if (symbol.letter === this.letter) {
|
|
73
|
+
const theirColor = grid.getTile(symbolX, symbolY).color;
|
|
74
|
+
if ((color !== Color.Gray && !visited[symbolY][symbolX]) ||
|
|
75
|
+
(color !== Color.Gray &&
|
|
76
|
+
theirColor !== Color.Gray &&
|
|
77
|
+
theirColor !== color)) {
|
|
78
|
+
return State.Error;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
else if (color !== Color.Gray && connected[symbolY][symbolX]) {
|
|
82
|
+
return State.Error;
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
return complete ? State.Satisfied : State.Incomplete;
|
|
87
|
+
}
|
|
88
|
+
copyWith({ x, y, letter, }) {
|
|
89
|
+
return new LetterSymbol(x ?? this.x, y ?? this.y, letter ?? this.letter);
|
|
90
|
+
}
|
|
91
|
+
withLetter(letter) {
|
|
92
|
+
return this.copyWith({ letter });
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
Object.defineProperty(LetterSymbol, "CONFIGS", {
|
|
96
|
+
enumerable: true,
|
|
97
|
+
configurable: true,
|
|
98
|
+
writable: true,
|
|
99
|
+
value: Object.freeze([
|
|
100
|
+
{
|
|
101
|
+
type: ConfigType.Number,
|
|
102
|
+
default: 0,
|
|
103
|
+
field: 'x',
|
|
104
|
+
description: 'X',
|
|
105
|
+
configurable: false,
|
|
106
|
+
},
|
|
107
|
+
{
|
|
108
|
+
type: ConfigType.Number,
|
|
109
|
+
default: 0,
|
|
110
|
+
field: 'y',
|
|
111
|
+
description: 'Y',
|
|
112
|
+
configurable: false,
|
|
113
|
+
},
|
|
114
|
+
{
|
|
115
|
+
type: ConfigType.String,
|
|
116
|
+
default: 'A',
|
|
117
|
+
field: 'letter',
|
|
118
|
+
description: 'Letter',
|
|
119
|
+
configurable: true,
|
|
120
|
+
},
|
|
121
|
+
])
|
|
122
|
+
});
|
|
123
|
+
Object.defineProperty(LetterSymbol, "EXAMPLE_GRID", {
|
|
124
|
+
enumerable: true,
|
|
125
|
+
configurable: true,
|
|
126
|
+
writable: true,
|
|
127
|
+
value: Object.freeze(GridData.create(['bbbww', 'wwbbw', 'wwbbb', 'bwwww'])
|
|
128
|
+
.addSymbol(new LetterSymbol(0, 0, 'B'))
|
|
129
|
+
.addSymbol(new LetterSymbol(3, 0, 'A'))
|
|
130
|
+
.addSymbol(new LetterSymbol(4, 1, 'A'))
|
|
131
|
+
.addSymbol(new LetterSymbol(3, 2, 'B'))
|
|
132
|
+
.addSymbol(new LetterSymbol(1, 1, 'C'))
|
|
133
|
+
.addSymbol(new LetterSymbol(0, 2, 'C'))
|
|
134
|
+
.addSymbol(new LetterSymbol(4, 3, 'C')))
|
|
135
|
+
});
|
|
136
|
+
export default LetterSymbol;
|
|
137
|
+
export const instance = new LetterSymbol(0, 0, 'A');
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { AnyConfig } from '../config';
|
|
2
|
+
import GridData from '../grid';
|
|
3
|
+
import { Orientation, State } from '../primitives';
|
|
4
|
+
import DirectionLinkerSymbol from './directionLinkerSymbol';
|
|
5
|
+
export default class LotusSymbol extends DirectionLinkerSymbol {
|
|
6
|
+
readonly x: number;
|
|
7
|
+
readonly y: number;
|
|
8
|
+
readonly orientation: Orientation;
|
|
9
|
+
private static readonly linkedDirectionsFromOrientation;
|
|
10
|
+
/**
|
|
11
|
+
* **Areas containing this symbol must be symmetrical**
|
|
12
|
+
*
|
|
13
|
+
* @param x - The x-coordinate of the symbol.
|
|
14
|
+
* @param y - The y-coordinate of the symbol.
|
|
15
|
+
* @param orientation - The orientation of the symbol.
|
|
16
|
+
*/
|
|
17
|
+
constructor(x: number, y: number, orientation: Orientation);
|
|
18
|
+
get id(): string;
|
|
19
|
+
get explanation(): string;
|
|
20
|
+
get configs(): readonly AnyConfig[] | null;
|
|
21
|
+
createExampleGrid(): GridData;
|
|
22
|
+
validateSymbol(grid: GridData): State;
|
|
23
|
+
copyWith({ x, y, orientation, }: {
|
|
24
|
+
x?: number;
|
|
25
|
+
y?: number;
|
|
26
|
+
orientation?: Orientation;
|
|
27
|
+
}): this;
|
|
28
|
+
}
|
|
29
|
+
export declare const instance: LotusSymbol;
|