cubegin 0.0.1

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 (164) hide show
  1. package/CHANGELOG.md +17 -0
  2. package/LICENSE +674 -0
  3. package/NOTICE +11 -0
  4. package/README.md +49 -0
  5. package/dist/scramble-core/src/batch.mjs +18 -0
  6. package/dist/scramble-core/src/generator.d.mts +35 -0
  7. package/dist/scramble-core/src/generator.mjs +136 -0
  8. package/dist/scramble-core/src/generators/clock.d.mts +11 -0
  9. package/dist/scramble-core/src/generators/clock.mjs +32 -0
  10. package/dist/scramble-core/src/generators/cube-random-turns.d.mts +11 -0
  11. package/dist/scramble-core/src/generators/cube-random-turns.mjs +54 -0
  12. package/dist/scramble-core/src/generators/four-by-four.d.mts +14 -0
  13. package/dist/scramble-core/src/generators/four-by-four.mjs +43 -0
  14. package/dist/scramble-core/src/generators/megaminx.d.mts +11 -0
  15. package/dist/scramble-core/src/generators/megaminx.mjs +18 -0
  16. package/dist/scramble-core/src/generators/pyraminx.d.mts +11 -0
  17. package/dist/scramble-core/src/generators/pyraminx.mjs +17 -0
  18. package/dist/scramble-core/src/generators/skewb.d.mts +11 -0
  19. package/dist/scramble-core/src/generators/skewb.mjs +17 -0
  20. package/dist/scramble-core/src/generators/square1.d.mts +11 -0
  21. package/dist/scramble-core/src/generators/square1.mjs +28 -0
  22. package/dist/scramble-core/src/generators/three-by-three.d.mts +25 -0
  23. package/dist/scramble-core/src/generators/three-by-three.mjs +85 -0
  24. package/dist/scramble-core/src/generators/two-by-two.d.mts +11 -0
  25. package/dist/scramble-core/src/generators/two-by-two.mjs +17 -0
  26. package/dist/scramble-core/src/random-source.d.mts +7 -0
  27. package/dist/scramble-core/src/random-source.mjs +8 -0
  28. package/dist/scramble-core/src/solvers/min2phase/coord-cube.mjs +10 -0
  29. package/dist/scramble-core/src/solvers/min2phase/cubie-cube.mjs +246 -0
  30. package/dist/scramble-core/src/solvers/min2phase/engine.mjs +1281 -0
  31. package/dist/scramble-core/src/solvers/min2phase/search-wca.mjs +21 -0
  32. package/dist/scramble-core/src/solvers/min2phase/search.mjs +25 -0
  33. package/dist/scramble-core/src/solvers/min2phase/tools.mjs +169 -0
  34. package/dist/scramble-core/src/solvers/min2phase/util.mjs +30 -0
  35. package/dist/scramble-core/src/solvers/pyraminx-solver.d.mts +17 -0
  36. package/dist/scramble-core/src/solvers/pyraminx-solver.mjs +350 -0
  37. package/dist/scramble-core/src/solvers/skewb-solver.d.mts +15 -0
  38. package/dist/scramble-core/src/solvers/skewb-solver.mjs +399 -0
  39. package/dist/scramble-core/src/solvers/sq12phase/full-cube.mjs +212 -0
  40. package/dist/scramble-core/src/solvers/sq12phase/search.mjs +520 -0
  41. package/dist/scramble-core/src/solvers/sq12phase/shape.mjs +214 -0
  42. package/dist/scramble-core/src/solvers/sq12phase/square.mjs +135 -0
  43. package/dist/scramble-core/src/solvers/threephase/center.mjs +798 -0
  44. package/dist/scramble-core/src/solvers/threephase/edge.mjs +632 -0
  45. package/dist/scramble-core/src/solvers/threephase/full-cube.mjs +554 -0
  46. package/dist/scramble-core/src/solvers/threephase/search.mjs +262 -0
  47. package/dist/scramble-core/src/solvers/threephase/tables.mjs +201 -0
  48. package/dist/scramble-core/src/solvers/two-by-two-solver.d.mts +15 -0
  49. package/dist/scramble-core/src/solvers/two-by-two-solver.mjs +298 -0
  50. package/dist/scramble-core.d.mts +15 -0
  51. package/dist/scramble-core.mjs +15 -0
  52. package/dist/scramble-image/src/color.d.mts +12 -0
  53. package/dist/scramble-image/src/color.mjs +11 -0
  54. package/dist/scramble-image/src/render.d.mts +10 -0
  55. package/dist/scramble-image/src/render.mjs +71 -0
  56. package/dist/scramble-image/src/renderers/clock.d.mts +6 -0
  57. package/dist/scramble-image/src/renderers/clock.mjs +145 -0
  58. package/dist/scramble-image/src/renderers/cube-isometric.d.mts +8 -0
  59. package/dist/scramble-image/src/renderers/cube-isometric.mjs +204 -0
  60. package/dist/scramble-image/src/renderers/cube-net.d.mts +8 -0
  61. package/dist/scramble-image/src/renderers/cube-net.mjs +52 -0
  62. package/dist/scramble-image/src/renderers/megaminx-isometric.d.mts +9 -0
  63. package/dist/scramble-image/src/renderers/megaminx-isometric.mjs +320 -0
  64. package/dist/scramble-image/src/renderers/megaminx.d.mts +9 -0
  65. package/dist/scramble-image/src/renderers/megaminx.mjs +173 -0
  66. package/dist/scramble-image/src/renderers/pyraminx-isometric.d.mts +9 -0
  67. package/dist/scramble-image/src/renderers/pyraminx-isometric.mjs +185 -0
  68. package/dist/scramble-image/src/renderers/pyraminx.d.mts +9 -0
  69. package/dist/scramble-image/src/renderers/pyraminx.mjs +111 -0
  70. package/dist/scramble-image/src/renderers/skewb-isometric.d.mts +9 -0
  71. package/dist/scramble-image/src/renderers/skewb-isometric.mjs +233 -0
  72. package/dist/scramble-image/src/renderers/skewb.d.mts +9 -0
  73. package/dist/scramble-image/src/renderers/skewb.mjs +187 -0
  74. package/dist/scramble-image/src/renderers/square1.d.mts +10 -0
  75. package/dist/scramble-image/src/renderers/square1.mjs +253 -0
  76. package/dist/scramble-image/src/svg/svg-document.d.mts +6 -0
  77. package/dist/scramble-image/src/svg/svg-document.mjs +7 -0
  78. package/dist/scramble-image/src/svg/svg-elements.d.mts +15 -0
  79. package/dist/scramble-image/src/svg/svg-elements.mjs +25 -0
  80. package/dist/scramble-image/src/svg/svg-serialize.mjs +29 -0
  81. package/dist/scramble-image.d.mts +15 -0
  82. package/dist/scramble-image.mjs +15 -0
  83. package/dist/scramble-puzzle/src/algorithm.d.mts +8 -0
  84. package/dist/scramble-puzzle/src/algorithm.mjs +16 -0
  85. package/dist/scramble-puzzle/src/algorithm2.mjs +16 -0
  86. package/dist/scramble-puzzle/src/clock/clock-definition.d.mts +8 -0
  87. package/dist/scramble-puzzle/src/clock/clock-definition.mjs +18 -0
  88. package/dist/scramble-puzzle/src/clock/clock-definition2.mjs +18 -0
  89. package/dist/scramble-puzzle/src/clock/clock-parser.d.mts +18 -0
  90. package/dist/scramble-puzzle/src/clock/clock-parser.mjs +35 -0
  91. package/dist/scramble-puzzle/src/clock/clock-parser2.mjs +35 -0
  92. package/dist/scramble-puzzle/src/clock/clock-state.d.mts +8 -0
  93. package/dist/scramble-puzzle/src/clock/clock-state.mjs +212 -0
  94. package/dist/scramble-puzzle/src/clock/clock-state2.d.mts +13 -0
  95. package/dist/scramble-puzzle/src/clock/clock-state2.mjs +212 -0
  96. package/dist/scramble-puzzle/src/cube/cube-definition.d.mts +9 -0
  97. package/dist/scramble-puzzle/src/cube/cube-definition.mjs +18 -0
  98. package/dist/scramble-puzzle/src/cube/cube-definition2.mjs +18 -0
  99. package/dist/scramble-puzzle/src/cube/cube-move.d.mts +4 -0
  100. package/dist/scramble-puzzle/src/cube/cube-move2.d.mts +17 -0
  101. package/dist/scramble-puzzle/src/cube/cube-parser.d.mts +7 -0
  102. package/dist/scramble-puzzle/src/cube/cube-parser.mjs +60 -0
  103. package/dist/scramble-puzzle/src/cube/cube-parser2.mjs +60 -0
  104. package/dist/scramble-puzzle/src/cube/cube-state.d.mts +12 -0
  105. package/dist/scramble-puzzle/src/cube/cube-state.mjs +187 -0
  106. package/dist/scramble-puzzle/src/cube/cube-state2.d.mts +15 -0
  107. package/dist/scramble-puzzle/src/cube/cube-state2.mjs +187 -0
  108. package/dist/scramble-puzzle/src/errors.d.mts +15 -0
  109. package/dist/scramble-puzzle/src/errors.mjs +24 -0
  110. package/dist/scramble-puzzle/src/errors2.mjs +30 -0
  111. package/dist/scramble-puzzle/src/events.d.mts +5 -0
  112. package/dist/scramble-puzzle/src/events.mjs +90 -0
  113. package/dist/scramble-puzzle/src/events2.d.mts +98 -0
  114. package/dist/scramble-puzzle/src/events2.mjs +109 -0
  115. package/dist/scramble-puzzle/src/index.mjs +22 -0
  116. package/dist/scramble-puzzle/src/megaminx/megaminx-definition.d.mts +8 -0
  117. package/dist/scramble-puzzle/src/megaminx/megaminx-definition.mjs +18 -0
  118. package/dist/scramble-puzzle/src/megaminx/megaminx-definition2.mjs +18 -0
  119. package/dist/scramble-puzzle/src/megaminx/megaminx-parser.d.mts +5 -0
  120. package/dist/scramble-puzzle/src/megaminx/megaminx-parser.mjs +57 -0
  121. package/dist/scramble-puzzle/src/megaminx/megaminx-parser2.d.mts +20 -0
  122. package/dist/scramble-puzzle/src/megaminx/megaminx-parser2.mjs +57 -0
  123. package/dist/scramble-puzzle/src/megaminx/megaminx-state.d.mts +9 -0
  124. package/dist/scramble-puzzle/src/megaminx/megaminx-state.mjs +112 -0
  125. package/dist/scramble-puzzle/src/megaminx/megaminx-state2.d.mts +14 -0
  126. package/dist/scramble-puzzle/src/megaminx/megaminx-state2.mjs +112 -0
  127. package/dist/scramble-puzzle/src/puzzle-definition.d.mts +19 -0
  128. package/dist/scramble-puzzle/src/pyraminx/pyraminx-definition.d.mts +8 -0
  129. package/dist/scramble-puzzle/src/pyraminx/pyraminx-definition.mjs +18 -0
  130. package/dist/scramble-puzzle/src/pyraminx/pyraminx-definition2.mjs +18 -0
  131. package/dist/scramble-puzzle/src/pyraminx/pyraminx-parser.d.mts +5 -0
  132. package/dist/scramble-puzzle/src/pyraminx/pyraminx-parser.mjs +34 -0
  133. package/dist/scramble-puzzle/src/pyraminx/pyraminx-parser2.d.mts +21 -0
  134. package/dist/scramble-puzzle/src/pyraminx/pyraminx-parser2.mjs +34 -0
  135. package/dist/scramble-puzzle/src/pyraminx/pyraminx-state.d.mts +11 -0
  136. package/dist/scramble-puzzle/src/pyraminx/pyraminx-state.mjs +90 -0
  137. package/dist/scramble-puzzle/src/pyraminx/pyraminx-state2.d.mts +14 -0
  138. package/dist/scramble-puzzle/src/pyraminx/pyraminx-state2.mjs +90 -0
  139. package/dist/scramble-puzzle/src/registry.d.mts +11 -0
  140. package/dist/scramble-puzzle/src/registry.mjs +13 -0
  141. package/dist/scramble-puzzle/src/skewb/skewb-definition.d.mts +8 -0
  142. package/dist/scramble-puzzle/src/skewb/skewb-definition.mjs +18 -0
  143. package/dist/scramble-puzzle/src/skewb/skewb-definition2.mjs +18 -0
  144. package/dist/scramble-puzzle/src/skewb/skewb-parser.d.mts +5 -0
  145. package/dist/scramble-puzzle/src/skewb/skewb-parser.mjs +33 -0
  146. package/dist/scramble-puzzle/src/skewb/skewb-parser2.d.mts +14 -0
  147. package/dist/scramble-puzzle/src/skewb/skewb-parser2.mjs +33 -0
  148. package/dist/scramble-puzzle/src/skewb/skewb-state.d.mts +11 -0
  149. package/dist/scramble-puzzle/src/skewb/skewb-state.mjs +75 -0
  150. package/dist/scramble-puzzle/src/skewb/skewb-state2.d.mts +14 -0
  151. package/dist/scramble-puzzle/src/skewb/skewb-state2.mjs +75 -0
  152. package/dist/scramble-puzzle/src/square1/square1-definition.d.mts +8 -0
  153. package/dist/scramble-puzzle/src/square1/square1-definition.mjs +18 -0
  154. package/dist/scramble-puzzle/src/square1/square1-definition2.mjs +18 -0
  155. package/dist/scramble-puzzle/src/square1/square1-parser.d.mts +17 -0
  156. package/dist/scramble-puzzle/src/square1/square1-parser.mjs +43 -0
  157. package/dist/scramble-puzzle/src/square1/square1-parser2.mjs +47 -0
  158. package/dist/scramble-puzzle/src/square1/square1-state.d.mts +9 -0
  159. package/dist/scramble-puzzle/src/square1/square1-state.mjs +115 -0
  160. package/dist/scramble-puzzle/src/square1/square1-state2.d.mts +21 -0
  161. package/dist/scramble-puzzle/src/square1/square1-state2.mjs +115 -0
  162. package/dist/scramble-puzzle.d.mts +25 -0
  163. package/dist/scramble-puzzle.mjs +23 -0
  164. package/package.json +37 -0
@@ -0,0 +1,214 @@
1
+ //#region .build/vendor/scramble-core/src/solvers/sq12phase/shape.ts
2
+ const N_SHAPES = 3678;
3
+ const N_SHAPE_STATES = N_SHAPES * 2;
4
+ const FACE_TURN_METRIC = 0;
5
+ const WCA_TURN_METRIC = 1;
6
+ const SEARCH_METRIC = WCA_TURN_METRIC;
7
+ const HALF_LAYER = [
8
+ 0,
9
+ 3,
10
+ 6,
11
+ 12,
12
+ 15,
13
+ 24,
14
+ 27,
15
+ 30,
16
+ 48,
17
+ 51,
18
+ 54,
19
+ 60,
20
+ 63
21
+ ];
22
+ const SOLVED_SHAPE_WITH_PARITY = 7191990;
23
+ let cachedTables;
24
+ var ShapeCoordinate = class {
25
+ top = 0;
26
+ bottom = 0;
27
+ parity = 0;
28
+ constructor(shapeIdx) {
29
+ this.shapeIdx = shapeIdx;
30
+ }
31
+ getIdx() {
32
+ return getShape2IdxFrom(this.shapeIdx, this.parity << 24 | this.top << 12 | this.bottom);
33
+ }
34
+ setIdx(index) {
35
+ this.parity = index & 1;
36
+ this.top = this.shapeIdx[index >> 1];
37
+ this.bottom = this.top & 4095;
38
+ this.top >>= 12;
39
+ }
40
+ topMove() {
41
+ let move = 0;
42
+ let moveParity = 0;
43
+ do {
44
+ if ((this.top & 2048) === 0) {
45
+ move += 1;
46
+ this.top <<= 1;
47
+ } else {
48
+ move += 2;
49
+ this.top = this.top << 2 ^ 12291;
50
+ }
51
+ moveParity = 1 - moveParity;
52
+ } while ((popCount(this.top & 63) & 1) !== 0);
53
+ if ((popCount(this.top) & 2) === 0) this.parity ^= moveParity;
54
+ return move;
55
+ }
56
+ bottomMove() {
57
+ let move = 0;
58
+ let moveParity = 0;
59
+ do {
60
+ if ((this.bottom & 2048) === 0) {
61
+ move += 1;
62
+ this.bottom <<= 1;
63
+ } else {
64
+ move += 2;
65
+ this.bottom = this.bottom << 2 ^ 12291;
66
+ }
67
+ moveParity = 1 - moveParity;
68
+ } while ((popCount(this.bottom & 63) & 1) !== 0);
69
+ if ((popCount(this.bottom) & 2) === 0) this.parity ^= moveParity;
70
+ return move;
71
+ }
72
+ twistMove() {
73
+ const topSlice = this.top & 63;
74
+ const topSliceCorners = popCount(topSlice);
75
+ const bottomSliceCorners = popCount(this.bottom & 4032);
76
+ this.parity ^= 1 & (topSliceCorners & bottomSliceCorners) >> 1;
77
+ this.top = this.top & 4032 | this.bottom >> 6 & 63;
78
+ this.bottom = this.bottom & 63 | topSlice << 6;
79
+ }
80
+ };
81
+ const getShape2Idx = (shapeWithParity) => getShape2IdxFrom(getShapeTables().shapeIdx, shapeWithParity);
82
+ const getShapeTables = () => {
83
+ cachedTables ??= createShapeTables();
84
+ return cachedTables;
85
+ };
86
+ const createShapeTables = () => {
87
+ const shapeIdx = createShapeIndex();
88
+ const topMove = new Int32Array(N_SHAPE_STATES);
89
+ const bottomMove = new Int32Array(N_SHAPE_STATES);
90
+ const twistMove = new Int32Array(N_SHAPE_STATES);
91
+ const shape = new ShapeCoordinate(shapeIdx);
92
+ for (let index = 0; index < N_SHAPE_STATES; index += 1) {
93
+ shape.setIdx(index);
94
+ topMove[index] = shape.topMove() | shape.getIdx() << 4;
95
+ shape.setIdx(index);
96
+ bottomMove[index] = shape.bottomMove() | shape.getIdx() << 4;
97
+ shape.setIdx(index);
98
+ shape.twistMove();
99
+ twistMove[index] = shape.getIdx();
100
+ }
101
+ const shapePrun = new Int8Array(N_SHAPE_STATES);
102
+ const shapePrunOpt = new Int8Array(N_SHAPE_STATES);
103
+ shapePrun.fill(-1);
104
+ shapePrunOpt.fill(-1);
105
+ shapePrun[getShape2IdxFrom(shapeIdx, 14378715)] = 0;
106
+ shapePrun[getShape2IdxFrom(shapeIdx, 31157686)] = 0;
107
+ shapePrun[getShape2IdxFrom(shapeIdx, 23967451)] = 0;
108
+ shapePrun[getShape2IdxFrom(shapeIdx, 7191990)] = 0;
109
+ shapePrunOpt[getShape2IdxFrom(shapeIdx, SOLVED_SHAPE_WITH_PARITY)] = 0;
110
+ const tables = {
111
+ shapeIdx,
112
+ shapePrun,
113
+ shapePrunOpt,
114
+ topMove,
115
+ bottomMove,
116
+ twistMove
117
+ };
118
+ initPruning(tables, shapePrun, 4, FACE_TURN_METRIC);
119
+ initPruning(tables, shapePrunOpt, 1, SEARCH_METRIC);
120
+ return tables;
121
+ };
122
+ const createShapeIndex = () => {
123
+ const shapeIdx = new Int32Array(N_SHAPES);
124
+ let count = 0;
125
+ for (let index = 0; index < 2197 * 13; index += 1) {
126
+ const dr = HALF_LAYER[index % 13];
127
+ const dl = HALF_LAYER[Math.floor(index / 13) % 13];
128
+ const ur = HALF_LAYER[Math.floor(index / 13 / 13) % 13];
129
+ const value = HALF_LAYER[Math.floor(index / 13 / 13 / 13)] << 18 | ur << 12 | dl << 6 | dr;
130
+ if (popCount(value) === 16) {
131
+ shapeIdx[count] = value;
132
+ count += 1;
133
+ }
134
+ }
135
+ return shapeIdx;
136
+ };
137
+ const initPruning = (tables, pruning, doneStart, metric) => {
138
+ let done = doneStart;
139
+ let previousDone = 0;
140
+ let depth = -1;
141
+ while (done !== previousDone) {
142
+ previousDone = done;
143
+ depth += 1;
144
+ for (let index = 0; index < N_SHAPE_STATES; index += 1) {
145
+ if (pruning[index] !== depth) continue;
146
+ const twisted = tables.twistMove[index];
147
+ if (pruning[twisted] === -1) {
148
+ done += 1;
149
+ pruning[twisted] = depth + 1;
150
+ }
151
+ if (metric === FACE_TURN_METRIC) {
152
+ for (let move = 0, increment = 0, next = index; move !== 12; move += increment) {
153
+ const moved = tables.topMove[next];
154
+ increment = moved & 15;
155
+ next = moved >> 4;
156
+ if (pruning[next] === -1) {
157
+ done += 1;
158
+ pruning[next] = depth + 1;
159
+ }
160
+ }
161
+ for (let move = 0, increment = 0, next = index; move !== 12; move += increment) {
162
+ const moved = tables.bottomMove[next];
163
+ increment = moved & 15;
164
+ next = moved >> 4;
165
+ if (pruning[next] === -1) {
166
+ done += 1;
167
+ pruning[next] = depth + 1;
168
+ }
169
+ }
170
+ } else if (metric === WCA_TURN_METRIC) for (let move = 0, increment = 0, next = index; move !== 12; move += increment) {
171
+ const movedTop = tables.topMove[next];
172
+ increment = movedTop & 15;
173
+ next = movedTop >> 4;
174
+ for (let bottomMove = 0, bottomIncrement = 0, bottomNext = next; bottomMove !== 12; bottomMove += bottomIncrement) {
175
+ const movedBottom = tables.bottomMove[bottomNext];
176
+ bottomIncrement = movedBottom & 15;
177
+ bottomNext = movedBottom >> 4;
178
+ if (pruning[bottomNext] === -1) {
179
+ done += 1;
180
+ pruning[bottomNext] = depth + 1;
181
+ }
182
+ }
183
+ }
184
+ }
185
+ }
186
+ };
187
+ const getShape2IdxFrom = (shapeIdx, shapeWithParity) => {
188
+ const index = binarySearch(shapeIdx, shapeWithParity & 16777215);
189
+ if (index < 0) throw new RangeError("@cubegin/scramble-core: invalid Square-1 shape coordinate");
190
+ return index << 1 | shapeWithParity >> 24 & 1;
191
+ };
192
+ const binarySearch = (values, target) => {
193
+ let low = 0;
194
+ let high = values.length - 1;
195
+ while (low <= high) {
196
+ const middle = low + high >> 1;
197
+ const value = values[middle];
198
+ if (value < target) low = middle + 1;
199
+ else if (value > target) high = middle - 1;
200
+ else return middle;
201
+ }
202
+ return -1;
203
+ };
204
+ const popCount = (value) => {
205
+ let remaining = value >>> 0;
206
+ let count = 0;
207
+ while (remaining !== 0) {
208
+ remaining &= remaining - 1;
209
+ count += 1;
210
+ }
211
+ return count;
212
+ };
213
+ //#endregion
214
+ export { getShape2Idx, getShapeTables, popCount };
@@ -0,0 +1,135 @@
1
+ //#region .build/vendor/scramble-core/src/solvers/sq12phase/square.ts
2
+ const N_PERMUTATIONS = 40320;
3
+ const N_MIDDLE_LAYER_STATES = N_PERMUTATIONS * 2;
4
+ const FACTORIAL = [
5
+ 1,
6
+ 1,
7
+ 2,
8
+ 6,
9
+ 24,
10
+ 120,
11
+ 720,
12
+ 5040
13
+ ];
14
+ let cachedTables;
15
+ const createSquareCoordinate = () => ({
16
+ edgePerm: 0,
17
+ cornPerm: 0,
18
+ topEdgeFirst: false,
19
+ botEdgeFirst: false,
20
+ ml: 0
21
+ });
22
+ const set8Perm = (pieces, permutation) => {
23
+ let remaining = permutation;
24
+ let value = 1985229328;
25
+ for (let index = 0; index < 7; index += 1) {
26
+ const factorial = FACTORIAL[7 - index];
27
+ let piece = Math.floor(remaining / factorial);
28
+ remaining -= piece * factorial;
29
+ piece <<= 2;
30
+ pieces[index] = value >> piece & 7;
31
+ const mask = (1 << piece) - 1;
32
+ value = (value & mask) + (value >> 4 & ~mask);
33
+ }
34
+ pieces[7] = value;
35
+ };
36
+ const get8Perm = (pieces) => {
37
+ let permutation = 0;
38
+ let value = 1985229328;
39
+ for (let index = 0; index < 7; index += 1) {
40
+ const piece = pieces[index] << 2;
41
+ permutation = (8 - index) * permutation + (value >> piece & 7);
42
+ value -= 286331152 << piece;
43
+ }
44
+ return permutation;
45
+ };
46
+ const createMoveTables = () => {
47
+ const twistMove = new Uint16Array(N_PERMUTATIONS);
48
+ const topMove = new Uint16Array(N_PERMUTATIONS);
49
+ const bottomMove = new Uint16Array(N_PERMUTATIONS);
50
+ const pieces = Array.from({ length: 8 }, () => 0);
51
+ for (let permutation = 0; permutation < N_PERMUTATIONS; permutation += 1) {
52
+ set8Perm(pieces, permutation);
53
+ swap(pieces, 2, 4);
54
+ swap(pieces, 3, 5);
55
+ twistMove[permutation] = get8Perm(pieces);
56
+ set8Perm(pieces, permutation);
57
+ const topPiece = pieces[0];
58
+ pieces[0] = pieces[1];
59
+ pieces[1] = pieces[2];
60
+ pieces[2] = pieces[3];
61
+ pieces[3] = topPiece;
62
+ topMove[permutation] = get8Perm(pieces);
63
+ set8Perm(pieces, permutation);
64
+ const bottomPiece = pieces[4];
65
+ pieces[4] = pieces[5];
66
+ pieces[5] = pieces[6];
67
+ pieces[6] = pieces[7];
68
+ pieces[7] = bottomPiece;
69
+ bottomMove[permutation] = get8Perm(pieces);
70
+ }
71
+ return {
72
+ twistMove,
73
+ topMove,
74
+ bottomMove
75
+ };
76
+ };
77
+ const createPruningTable = ({ twistMove, topMove, bottomMove }) => {
78
+ const squarePrun = new Int8Array(N_MIDDLE_LAYER_STATES);
79
+ squarePrun.fill(-1);
80
+ squarePrun[0] = 0;
81
+ let depth = 0;
82
+ let done = 1;
83
+ while (done < N_MIDDLE_LAYER_STATES) {
84
+ const inverseFill = depth >= 11;
85
+ const findValue = inverseFill ? -1 : depth;
86
+ const checkValue = inverseFill ? depth : -1;
87
+ depth += 1;
88
+ for (let index = 0; index < N_MIDDLE_LAYER_STATES; index += 1) {
89
+ if (squarePrun[index] !== findValue) continue;
90
+ const ml = index & 1;
91
+ let permutation = index >> 1;
92
+ const twisted = twistMove[permutation] << 1 | 1 - ml;
93
+ if (squarePrun[twisted] === checkValue) {
94
+ done += 1;
95
+ squarePrun[inverseFill ? index : twisted] = depth;
96
+ if (inverseFill) continue;
97
+ }
98
+ for (let move = 0; move < 4; move += 1) {
99
+ permutation = topMove[permutation];
100
+ const moved = permutation << 1 | ml;
101
+ if (squarePrun[moved] !== checkValue) continue;
102
+ done += 1;
103
+ squarePrun[inverseFill ? index : moved] = depth;
104
+ if (inverseFill) break;
105
+ }
106
+ if (inverseFill && squarePrun[index] !== findValue) continue;
107
+ for (let move = 0; move < 4; move += 1) {
108
+ permutation = bottomMove[permutation];
109
+ const moved = permutation << 1 | ml;
110
+ if (squarePrun[moved] !== checkValue) continue;
111
+ done += 1;
112
+ squarePrun[inverseFill ? index : moved] = depth;
113
+ if (inverseFill) break;
114
+ }
115
+ }
116
+ }
117
+ return squarePrun;
118
+ };
119
+ const getSquareTables = () => {
120
+ cachedTables ??= (() => {
121
+ const moveTables = createMoveTables();
122
+ return {
123
+ ...moveTables,
124
+ squarePrun: createPruningTable(moveTables)
125
+ };
126
+ })();
127
+ return cachedTables;
128
+ };
129
+ const swap = (pieces, first, second) => {
130
+ const piece = pieces[first];
131
+ pieces[first] = pieces[second];
132
+ pieces[second] = piece;
133
+ };
134
+ //#endregion
135
+ export { createSquareCoordinate, get8Perm, getSquareTables };