@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.
Files changed (211) hide show
  1. package/LICENSE +661 -0
  2. package/README.md +19 -0
  3. package/assets/logic-core.global.d.ts +5865 -0
  4. package/assets/z3-built.js +14723 -0
  5. package/assets/z3-built.wasm +0 -0
  6. package/assets/z3-built.worker.js +206 -0
  7. package/dist/data/config.d.ts +101 -0
  8. package/dist/data/config.js +55 -0
  9. package/dist/data/configurable.d.ts +12 -0
  10. package/dist/data/configurable.js +26 -0
  11. package/dist/data/dataHelper.d.ts +77 -0
  12. package/dist/data/dataHelper.js +190 -0
  13. package/dist/data/events/eventHelper.d.ts +1 -0
  14. package/dist/data/events/eventHelper.js +6 -0
  15. package/dist/data/events/onFinalValidation.d.ts +14 -0
  16. package/dist/data/events/onFinalValidation.js +4 -0
  17. package/dist/data/events/onGridChange.d.ts +6 -0
  18. package/dist/data/events/onGridChange.js +4 -0
  19. package/dist/data/events/onGridResize.d.ts +9 -0
  20. package/dist/data/events/onGridResize.js +4 -0
  21. package/dist/data/events/onSetGrid.d.ts +6 -0
  22. package/dist/data/events/onSetGrid.js +4 -0
  23. package/dist/data/events/onSymbolValidation.d.ts +18 -0
  24. package/dist/data/events/onSymbolValidation.js +4 -0
  25. package/dist/data/grid.d.ts +362 -0
  26. package/dist/data/grid.js +886 -0
  27. package/dist/data/gridConnections.d.ts +38 -0
  28. package/dist/data/gridConnections.js +328 -0
  29. package/dist/data/instruction.d.ts +19 -0
  30. package/dist/data/instruction.js +23 -0
  31. package/dist/data/primitives.d.ts +85 -0
  32. package/dist/data/primitives.js +90 -0
  33. package/dist/data/puzzle.d.ts +86 -0
  34. package/dist/data/puzzle.js +22 -0
  35. package/dist/data/rules/banPatternRule.d.ts +29 -0
  36. package/dist/data/rules/banPatternRule.js +133 -0
  37. package/dist/data/rules/cellCountRule.d.ts +32 -0
  38. package/dist/data/rules/cellCountRule.js +166 -0
  39. package/dist/data/rules/completePatternRule.d.ts +22 -0
  40. package/dist/data/rules/completePatternRule.js +53 -0
  41. package/dist/data/rules/connectAllRule.d.ts +28 -0
  42. package/dist/data/rules/connectAllRule.js +113 -0
  43. package/dist/data/rules/customRule.d.ts +32 -0
  44. package/dist/data/rules/customRule.js +92 -0
  45. package/dist/data/rules/foresightRule.d.ts +30 -0
  46. package/dist/data/rules/foresightRule.js +107 -0
  47. package/dist/data/rules/index.d.ts +3 -0
  48. package/dist/data/rules/index.js +10 -0
  49. package/dist/data/rules/musicControlLine.d.ts +64 -0
  50. package/dist/data/rules/musicControlLine.js +178 -0
  51. package/dist/data/rules/musicGridRule.d.ts +46 -0
  52. package/dist/data/rules/musicGridRule.js +211 -0
  53. package/dist/data/rules/mysteryRule.d.ts +37 -0
  54. package/dist/data/rules/mysteryRule.js +164 -0
  55. package/dist/data/rules/offByXRule.d.ts +30 -0
  56. package/dist/data/rules/offByXRule.js +134 -0
  57. package/dist/data/rules/regionAreaRule.d.ts +33 -0
  58. package/dist/data/rules/regionAreaRule.js +182 -0
  59. package/dist/data/rules/regionShapeRule.d.ts +22 -0
  60. package/dist/data/rules/regionShapeRule.js +58 -0
  61. package/dist/data/rules/rule.d.ts +18 -0
  62. package/dist/data/rules/rule.js +19 -0
  63. package/dist/data/rules/rules.gen.d.ts +14 -0
  64. package/dist/data/rules/rules.gen.js +18 -0
  65. package/dist/data/rules/sameShapeRule.d.ts +27 -0
  66. package/dist/data/rules/sameShapeRule.js +88 -0
  67. package/dist/data/rules/symbolsPerRegionRule.d.ts +37 -0
  68. package/dist/data/rules/symbolsPerRegionRule.js +211 -0
  69. package/dist/data/rules/undercluedRule.d.ts +22 -0
  70. package/dist/data/rules/undercluedRule.js +60 -0
  71. package/dist/data/rules/uniqueShapeRule.d.ts +27 -0
  72. package/dist/data/rules/uniqueShapeRule.js +85 -0
  73. package/dist/data/serializer/allSerializers.d.ts +30 -0
  74. package/dist/data/serializer/allSerializers.js +64 -0
  75. package/dist/data/serializer/compressor/allCompressors.d.ts +14 -0
  76. package/dist/data/serializer/compressor/allCompressors.js +43 -0
  77. package/dist/data/serializer/compressor/compressorBase.d.ts +16 -0
  78. package/dist/data/serializer/compressor/compressorBase.js +2 -0
  79. package/dist/data/serializer/compressor/deflateCompressor.d.ts +7 -0
  80. package/dist/data/serializer/compressor/deflateCompressor.js +17 -0
  81. package/dist/data/serializer/compressor/gzipCompressor.d.ts +5 -0
  82. package/dist/data/serializer/compressor/gzipCompressor.js +9 -0
  83. package/dist/data/serializer/compressor/streamCompressor.d.ts +6 -0
  84. package/dist/data/serializer/compressor/streamCompressor.js +36 -0
  85. package/dist/data/serializer/serializerBase.d.ts +27 -0
  86. package/dist/data/serializer/serializerBase.js +2 -0
  87. package/dist/data/serializer/serializer_v0.d.ts +36 -0
  88. package/dist/data/serializer/serializer_v0.js +426 -0
  89. package/dist/data/shapes.d.ts +17 -0
  90. package/dist/data/shapes.js +117 -0
  91. package/dist/data/solver/allSolvers.d.ts +3 -0
  92. package/dist/data/solver/allSolvers.js +11 -0
  93. package/dist/data/solver/backtrack/backtrackSolver.d.ts +9 -0
  94. package/dist/data/solver/backtrack/backtrackSolver.js +92 -0
  95. package/dist/data/solver/backtrack/backtrackWorker.d.ts +2 -0
  96. package/dist/data/solver/backtrack/backtrackWorker.js +295 -0
  97. package/dist/data/solver/backtrack/data.d.ts +46 -0
  98. package/dist/data/solver/backtrack/data.js +140 -0
  99. package/dist/data/solver/backtrack/rules/banPattern.d.ts +9 -0
  100. package/dist/data/solver/backtrack/rules/banPattern.js +66 -0
  101. package/dist/data/solver/backtrack/rules/cellCount.d.ts +7 -0
  102. package/dist/data/solver/backtrack/rules/cellCount.js +30 -0
  103. package/dist/data/solver/backtrack/rules/connectAll.d.ts +7 -0
  104. package/dist/data/solver/backtrack/rules/connectAll.js +49 -0
  105. package/dist/data/solver/backtrack/rules/regionArea.d.ts +8 -0
  106. package/dist/data/solver/backtrack/rules/regionArea.js +76 -0
  107. package/dist/data/solver/backtrack/rules/regionShape.d.ts +8 -0
  108. package/dist/data/solver/backtrack/rules/regionShape.js +62 -0
  109. package/dist/data/solver/backtrack/rules/sameShape.d.ts +8 -0
  110. package/dist/data/solver/backtrack/rules/sameShape.js +19 -0
  111. package/dist/data/solver/backtrack/rules/symbolsPerRegion.d.ts +10 -0
  112. package/dist/data/solver/backtrack/rules/symbolsPerRegion.js +92 -0
  113. package/dist/data/solver/backtrack/rules/uniqueShape.d.ts +8 -0
  114. package/dist/data/solver/backtrack/rules/uniqueShape.js +19 -0
  115. package/dist/data/solver/backtrack/symbols/areaNumber.d.ts +9 -0
  116. package/dist/data/solver/backtrack/symbols/areaNumber.js +77 -0
  117. package/dist/data/solver/backtrack/symbols/dart.d.ts +9 -0
  118. package/dist/data/solver/backtrack/symbols/dart.js +58 -0
  119. package/dist/data/solver/backtrack/symbols/directionLinker.d.ts +9 -0
  120. package/dist/data/solver/backtrack/symbols/directionLinker.js +50 -0
  121. package/dist/data/solver/backtrack/symbols/galaxy.d.ts +9 -0
  122. package/dist/data/solver/backtrack/symbols/galaxy.js +19 -0
  123. package/dist/data/solver/backtrack/symbols/letter.d.ts +9 -0
  124. package/dist/data/solver/backtrack/symbols/letter.js +100 -0
  125. package/dist/data/solver/backtrack/symbols/lotus.d.ts +9 -0
  126. package/dist/data/solver/backtrack/symbols/lotus.js +36 -0
  127. package/dist/data/solver/backtrack/symbols/minesweeper.d.ts +9 -0
  128. package/dist/data/solver/backtrack/symbols/minesweeper.js +55 -0
  129. package/dist/data/solver/backtrack/symbols/myopia.d.ts +7 -0
  130. package/dist/data/solver/backtrack/symbols/myopia.js +79 -0
  131. package/dist/data/solver/backtrack/symbols/viewpoint.d.ts +7 -0
  132. package/dist/data/solver/backtrack/symbols/viewpoint.js +56 -0
  133. package/dist/data/solver/solver.d.ts +61 -0
  134. package/dist/data/solver/solver.js +55 -0
  135. package/dist/data/solver/underclued/undercluedSolver.d.ts +8 -0
  136. package/dist/data/solver/underclued/undercluedSolver.js +55 -0
  137. package/dist/data/solver/underclued/undercluedWorker.d.ts +2 -0
  138. package/dist/data/solver/underclued/undercluedWorker.js +131 -0
  139. package/dist/data/solver/z3/modules/areaNumberModule.d.ts +9 -0
  140. package/dist/data/solver/z3/modules/areaNumberModule.js +35 -0
  141. package/dist/data/solver/z3/modules/cellCountModule.d.ts +9 -0
  142. package/dist/data/solver/z3/modules/cellCountModule.js +59 -0
  143. package/dist/data/solver/z3/modules/connectAllModule.d.ts +9 -0
  144. package/dist/data/solver/z3/modules/connectAllModule.js +32 -0
  145. package/dist/data/solver/z3/modules/dartModule.d.ts +9 -0
  146. package/dist/data/solver/z3/modules/dartModule.js +69 -0
  147. package/dist/data/solver/z3/modules/index.d.ts +3 -0
  148. package/dist/data/solver/z3/modules/index.js +10 -0
  149. package/dist/data/solver/z3/modules/letterModule.d.ts +9 -0
  150. package/dist/data/solver/z3/modules/letterModule.js +41 -0
  151. package/dist/data/solver/z3/modules/modules.gen.d.ts +8 -0
  152. package/dist/data/solver/z3/modules/modules.gen.js +12 -0
  153. package/dist/data/solver/z3/modules/myopiaModule.d.ts +9 -0
  154. package/dist/data/solver/z3/modules/myopiaModule.js +64 -0
  155. package/dist/data/solver/z3/modules/regionAreaModule.d.ts +9 -0
  156. package/dist/data/solver/z3/modules/regionAreaModule.js +48 -0
  157. package/dist/data/solver/z3/modules/viewpointModule.d.ts +9 -0
  158. package/dist/data/solver/z3/modules/viewpointModule.js +37 -0
  159. package/dist/data/solver/z3/modules/z3Module.d.ts +7 -0
  160. package/dist/data/solver/z3/modules/z3Module.js +3 -0
  161. package/dist/data/solver/z3/utils.d.ts +2 -0
  162. package/dist/data/solver/z3/utils.js +26 -0
  163. package/dist/data/solver/z3/z3Solver.d.ts +10 -0
  164. package/dist/data/solver/z3/z3Solver.js +134 -0
  165. package/dist/data/solver/z3/z3SolverContext.d.ts +808 -0
  166. package/dist/data/solver/z3/z3SolverContext.js +49 -0
  167. package/dist/data/symbols/areaNumberSymbol.d.ts +30 -0
  168. package/dist/data/symbols/areaNumberSymbol.js +88 -0
  169. package/dist/data/symbols/customIconSymbol.d.ts +35 -0
  170. package/dist/data/symbols/customIconSymbol.js +105 -0
  171. package/dist/data/symbols/customSymbol.d.ts +23 -0
  172. package/dist/data/symbols/customSymbol.js +48 -0
  173. package/dist/data/symbols/customTextSymbol.d.ts +33 -0
  174. package/dist/data/symbols/customTextSymbol.js +106 -0
  175. package/dist/data/symbols/dartSymbol.d.ts +35 -0
  176. package/dist/data/symbols/dartSymbol.js +110 -0
  177. package/dist/data/symbols/directionLinkerSymbol.d.ts +36 -0
  178. package/dist/data/symbols/directionLinkerSymbol.js +259 -0
  179. package/dist/data/symbols/galaxySymbol.d.ts +26 -0
  180. package/dist/data/symbols/galaxySymbol.js +74 -0
  181. package/dist/data/symbols/index.d.ts +3 -0
  182. package/dist/data/symbols/index.js +10 -0
  183. package/dist/data/symbols/letterSymbol.d.ts +31 -0
  184. package/dist/data/symbols/letterSymbol.js +137 -0
  185. package/dist/data/symbols/lotusSymbol.d.ts +29 -0
  186. package/dist/data/symbols/lotusSymbol.js +132 -0
  187. package/dist/data/symbols/minesweeperSymbol.d.ts +31 -0
  188. package/dist/data/symbols/minesweeperSymbol.js +100 -0
  189. package/dist/data/symbols/multiEntrySymbol.d.ts +11 -0
  190. package/dist/data/symbols/multiEntrySymbol.js +14 -0
  191. package/dist/data/symbols/myopiaSymbol.d.ts +34 -0
  192. package/dist/data/symbols/myopiaSymbol.js +187 -0
  193. package/dist/data/symbols/numberSymbol.d.ts +19 -0
  194. package/dist/data/symbols/numberSymbol.js +41 -0
  195. package/dist/data/symbols/symbol.d.ts +16 -0
  196. package/dist/data/symbols/symbol.js +51 -0
  197. package/dist/data/symbols/symbols.gen.d.ts +10 -0
  198. package/dist/data/symbols/symbols.gen.js +14 -0
  199. package/dist/data/symbols/viewpointSymbol.d.ts +31 -0
  200. package/dist/data/symbols/viewpointSymbol.js +106 -0
  201. package/dist/data/tile.d.ts +26 -0
  202. package/dist/data/tile.js +68 -0
  203. package/dist/data/tileConnections.d.ts +25 -0
  204. package/dist/data/tileConnections.js +74 -0
  205. package/dist/data/validate.d.ts +5 -0
  206. package/dist/data/validate.js +131 -0
  207. package/dist/index.d.ts +96 -0
  208. package/dist/index.js +100 -0
  209. package/dist/polyfill/streamPolyfill.d.ts +2 -0
  210. package/dist/polyfill/streamPolyfill.js +1 -0
  211. package/package.json +75 -0
@@ -0,0 +1,38 @@
1
+ import { Edge, Position } from './primitives';
2
+ import TileConnections from './tileConnections';
3
+ export default class GridConnections {
4
+ readonly edges: readonly Edge[];
5
+ constructor(edges?: readonly Edge[]);
6
+ addEdge(edge: Edge): GridConnections;
7
+ removeEdge(edge: Edge): GridConnections;
8
+ isConnected(edge: Edge): boolean;
9
+ getConnectionsAt({ x, y }: Position): readonly Edge[];
10
+ getForTile({ x, y }: Position): TileConnections;
11
+ getConnectedTiles({ x, y }: Position): readonly Position[];
12
+ /**
13
+ * Create new GridConnections from a string array.
14
+ *
15
+ * - Use `.` for cells that don't connect to anything.
16
+ * - Use any other character for cells that connect to the same character.
17
+ *
18
+ * @param array - The string array to create the connections from.
19
+ * @returns The created connections. You can apply this to a GridData object using GridData.withConnections.
20
+ */
21
+ static create(array: string[]): GridConnections;
22
+ /**
23
+ * Check if two GridConnections objects are equal.
24
+ * @param other The other GridConnections object to compare to.
25
+ * @returns Whether the two objects are equal.
26
+ */
27
+ equals(other: GridConnections): boolean;
28
+ /**
29
+ * Deduplicate an array of edges.
30
+ * @param edges The array of edges to deduplicate.
31
+ * @returns The deduplicated array of edges.
32
+ */
33
+ static deduplicateEdges(edges: readonly Edge[]): readonly Edge[];
34
+ insertColumn(index: number): GridConnections;
35
+ insertRow(index: number): GridConnections;
36
+ removeColumn(index: number): GridConnections;
37
+ removeRow(index: number): GridConnections;
38
+ }
@@ -0,0 +1,328 @@
1
+ import TileConnections from './tileConnections';
2
+ function isSameEdge(a, b) {
3
+ return ((a.x1 === b.x1 && a.y1 === b.y1 && a.x2 === b.x2 && a.y2 === b.y2) ||
4
+ (a.x1 === b.x2 && a.y1 === b.y2 && a.x2 === b.x1 && a.y2 === b.y1));
5
+ }
6
+ export default class GridConnections {
7
+ constructor(edges) {
8
+ Object.defineProperty(this, "edges", {
9
+ enumerable: true,
10
+ configurable: true,
11
+ writable: true,
12
+ value: void 0
13
+ });
14
+ this.edges = GridConnections.deduplicateEdges(edges ?? []);
15
+ }
16
+ addEdge(edge) {
17
+ if (this.edges.some(e => isSameEdge(e, edge))) {
18
+ return this;
19
+ }
20
+ return new GridConnections([...this.edges, edge]);
21
+ }
22
+ removeEdge(edge) {
23
+ return new GridConnections(this.edges.filter(e => !isSameEdge(e, edge)));
24
+ }
25
+ isConnected(edge) {
26
+ if (edge.x1 === edge.x2 && edge.y1 === edge.y2)
27
+ return true;
28
+ return this.edges.some(e => isSameEdge(e, edge));
29
+ }
30
+ getConnectionsAt({ x, y }) {
31
+ return this.edges.filter(e => (e.x1 === x && e.y1 === y) || (e.x2 === x && e.y2 === y));
32
+ }
33
+ getForTile({ x, y }) {
34
+ const result = new TileConnections();
35
+ // Get all connections within 2 steps of the tile
36
+ const edges = this.getConnectionsAt({ x, y });
37
+ const edges2 = [
38
+ ...edges,
39
+ ...edges.flatMap(edge => {
40
+ if (edge.x1 === x && edge.y1 === y) {
41
+ return this.getConnectionsAt({ x: edge.x2, y: edge.y2 });
42
+ }
43
+ else {
44
+ return this.getConnectionsAt({ x: edge.x1, y: edge.y1 });
45
+ }
46
+ }),
47
+ ];
48
+ // Fill in the connections
49
+ for (const edge of edges2) {
50
+ if (edge.x1 !== x || edge.y1 !== y) {
51
+ const offsetX = edge.x1 - x;
52
+ const offsetY = edge.y1 - y;
53
+ if (offsetX >= -1 && offsetX <= 1 && offsetY >= -1 && offsetY <= 1) {
54
+ result[offsetY][offsetX] = true;
55
+ }
56
+ }
57
+ if (edge.x2 !== x || edge.y2 !== y) {
58
+ const offsetX = edge.x2 - x;
59
+ const offsetY = edge.y2 - y;
60
+ if (offsetX >= -1 && offsetX <= 1 && offsetY >= -1 && offsetY <= 1) {
61
+ result[offsetY][offsetX] = true;
62
+ }
63
+ }
64
+ }
65
+ // Fix the center and corner connections
66
+ result.center = true;
67
+ if (!result.top || !result.left) {
68
+ result.topLeft = false;
69
+ }
70
+ if (!result.top || !result.right) {
71
+ result.topRight = false;
72
+ }
73
+ if (!result.bottom || !result.left) {
74
+ result.bottomLeft = false;
75
+ }
76
+ if (!result.bottom || !result.right) {
77
+ result.bottomRight = false;
78
+ }
79
+ return result;
80
+ }
81
+ getConnectedTiles({ x, y }) {
82
+ const result = [];
83
+ const visited = new Set();
84
+ const queue = [{ x, y }];
85
+ while (queue.length > 0) {
86
+ const current = queue.pop();
87
+ if (visited.has(`${current.x},${current.y}`)) {
88
+ continue;
89
+ }
90
+ visited.add(`${current.x},${current.y}`);
91
+ result.push(current);
92
+ const edges = this.getConnectionsAt(current);
93
+ for (const edge of edges) {
94
+ if (edge.x1 === current.x && edge.y1 === current.y) {
95
+ queue.push({ x: edge.x2, y: edge.y2 });
96
+ }
97
+ else {
98
+ queue.push({ x: edge.x1, y: edge.y1 });
99
+ }
100
+ }
101
+ }
102
+ return result;
103
+ }
104
+ /**
105
+ * Create new GridConnections from a string array.
106
+ *
107
+ * - Use `.` for cells that don't connect to anything.
108
+ * - Use any other character for cells that connect to the same character.
109
+ *
110
+ * @param array - The string array to create the connections from.
111
+ * @returns The created connections. You can apply this to a GridData object using GridData.withConnections.
112
+ */
113
+ static create(array) {
114
+ const edges = [];
115
+ for (let y = 0; y < array.length; y++) {
116
+ for (let x = 0; x < array[y].length; x++) {
117
+ if (array[y][x] === '.') {
118
+ continue;
119
+ }
120
+ if (x > 0 && array[y][x - 1] === array[y][x]) {
121
+ edges.push({ x1: x - 1, y1: y, x2: x, y2: y });
122
+ }
123
+ if (y > 0 && array[y - 1][x] === array[y][x]) {
124
+ edges.push({ x1: x, y1: y - 1, x2: x, y2: y });
125
+ }
126
+ }
127
+ }
128
+ return new GridConnections(edges);
129
+ }
130
+ /**
131
+ * Check if two GridConnections objects are equal.
132
+ * @param other The other GridConnections object to compare to.
133
+ * @returns Whether the two objects are equal.
134
+ */
135
+ equals(other) {
136
+ if (this.edges.length !== other.edges.length)
137
+ return false;
138
+ for (const edge of this.edges) {
139
+ if (!other.isConnected(edge))
140
+ return false;
141
+ }
142
+ return true;
143
+ }
144
+ /**
145
+ * Deduplicate an array of edges.
146
+ * @param edges The array of edges to deduplicate.
147
+ * @returns The deduplicated array of edges.
148
+ */
149
+ static deduplicateEdges(edges) {
150
+ return edges.filter((edge, index) => edges.findIndex(e => isSameEdge(e, edge)) === index);
151
+ }
152
+ insertColumn(index) {
153
+ return new GridConnections(this.edges.flatMap(edge => {
154
+ if ((edge.x1 < index && edge.x2 < index) ||
155
+ (edge.x1 >= index && edge.x2 >= index)) {
156
+ if (edge.x1 < index) {
157
+ return [edge];
158
+ }
159
+ return [
160
+ { x1: edge.x1 + 1, y1: edge.y1, x2: edge.x2 + 1, y2: edge.y2 },
161
+ ];
162
+ }
163
+ return [
164
+ { x1: edge.x1, y1: edge.y1, x2: edge.x2, y2: edge.y2 },
165
+ { x1: edge.x1 + 1, y1: edge.y1, x2: edge.x2 + 1, y2: edge.y2 },
166
+ ];
167
+ }));
168
+ }
169
+ insertRow(index) {
170
+ return new GridConnections(this.edges.flatMap(edge => {
171
+ if ((edge.y1 < index && edge.y2 < index) ||
172
+ (edge.y1 >= index && edge.y2 >= index)) {
173
+ if (edge.y1 < index) {
174
+ return [edge];
175
+ }
176
+ return [
177
+ { x1: edge.x1, y1: edge.y1 + 1, x2: edge.x2, y2: edge.y2 + 1 },
178
+ ];
179
+ }
180
+ return [
181
+ { x1: edge.x1, y1: edge.y1, x2: edge.x2, y2: edge.y2 },
182
+ { x1: edge.x1, y1: edge.y1 + 1, x2: edge.x2, y2: edge.y2 + 1 },
183
+ ];
184
+ }));
185
+ }
186
+ removeColumn(index) {
187
+ const toProcess = new Map();
188
+ const toKeep = [];
189
+ this.edges.forEach(edge => {
190
+ if ((edge.x1 < index && edge.x2 < index) ||
191
+ (edge.x1 > index && edge.x2 > index)) {
192
+ if (edge.x1 < index) {
193
+ toKeep.push(edge);
194
+ }
195
+ else {
196
+ toKeep.push({
197
+ x1: edge.x1 - 1,
198
+ y1: edge.y1,
199
+ x2: edge.x2 - 1,
200
+ y2: edge.y2,
201
+ });
202
+ }
203
+ }
204
+ else if (edge.x1 !== index && edge.x2 !== index) {
205
+ toKeep.push({
206
+ x1: edge.x1 > index ? edge.x1 - 1 : edge.x1,
207
+ y1: edge.y1,
208
+ x2: edge.x2 > index ? edge.x2 - 1 : edge.x2,
209
+ y2: edge.y2,
210
+ });
211
+ }
212
+ else {
213
+ if (edge.x1 === index) {
214
+ if (!toProcess.has(edge.y1)) {
215
+ toProcess.set(edge.y1, [edge]);
216
+ }
217
+ else {
218
+ toProcess.get(edge.y1).push(edge);
219
+ }
220
+ }
221
+ else if (edge.x2 === index) {
222
+ if (!toProcess.has(edge.y2)) {
223
+ toProcess.set(edge.y2, [edge]);
224
+ }
225
+ else {
226
+ toProcess.get(edge.y2).push(edge);
227
+ }
228
+ }
229
+ }
230
+ });
231
+ for (const [key, list] of toProcess.entries()) {
232
+ for (let i = 1; i < list.length; i++) {
233
+ if (!isSameEdge(list[i], list[i - 1])) {
234
+ let x1, y1, x2, y2;
235
+ if (list[i].x1 === index && list[i].y1 === key) {
236
+ x1 = list[i].x2 > index ? list[i].x2 - 1 : list[i].x2;
237
+ y1 = list[i].y2;
238
+ }
239
+ else {
240
+ x1 = list[i].x1 > index ? list[i].x1 - 1 : list[i].x1;
241
+ y1 = list[i].y1;
242
+ }
243
+ if (list[i - 1].x1 === index && list[i - 1].y1 === key) {
244
+ x2 = list[i - 1].x2 > index ? list[i - 1].x2 - 1 : list[i - 1].x2;
245
+ y2 = list[i - 1].y2;
246
+ }
247
+ else {
248
+ x2 = list[i - 1].x1 > index ? list[i - 1].x1 - 1 : list[i - 1].x1;
249
+ y2 = list[i - 1].y1;
250
+ }
251
+ toKeep.push({ x1, y1, x2, y2 });
252
+ }
253
+ }
254
+ }
255
+ return new GridConnections(toKeep);
256
+ }
257
+ removeRow(index) {
258
+ const toProcess = new Map();
259
+ const toKeep = [];
260
+ this.edges.forEach(edge => {
261
+ if ((edge.y1 < index && edge.y2 < index) ||
262
+ (edge.y1 > index && edge.y2 > index)) {
263
+ if (edge.y1 < index) {
264
+ toKeep.push(edge);
265
+ }
266
+ else {
267
+ toKeep.push({
268
+ x1: edge.x1,
269
+ y1: edge.y1 - 1,
270
+ x2: edge.x2,
271
+ y2: edge.y2 - 1,
272
+ });
273
+ }
274
+ }
275
+ else if (edge.y1 !== index && edge.y2 !== index) {
276
+ toKeep.push({
277
+ x1: edge.x1,
278
+ y1: edge.y1 > index ? edge.y1 - 1 : edge.y1,
279
+ x2: edge.x2,
280
+ y2: edge.y2 > index ? edge.y2 - 1 : edge.y2,
281
+ });
282
+ }
283
+ else {
284
+ if (edge.y1 === index) {
285
+ if (!toProcess.has(edge.x1)) {
286
+ toProcess.set(edge.x1, [edge]);
287
+ }
288
+ else {
289
+ toProcess.get(edge.x1).push(edge);
290
+ }
291
+ }
292
+ else if (edge.y2 === index) {
293
+ if (!toProcess.has(edge.x2)) {
294
+ toProcess.set(edge.x2, [edge]);
295
+ }
296
+ else {
297
+ toProcess.get(edge.x2).push(edge);
298
+ }
299
+ }
300
+ }
301
+ });
302
+ for (const [key, list] of toProcess.entries()) {
303
+ for (let i = 1; i < list.length; i++) {
304
+ if (!isSameEdge(list[i], list[i - 1])) {
305
+ let x1, y1, x2, y2;
306
+ if (list[i].y1 === index && list[i].x1 === key) {
307
+ x1 = list[i].x2;
308
+ y1 = list[i].y2 > index ? list[i].y2 - 1 : list[i].y2;
309
+ }
310
+ else {
311
+ x1 = list[i].x1;
312
+ y1 = list[i].y1 > index ? list[i].y1 - 1 : list[i].y1;
313
+ }
314
+ if (list[i - 1].y1 === index && list[i - 1].x1 === key) {
315
+ x2 = list[i - 1].x2;
316
+ y2 = list[i - 1].y2 > index ? list[i - 1].y2 - 1 : list[i - 1].y2;
317
+ }
318
+ else {
319
+ x2 = list[i - 1].x1;
320
+ y2 = list[i - 1].y1 > index ? list[i - 1].y1 - 1 : list[i - 1].y1;
321
+ }
322
+ toKeep.push({ x1, y1, x2, y2 });
323
+ }
324
+ }
325
+ }
326
+ return new GridConnections(toKeep);
327
+ }
328
+ }
@@ -0,0 +1,19 @@
1
+ import Configurable from './configurable';
2
+ import GridData from './grid';
3
+ export default abstract class Instruction extends Configurable {
4
+ abstract get id(): string;
5
+ abstract get explanation(): string;
6
+ abstract createExampleGrid(): GridData;
7
+ /**
8
+ * Indicates that validation by logic is not available and the solution must be used for validation
9
+ */
10
+ get validateWithSolution(): boolean;
11
+ get necessaryForCompletion(): boolean;
12
+ /**
13
+ * Check if this instruction is equal to another instruction by comparing their IDs and configs.
14
+ *
15
+ * @param other The other instruction to compare to.
16
+ * @returns Whether the two instructions are equal.
17
+ */
18
+ equals(other: Instruction): boolean;
19
+ }
@@ -0,0 +1,23 @@
1
+ import Configurable from './configurable';
2
+ export default class Instruction extends Configurable {
3
+ /**
4
+ * Indicates that validation by logic is not available and the solution must be used for validation
5
+ */
6
+ get validateWithSolution() {
7
+ return false;
8
+ }
9
+ get necessaryForCompletion() {
10
+ return true;
11
+ }
12
+ /**
13
+ * Check if this instruction is equal to another instruction by comparing their IDs and configs.
14
+ *
15
+ * @param other The other instruction to compare to.
16
+ * @returns Whether the two instructions are equal.
17
+ */
18
+ equals(other) {
19
+ if (this.id !== other.id)
20
+ return false;
21
+ return super.equals(other);
22
+ }
23
+ }
@@ -0,0 +1,85 @@
1
+ export interface Position {
2
+ readonly x: number;
3
+ readonly y: number;
4
+ }
5
+ export interface Edge {
6
+ readonly x1: number;
7
+ readonly y1: number;
8
+ readonly x2: number;
9
+ readonly y2: number;
10
+ }
11
+ export declare enum State {
12
+ Error = "error",
13
+ Satisfied = "satisfied",
14
+ Incomplete = "incomplete"
15
+ }
16
+ export type RuleState = {
17
+ readonly state: State.Error;
18
+ readonly positions: readonly Position[];
19
+ } | {
20
+ readonly state: State.Satisfied;
21
+ } | {
22
+ readonly state: State.Incomplete;
23
+ };
24
+ export interface GridState {
25
+ final: State;
26
+ rules: readonly RuleState[];
27
+ symbols: ReadonlyMap<string, State[]>;
28
+ }
29
+ export declare enum Color {
30
+ Dark = "dark",
31
+ Light = "light",
32
+ Gray = "gray"
33
+ }
34
+ export declare enum Comparison {
35
+ Equal = "eq",
36
+ AtLeast = "ge",
37
+ AtMost = "le"
38
+ }
39
+ export declare const COMPARISONS: readonly Comparison[];
40
+ export declare enum Direction {
41
+ Up = "up",
42
+ Down = "down",
43
+ Left = "left",
44
+ Right = "right"
45
+ }
46
+ export declare const DIRECTIONS: readonly Direction[];
47
+ export type DirectionMap<T> = {
48
+ [key in Direction]: T;
49
+ };
50
+ export type DirectionToggle = Readonly<DirectionMap<boolean>>;
51
+ export declare function directionToggle(...directions: readonly Direction[]): {
52
+ up: boolean;
53
+ down: boolean;
54
+ left: boolean;
55
+ right: boolean;
56
+ };
57
+ export declare enum Orientation {
58
+ Up = "up",
59
+ UpRight = "up-right",
60
+ Right = "right",
61
+ DownRight = "down-right",
62
+ Down = "down",
63
+ DownLeft = "down-left",
64
+ Left = "left",
65
+ UpLeft = "up-left"
66
+ }
67
+ export declare const ORIENTATIONS: readonly Orientation[];
68
+ export type OrientationMap<T> = {
69
+ [key in Orientation]: T;
70
+ };
71
+ export type OrientationToggle = Readonly<OrientationMap<boolean>>;
72
+ export declare function orientationToggle(...orientations: readonly Orientation[]): {
73
+ up: boolean;
74
+ 'up-right': boolean;
75
+ right: boolean;
76
+ 'down-right': boolean;
77
+ down: boolean;
78
+ 'down-left': boolean;
79
+ left: boolean;
80
+ 'up-left': boolean;
81
+ };
82
+ export declare enum Mode {
83
+ Create = "create",
84
+ Solve = "solve"
85
+ }
@@ -0,0 +1,90 @@
1
+ export var State;
2
+ (function (State) {
3
+ State["Error"] = "error";
4
+ State["Satisfied"] = "satisfied";
5
+ State["Incomplete"] = "incomplete";
6
+ })(State || (State = {}));
7
+ export var Color;
8
+ (function (Color) {
9
+ Color["Dark"] = "dark";
10
+ Color["Light"] = "light";
11
+ Color["Gray"] = "gray";
12
+ })(Color || (Color = {}));
13
+ export var Comparison;
14
+ (function (Comparison) {
15
+ Comparison["Equal"] = "eq";
16
+ Comparison["AtLeast"] = "ge";
17
+ Comparison["AtMost"] = "le";
18
+ })(Comparison || (Comparison = {}));
19
+ export const COMPARISONS = [
20
+ Comparison.Equal,
21
+ Comparison.AtLeast,
22
+ Comparison.AtMost,
23
+ ];
24
+ export var Direction;
25
+ (function (Direction) {
26
+ Direction["Up"] = "up";
27
+ Direction["Down"] = "down";
28
+ Direction["Left"] = "left";
29
+ Direction["Right"] = "right";
30
+ })(Direction || (Direction = {}));
31
+ export const DIRECTIONS = [
32
+ Direction.Up,
33
+ Direction.Down,
34
+ Direction.Left,
35
+ Direction.Right,
36
+ ];
37
+ export function directionToggle(...directions) {
38
+ const result = {
39
+ up: false,
40
+ down: false,
41
+ left: false,
42
+ right: false,
43
+ };
44
+ for (const direction of directions) {
45
+ result[direction] = true;
46
+ }
47
+ return result;
48
+ }
49
+ export var Orientation;
50
+ (function (Orientation) {
51
+ Orientation["Up"] = "up";
52
+ Orientation["UpRight"] = "up-right";
53
+ Orientation["Right"] = "right";
54
+ Orientation["DownRight"] = "down-right";
55
+ Orientation["Down"] = "down";
56
+ Orientation["DownLeft"] = "down-left";
57
+ Orientation["Left"] = "left";
58
+ Orientation["UpLeft"] = "up-left";
59
+ })(Orientation || (Orientation = {}));
60
+ export const ORIENTATIONS = [
61
+ Orientation.Up,
62
+ Orientation.UpRight,
63
+ Orientation.Right,
64
+ Orientation.DownRight,
65
+ Orientation.Down,
66
+ Orientation.DownLeft,
67
+ Orientation.Left,
68
+ Orientation.UpLeft,
69
+ ];
70
+ export function orientationToggle(...orientations) {
71
+ const result = {
72
+ up: false,
73
+ 'up-right': false,
74
+ right: false,
75
+ 'down-right': false,
76
+ down: false,
77
+ 'down-left': false,
78
+ left: false,
79
+ 'up-left': false,
80
+ };
81
+ for (const orientation of orientations) {
82
+ result[orientation] = true;
83
+ }
84
+ return result;
85
+ }
86
+ export var Mode;
87
+ (function (Mode) {
88
+ Mode["Create"] = "create";
89
+ Mode["Solve"] = "solve";
90
+ })(Mode || (Mode = {}));
@@ -0,0 +1,86 @@
1
+ import { z } from 'zod';
2
+ import GridData from './grid';
3
+ export type PuzzleMetadata = {
4
+ /**
5
+ * The title of the puzzle. (required)
6
+ */
7
+ title: string;
8
+ /**
9
+ * The author of the puzzle. (required)
10
+ */
11
+ author: string;
12
+ /**
13
+ * A description of the puzzle. (can be empty)
14
+ */
15
+ description: string;
16
+ /**
17
+ * A link to a place to discuss this puzzle. (can be empty)
18
+ */
19
+ link: string;
20
+ /**
21
+ * The difficulty of the puzzle, from 1 to 10. (required)
22
+ *
23
+ * 6-10 represent star difficulties.
24
+ */
25
+ difficulty: number;
26
+ };
27
+ export declare const MetadataSchema: z.ZodObject<{
28
+ title: z.ZodString;
29
+ author: z.ZodString;
30
+ description: z.ZodString;
31
+ link: z.ZodString;
32
+ difficulty: z.ZodNumber;
33
+ }, "strict", z.ZodTypeAny, {
34
+ description: string;
35
+ title: string;
36
+ author: string;
37
+ link: string;
38
+ difficulty: number;
39
+ }, {
40
+ description: string;
41
+ title: string;
42
+ author: string;
43
+ link: string;
44
+ difficulty: number;
45
+ }>;
46
+ export declare const PuzzleSchema: z.ZodObject<{
47
+ title: z.ZodString;
48
+ author: z.ZodString;
49
+ description: z.ZodString;
50
+ link: z.ZodString;
51
+ difficulty: z.ZodNumber;
52
+ grid: z.ZodType<GridData, z.ZodTypeDef, GridData>;
53
+ solution: z.ZodNullable<z.ZodType<GridData, z.ZodTypeDef, GridData>>;
54
+ }, "strict", z.ZodTypeAny, {
55
+ description: string;
56
+ grid: GridData;
57
+ title: string;
58
+ author: string;
59
+ link: string;
60
+ difficulty: number;
61
+ solution: GridData | null;
62
+ }, {
63
+ description: string;
64
+ grid: GridData;
65
+ title: string;
66
+ author: string;
67
+ link: string;
68
+ difficulty: number;
69
+ solution: GridData | null;
70
+ }>;
71
+ export type Puzzle = PuzzleMetadata & {
72
+ /**
73
+ * The grid of the puzzle. (required)
74
+ *
75
+ * You must fix all given cells in the grid. The rest of the cells will be cleared.
76
+ */
77
+ grid: GridData;
78
+ /**
79
+ * The solution to the puzzle. (optional)
80
+ *
81
+ * You should provide a solution if a rule requires it. Otherwise, the rule can never be satisfied.
82
+ *
83
+ * If there are no rules that require a solution, this field will be ignored.
84
+ */
85
+ solution: GridData | null;
86
+ };
@@ -0,0 +1,22 @@
1
+ import { z } from 'zod';
2
+ import GridData from './grid';
3
+ export const MetadataSchema = z
4
+ .object({
5
+ title: z.string().min(1),
6
+ author: z.string().min(1),
7
+ description: z.string(),
8
+ link: z.string(),
9
+ difficulty: z.number().int().min(1).max(10),
10
+ })
11
+ .strict();
12
+ export const PuzzleSchema = z
13
+ .object({
14
+ title: z.string().min(1),
15
+ author: z.string().min(1),
16
+ description: z.string(),
17
+ link: z.string(),
18
+ difficulty: z.number().int().min(1).max(10),
19
+ grid: z.instanceof(GridData),
20
+ solution: z.instanceof(GridData).nullable(),
21
+ })
22
+ .strict();