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,21 @@
1
+ import { axisForRestriction, isAxisRestriction, splitAlgorithm } from "./util.mjs";
2
+ import { Search } from "./search.mjs";
3
+ //#region .build/vendor/scramble-core/src/solvers/min2phase/search-wca.ts
4
+ var SearchWCA = class extends Search {
5
+ solution(facelets, maxDepth, probeMax, probeMin, verbose, firstAxisRestriction, lastAxisRestriction) {
6
+ if (!isValidRestriction(firstAxisRestriction)) return "Error 9";
7
+ if (!isValidRestriction(lastAxisRestriction)) return "Error 9";
8
+ const solution = super.solution(facelets, maxDepth, probeMax, probeMin, verbose);
9
+ if (solution.startsWith("Error")) return solution;
10
+ const moves = splitAlgorithm(solution);
11
+ if (violatesAxisRestriction(moves[0], firstAxisRestriction) || violatesAxisRestriction(moves.at(-1), lastAxisRestriction)) return "Error 7";
12
+ return solution;
13
+ }
14
+ };
15
+ const isValidRestriction = (restriction) => restriction === null || restriction === void 0 || isAxisRestriction(restriction);
16
+ const violatesAxisRestriction = (move, restriction) => {
17
+ if (move === void 0 || restriction === null || restriction === void 0) return false;
18
+ return axisForRestriction(move[0]) === axisForRestriction(restriction);
19
+ };
20
+ //#endregion
21
+ export { SearchWCA };
@@ -0,0 +1,25 @@
1
+ import { solve } from "./engine.mjs";
2
+ import { initCoordCube } from "./coord-cube.mjs";
3
+ import { invertAlgorithm } from "./util.mjs";
4
+ import { CubieCube } from "./cubie-cube.mjs";
5
+ //#region .build/vendor/scramble-core/src/solvers/min2phase/search.ts
6
+ var Search = class {
7
+ static init() {
8
+ initCoordCube();
9
+ }
10
+ solution(facelets, maxDepth, _probeMax, _probeMin, verbose) {
11
+ if (!Number.isSafeInteger(maxDepth) || maxDepth < 0) return "Error 7";
12
+ initCoordCube();
13
+ const cube = CubieCube.fromFaceCube(facelets);
14
+ if (cube === null) return "Error 1";
15
+ const verification = cube.verify();
16
+ if (verification !== 0) return `Error ${Math.abs(verification)}`;
17
+ const solution = solve(cube).trim();
18
+ if (solution.startsWith("Error")) return solution;
19
+ if ((solution.length === 0 ? [] : solution.split(/\s+/)).length > maxDepth) return "Error 7";
20
+ if ((verbose & 8) !== 0) return "Error 7";
21
+ return (verbose & 2) === 0 ? invertAlgorithm(solution) : solution;
22
+ }
23
+ };
24
+ //#endregion
25
+ export { Search };
@@ -0,0 +1,169 @@
1
+ import { drawRandomInt } from "./util.mjs";
2
+ import { CubieCube, getNParity, getNPerm } from "./cubie-cube.mjs";
3
+ //#region .build/vendor/scramble-core/src/solvers/min2phase/tools.ts
4
+ const STATE_RANDOM = null;
5
+ const STATE_SOLVED = [];
6
+ const randomCube = (random) => randomState(STATE_RANDOM, STATE_RANDOM, STATE_RANDOM, STATE_RANDOM, random);
7
+ const randomState = (cornerPermutation, cornerOrientation, edgePermutation, edgeOrientation, random) => {
8
+ const epUnknownCount = edgePermutation === STATE_RANDOM ? 12 : countUnknown(edgePermutation);
9
+ const cpUnknownCount = cornerPermutation === STATE_RANDOM ? 8 : countUnknown(cornerPermutation);
10
+ let parity;
11
+ let cpValue;
12
+ let epValue;
13
+ if (epUnknownCount < 2) {
14
+ if (edgePermutation === STATE_SOLVED) {
15
+ epValue = 0;
16
+ parity = 0;
17
+ } else if (edgePermutation !== STATE_RANDOM) {
18
+ const resolvedEp = materializeState(edgePermutation, 12);
19
+ parity = resolvePerm(resolvedEp, epUnknownCount, -1, random);
20
+ epValue = getNPerm(resolvedEp, 12);
21
+ } else throw new Error("@cubegin/scramble-core: invalid random edge state");
22
+ if (cornerPermutation === STATE_SOLVED) cpValue = 0;
23
+ else if (cornerPermutation === STATE_RANDOM) cpValue = drawRandomPermutationWithParity(random, 40320, 8, parity);
24
+ else {
25
+ const resolvedCp = materializeState(cornerPermutation, 8);
26
+ resolvePerm(resolvedCp, cpUnknownCount, parity, random);
27
+ cpValue = getNPerm(resolvedCp, 8);
28
+ }
29
+ } else {
30
+ if (cornerPermutation === STATE_SOLVED) {
31
+ cpValue = 0;
32
+ parity = 0;
33
+ } else if (cornerPermutation === STATE_RANDOM) {
34
+ cpValue = drawRandomInt(random, 40320);
35
+ parity = getNParity(cpValue, 8);
36
+ } else {
37
+ const resolvedCp = materializeState(cornerPermutation, 8);
38
+ parity = resolvePerm(resolvedCp, cpUnknownCount, -1, random);
39
+ cpValue = getNPerm(resolvedCp, 8);
40
+ }
41
+ if (edgePermutation === STATE_RANDOM) epValue = drawRandomPermutationWithParity(random, 479001600, 12, parity);
42
+ else {
43
+ const resolvedEp = materializeState(edgePermutation, 12);
44
+ resolvePerm(resolvedEp, epUnknownCount, parity, random);
45
+ epValue = getNPerm(resolvedEp, 12);
46
+ }
47
+ }
48
+ return CubieCube.fromCoordinates(cpValue, cornerOrientation === STATE_RANDOM ? drawRandomInt(random, 2187) : cornerOrientation === STATE_SOLVED ? 0 : resolveOri(materializeState(cornerOrientation, 8), 3, random), epValue, edgeOrientation === STATE_RANDOM ? drawRandomInt(random, 2048) : edgeOrientation === STATE_SOLVED ? 0 : resolveOri(materializeState(edgeOrientation, 12), 2, random)).toFaceCube();
49
+ };
50
+ const drawRandomPermutationWithParity = (random, maxExclusive, pieceCount, parity) => {
51
+ const permutationValue = drawRandomInt(random, maxExclusive);
52
+ return getNParity(permutationValue, pieceCount) === parity ? permutationValue : flipPermutationParity(permutationValue, pieceCount);
53
+ };
54
+ const flipPermutationParity = (permutationValue, pieceCount) => {
55
+ const permutation = permutationFromIndex(permutationValue, pieceCount);
56
+ const first = permutation[0] ?? 0;
57
+ permutation[0] = permutation[1] ?? 0;
58
+ permutation[1] = first;
59
+ return getNPerm(permutation, pieceCount);
60
+ };
61
+ const permutationFromIndex = (permutationValue, pieceCount) => {
62
+ const permutation = Array(pieceCount);
63
+ let index = permutationValue;
64
+ for (let i = pieceCount - 1; i >= 0; i -= 1) {
65
+ permutation[i] = index % (pieceCount - i);
66
+ index = Math.floor(index / (pieceCount - i));
67
+ for (let j = i + 1; j < pieceCount; j += 1) if ((permutation[j] ?? 0) >= (permutation[i] ?? 0)) permutation[j] = (permutation[j] ?? 0) + 1;
68
+ }
69
+ return permutation;
70
+ };
71
+ const resolveOri = (orientations, base, random) => {
72
+ let sum = 0;
73
+ let index = 0;
74
+ let lastUnknown = -1;
75
+ for (let i = 0; i < orientations.length; i += 1) {
76
+ if (orientations[i] === -1) {
77
+ orientations[i] = drawRandomInt(random, base);
78
+ lastUnknown = i;
79
+ }
80
+ sum += orientations[i] ?? 0;
81
+ }
82
+ if (sum % base !== 0 && lastUnknown !== -1) orientations[lastUnknown] = (30 + (orientations[lastUnknown] ?? 0) - sum) % base;
83
+ for (let i = 0; i < orientations.length - 1; i += 1) {
84
+ index *= base;
85
+ index += orientations[i] ?? 0;
86
+ }
87
+ return index;
88
+ };
89
+ const countUnknown = (state) => {
90
+ if (state === STATE_SOLVED) return 0;
91
+ return state?.filter((value) => value === -1).length ?? 0;
92
+ };
93
+ const resolvePerm = (permutation, unknownCount, parity, random) => {
94
+ const available = Array.from({ length: permutation.length }, (_, index) => permutation.includes(index) ? -1 : index);
95
+ let shuffledCount = 0;
96
+ for (let i = 0; i < available.length; i += 1) {
97
+ if (available[i] === -1) continue;
98
+ const swapIndex = drawRandomInt(random, shuffledCount + 1);
99
+ const value = available[i] ?? -1;
100
+ available[i] = available[swapIndex] ?? -1;
101
+ available[shuffledCount] = value;
102
+ shuffledCount += 1;
103
+ }
104
+ let last = -1;
105
+ let cursor = 0;
106
+ let remainingUnknown = unknownCount;
107
+ while (cursor < permutation.length && remainingUnknown > 0) {
108
+ if (permutation[cursor] === -1) {
109
+ if (remainingUnknown === 2) last = cursor;
110
+ permutation[cursor] = available[remainingUnknown -= 1] ?? 0;
111
+ }
112
+ cursor += 1;
113
+ }
114
+ const resolvedParity = getNParity(getNPerm(permutation, permutation.length), permutation.length);
115
+ if (resolvedParity === 1 - parity && last !== -1) {
116
+ const swapIndex = cursor - 1;
117
+ const value = permutation[swapIndex] ?? 0;
118
+ permutation[swapIndex] = permutation[last] ?? 0;
119
+ permutation[last] = value;
120
+ }
121
+ return resolvedParity;
122
+ };
123
+ const materializeState = (state, length) => {
124
+ if (state === STATE_SOLVED) return Array.from({ length }, (_, index) => index);
125
+ return [...state];
126
+ };
127
+ const MOVE_CUBES = [
128
+ CubieCube.fromCoordinates(15120, 0, 119750400, 0),
129
+ CubieCube.solved(),
130
+ CubieCube.solved(),
131
+ CubieCube.fromCoordinates(21021, 1494, 323403417, 0),
132
+ CubieCube.solved(),
133
+ CubieCube.solved(),
134
+ CubieCube.fromCoordinates(8064, 1236, 29441808, 550),
135
+ CubieCube.solved(),
136
+ CubieCube.solved(),
137
+ CubieCube.fromCoordinates(9, 0, 5880, 0),
138
+ CubieCube.solved(),
139
+ CubieCube.solved(),
140
+ CubieCube.fromCoordinates(1230, 412, 2949660, 0),
141
+ CubieCube.solved(),
142
+ CubieCube.solved(),
143
+ CubieCube.fromCoordinates(224, 137, 328552, 137),
144
+ CubieCube.solved(),
145
+ CubieCube.solved()
146
+ ];
147
+ for (let axis = 0; axis < 18; axis += 3) {
148
+ MOVE_CUBES[axis + 1] = multiply(MOVE_CUBES[axis], MOVE_CUBES[axis]);
149
+ MOVE_CUBES[axis + 2] = multiply(MOVE_CUBES[axis + 1], MOVE_CUBES[axis]);
150
+ }
151
+ function multiply(left, right) {
152
+ const cp = Array(8);
153
+ const co = Array(8);
154
+ const ep = Array(12);
155
+ const eo = Array(12);
156
+ for (let corner = 0; corner < 8; corner += 1) {
157
+ const rightCorner = right.cp[corner] ?? 0;
158
+ cp[corner] = left.cp[rightCorner] ?? 0;
159
+ co[corner] = ((left.co[rightCorner] ?? 0) + (right.co[corner] ?? 0)) % 3;
160
+ }
161
+ for (let edge = 0; edge < 12; edge += 1) {
162
+ const rightEdge = right.ep[edge] ?? 0;
163
+ ep[edge] = left.ep[rightEdge] ?? 0;
164
+ eo[edge] = (right.eo[edge] ?? 0) ^ (left.eo[rightEdge] ?? 0);
165
+ }
166
+ return new CubieCube(cp, co, ep, eo);
167
+ }
168
+ //#endregion
169
+ export { randomCube };
@@ -0,0 +1,30 @@
1
+ //#region .build/vendor/scramble-core/src/solvers/min2phase/util.ts
2
+ const SOLVED_FACE_CUBE = "UUUUUUUUURRRRRRRRRFFFFFFFFFDDDDDDDDDLLLLLLLLLBBBBBBBBB";
3
+ const FACE_AXIS = {
4
+ U: 0,
5
+ D: 0,
6
+ R: 1,
7
+ L: 1,
8
+ F: 2,
9
+ B: 2
10
+ };
11
+ const axisForRestriction = (restriction) => {
12
+ if (restriction === void 0) return void 0;
13
+ return FACE_AXIS[restriction];
14
+ };
15
+ const isAxisRestriction = (restriction) => restriction !== void 0 && axisForRestriction(restriction) !== void 0;
16
+ const splitAlgorithm = (algorithm) => algorithm.trim().length === 0 ? [] : algorithm.trim().split(/\s+/);
17
+ const invertAlgorithm = (algorithm) => splitAlgorithm(algorithm).reverse().map(invertMove).join(" ");
18
+ const drawRandomInt = (random, maxExclusive) => {
19
+ if (!Number.isSafeInteger(maxExclusive) || maxExclusive <= 0) throw new RangeError("@cubegin/scramble-core: random maxExclusive must be a positive safe integer");
20
+ const value = random.nextInt(maxExclusive);
21
+ if (!Number.isSafeInteger(value) || value < 0 || value >= maxExclusive) throw new RangeError(`@cubegin/scramble-core: random source returned ${value} for max ${maxExclusive}`);
22
+ return value;
23
+ };
24
+ const invertMove = (move) => {
25
+ if (move.endsWith("2")) return move;
26
+ if (move.endsWith("'")) return move.slice(0, -1);
27
+ return `${move}'`;
28
+ };
29
+ //#endregion
30
+ export { SOLVED_FACE_CUBE, axisForRestriction, drawRandomInt, invertAlgorithm, isAxisRestriction, splitAlgorithm };
@@ -0,0 +1,17 @@
1
+ import { RandomSource } from "../random-source.mjs";
2
+
3
+ //#region .build/vendor/scramble-core/src/solvers/pyraminx-solver.d.ts
4
+ interface PyraminxSolverState {
5
+ readonly edgePerm: number;
6
+ readonly edgeOrient: number;
7
+ readonly cornerOrient: number;
8
+ readonly tips: number;
9
+ }
10
+ declare class PyraminxSolver {
11
+ randomState(random: RandomSource): PyraminxSolverState;
12
+ solveIn(state: PyraminxSolverState, maxLength: number, includingTips: boolean, random: RandomSource): string | null;
13
+ generateExactly(state: PyraminxSolverState, length: number, includingTips: boolean, random: RandomSource): string;
14
+ private solve;
15
+ }
16
+ //#endregion
17
+ export { PyraminxSolver, PyraminxSolverState };
@@ -0,0 +1,350 @@
1
+ //#region .build/vendor/scramble-core/src/solvers/pyraminx-solver.ts
2
+ const ERROR_PREFIX = "@cubegin/scramble-core";
3
+ const N_EDGE_PERM = 720;
4
+ const N_EDGE_ORIENT = 32;
5
+ const N_CORNER_ORIENT = 81;
6
+ const N_ORIENT = N_EDGE_ORIENT * N_CORNER_ORIENT;
7
+ const N_TIPS = 81;
8
+ const N_MOVES = 8;
9
+ const MAX_LENGTH = 20;
10
+ const MAX_EDGE_PERM_ATTEMPTS = 100;
11
+ const MOVE_TO_STRING = [
12
+ "U",
13
+ "U'",
14
+ "L",
15
+ "L'",
16
+ "R",
17
+ "R'",
18
+ "B",
19
+ "B'"
20
+ ];
21
+ const INVERSE_MOVE_TO_STRING = [
22
+ "U'",
23
+ "U",
24
+ "L'",
25
+ "L",
26
+ "R'",
27
+ "R",
28
+ "B'",
29
+ "B"
30
+ ];
31
+ const TIP_TO_STRING = [
32
+ "u",
33
+ "u'",
34
+ "l",
35
+ "l'",
36
+ "r",
37
+ "r'",
38
+ "b",
39
+ "b'"
40
+ ];
41
+ const INVERSE_TIP_TO_STRING = [
42
+ "u'",
43
+ "u",
44
+ "l'",
45
+ "l",
46
+ "r'",
47
+ "r",
48
+ "b'",
49
+ "b"
50
+ ];
51
+ const FACT = [
52
+ 1,
53
+ 1,
54
+ 2,
55
+ 6,
56
+ 24,
57
+ 120,
58
+ 720
59
+ ];
60
+ let cachedTables;
61
+ const packEdgePerm = (edges) => {
62
+ let index = 0;
63
+ let value = 5517840;
64
+ for (let position = 0; position < 5; position += 1) {
65
+ const shiftedEdge = (edges[position] & 7) << 2;
66
+ index = (6 - position) * index + (value >> shiftedEdge & 7);
67
+ value -= 1118480 << shiftedEdge;
68
+ }
69
+ return index;
70
+ };
71
+ const unpackEdgePerm = (permutation, edges) => {
72
+ let remaining = permutation;
73
+ let value = 5517840;
74
+ for (let position = 0; position < 5; position += 1) {
75
+ const divisor = FACT[5 - position];
76
+ let edge = Math.floor(remaining / divisor);
77
+ remaining -= edge * divisor;
78
+ edge <<= 2;
79
+ edges[position] = value >> edge & 7;
80
+ const mask = (1 << edge) - 1;
81
+ value = (value & mask) + (value >> 4 & ~mask);
82
+ }
83
+ edges[5] = value;
84
+ };
85
+ const packEdgeOrient = (edges) => {
86
+ let orientation = 0;
87
+ for (let position = 0; position < 5; position += 1) orientation = 2 * orientation + (edges[position] >> 3);
88
+ return orientation;
89
+ };
90
+ const unpackEdgeOrient = (orientation, edges) => {
91
+ let remaining = orientation;
92
+ let orientationSum = 0;
93
+ for (let position = 4; position >= 0; position -= 1) {
94
+ const edgeOrientation = remaining & 1;
95
+ edges[position] = edgeOrientation << 3;
96
+ orientationSum ^= edgeOrientation;
97
+ remaining >>= 1;
98
+ }
99
+ edges[5] = orientationSum << 3;
100
+ };
101
+ const packCornerOrient = (corners) => {
102
+ let orientation = 0;
103
+ for (let position = 0; position < 4; position += 1) orientation = 3 * orientation + corners[position];
104
+ return orientation;
105
+ };
106
+ const unpackCornerOrient = (orientation, corners) => {
107
+ let remaining = orientation;
108
+ for (let position = 3; position >= 0; position -= 1) {
109
+ corners[position] = remaining % 3;
110
+ remaining = Math.floor(remaining / 3);
111
+ }
112
+ };
113
+ const cycleAndOrient = (edges, first, second, third, times) => {
114
+ for (let count = 0; count < times; count += 1) {
115
+ const savedThird = edges[third];
116
+ edges[third] = (edges[second] + 8) % 16;
117
+ edges[second] = (edges[first] + 8) % 16;
118
+ edges[first] = savedThird;
119
+ }
120
+ };
121
+ const moveEdges = (edges, move) => {
122
+ const face = Math.floor(move / 2);
123
+ const times = move % 2 + 1;
124
+ switch (face) {
125
+ case 0:
126
+ cycleAndOrient(edges, 5, 3, 1, times);
127
+ break;
128
+ case 1:
129
+ cycleAndOrient(edges, 2, 1, 0, times);
130
+ break;
131
+ case 2:
132
+ cycleAndOrient(edges, 0, 3, 4, times);
133
+ break;
134
+ case 3:
135
+ cycleAndOrient(edges, 2, 4, 5, times);
136
+ break;
137
+ }
138
+ };
139
+ const moveCorners = (corners, move) => {
140
+ const face = Math.floor(move / 2);
141
+ const times = move % 2 + 1;
142
+ corners[face] = (corners[face] + times) % 3;
143
+ };
144
+ const copyCubies = (source, target) => {
145
+ for (let index = 0; index < source.length; index += 1) target[index] = source[index];
146
+ };
147
+ const createMoveTables = () => {
148
+ const moveEdgePerm = Array.from({ length: N_EDGE_PERM }, () => new Uint16Array(N_MOVES));
149
+ const moveEdgeOrient = Array.from({ length: N_EDGE_ORIENT }, () => new Uint8Array(N_MOVES));
150
+ const moveCornerOrient = Array.from({ length: N_CORNER_ORIENT }, () => new Uint8Array(N_MOVES));
151
+ const edges = Array.from({ length: 6 }, () => 0);
152
+ const movedEdges = Array.from({ length: 6 }, () => 0);
153
+ const corners = Array.from({ length: 4 }, () => 0);
154
+ const movedCorners = Array.from({ length: 4 }, () => 0);
155
+ for (let permutation = 0; permutation < N_EDGE_PERM; permutation += 1) {
156
+ unpackEdgePerm(permutation, edges);
157
+ for (let move = 0; move < N_MOVES; move += 1) {
158
+ copyCubies(edges, movedEdges);
159
+ moveEdges(movedEdges, move);
160
+ moveEdgePerm[permutation][move] = packEdgePerm(movedEdges);
161
+ }
162
+ }
163
+ for (let orientation = 0; orientation < N_EDGE_ORIENT; orientation += 1) {
164
+ unpackEdgeOrient(orientation, edges);
165
+ for (let move = 0; move < N_MOVES; move += 1) {
166
+ copyCubies(edges, movedEdges);
167
+ moveEdges(movedEdges, move);
168
+ moveEdgeOrient[orientation][move] = packEdgeOrient(movedEdges);
169
+ }
170
+ }
171
+ for (let orientation = 0; orientation < N_CORNER_ORIENT; orientation += 1) {
172
+ unpackCornerOrient(orientation, corners);
173
+ for (let move = 0; move < N_MOVES; move += 1) {
174
+ copyCubies(corners, movedCorners);
175
+ moveCorners(movedCorners, move);
176
+ moveCornerOrient[orientation][move] = packCornerOrient(movedCorners);
177
+ }
178
+ }
179
+ return {
180
+ moveEdgePerm,
181
+ moveEdgeOrient,
182
+ moveCornerOrient
183
+ };
184
+ };
185
+ const createPermutationPruningTable = (moveEdgePerm) => {
186
+ const pruning = new Int8Array(N_EDGE_PERM);
187
+ pruning.fill(-1);
188
+ pruning[0] = 0;
189
+ let done = 1;
190
+ for (let length = 0; done < N_EDGE_PERM / 2; length += 1) for (let permutation = 0; permutation < N_EDGE_PERM; permutation += 1) {
191
+ if (pruning[permutation] !== length) continue;
192
+ for (let move = 0; move < N_MOVES; move += 1) {
193
+ const nextPermutation = moveEdgePerm[permutation][move];
194
+ if (pruning[nextPermutation] !== -1) continue;
195
+ pruning[nextPermutation] = length + 1;
196
+ done += 1;
197
+ }
198
+ }
199
+ return pruning;
200
+ };
201
+ const createOrientationPruningTable = (moveEdgeOrient, moveCornerOrient) => {
202
+ const pruning = new Int8Array(N_ORIENT);
203
+ pruning.fill(-1);
204
+ pruning[0] = 0;
205
+ let done = 1;
206
+ for (let length = 0; done < N_ORIENT; length += 1) for (let orientation = 0; orientation < N_ORIENT; orientation += 1) {
207
+ if (pruning[orientation] !== length) continue;
208
+ for (let move = 0; move < N_MOVES; move += 1) {
209
+ const nextEdgeOrient = moveEdgeOrient[orientation % N_EDGE_ORIENT][move];
210
+ const nextOrientation = moveCornerOrient[Math.floor(orientation / N_EDGE_ORIENT)][move] * N_EDGE_ORIENT + nextEdgeOrient;
211
+ if (pruning[nextOrientation] !== -1) continue;
212
+ pruning[nextOrientation] = length + 1;
213
+ done += 1;
214
+ }
215
+ }
216
+ return pruning;
217
+ };
218
+ const createTables = () => {
219
+ const { moveEdgePerm, moveEdgeOrient, moveCornerOrient } = createMoveTables();
220
+ return {
221
+ moveEdgePerm,
222
+ moveEdgeOrient,
223
+ moveCornerOrient,
224
+ prunPerm: createPermutationPruningTable(moveEdgePerm),
225
+ prunOrient: createOrientationPruningTable(moveEdgeOrient, moveCornerOrient)
226
+ };
227
+ };
228
+ const getTables = () => {
229
+ cachedTables ??= createTables();
230
+ return cachedTables;
231
+ };
232
+ const validateCoordinate = (coordinateName, coordinate, maxExclusive) => {
233
+ if (!Number.isSafeInteger(coordinate) || coordinate < 0 || coordinate >= maxExclusive) throw new RangeError(`${ERROR_PREFIX}: Pyraminx ${coordinateName} must be an integer from 0 to ${maxExclusive - 1}`);
234
+ };
235
+ const validateState = (state) => {
236
+ validateCoordinate("edgePerm", state.edgePerm, N_EDGE_PERM);
237
+ validateCoordinate("edgeOrient", state.edgeOrient, N_EDGE_ORIENT);
238
+ validateCoordinate("cornerOrient", state.cornerOrient, N_CORNER_ORIENT);
239
+ validateCoordinate("tips", state.tips, N_TIPS);
240
+ };
241
+ const validateLength = (length) => {
242
+ if (!Number.isSafeInteger(length) || length < 0 || length > MAX_LENGTH) throw new RangeError(`${ERROR_PREFIX}: Pyraminx solve length must be an integer from 0 to ${MAX_LENGTH}`);
243
+ };
244
+ const nextCoordinate = (random, coordinateName, maxExclusive) => {
245
+ const coordinate = random.nextInt(maxExclusive);
246
+ validateCoordinate(coordinateName, coordinate, maxExclusive);
247
+ return coordinate;
248
+ };
249
+ const unsolvedTips = (tips) => {
250
+ let count = 0;
251
+ let remainingTips = tips;
252
+ while (remainingTips !== 0) {
253
+ if (remainingTips % 3 > 0) count += 1;
254
+ remainingTips = Math.floor(remainingTips / 3);
255
+ }
256
+ return count;
257
+ };
258
+ const search = ({ edgePerm, edgeOrient, cornerOrient, depth, length, lastMove, solution, random, tables }) => {
259
+ if (length === 0) return edgePerm === 0 && edgeOrient === 0 && cornerOrient === 0;
260
+ if (tables.prunPerm[edgePerm] > length || tables.prunOrient[cornerOrient * N_EDGE_ORIENT + edgeOrient] > length) return false;
261
+ const randomOffset = nextCoordinate(random, "searchMoveOffset", N_MOVES);
262
+ for (let move = 0; move < N_MOVES; move += 1) {
263
+ const randomMove = (move + randomOffset) % N_MOVES;
264
+ if (Math.floor(randomMove / 2) === Math.floor(lastMove / 2)) continue;
265
+ if (search({
266
+ edgePerm: tables.moveEdgePerm[edgePerm][randomMove],
267
+ edgeOrient: tables.moveEdgeOrient[edgeOrient][randomMove],
268
+ cornerOrient: tables.moveCornerOrient[cornerOrient][randomMove],
269
+ depth: depth + 1,
270
+ length: length - 1,
271
+ lastMove: randomMove,
272
+ solution,
273
+ random,
274
+ tables
275
+ })) {
276
+ solution[depth] = randomMove;
277
+ return true;
278
+ }
279
+ }
280
+ return false;
281
+ };
282
+ const formatSolution = (state, solution, length, inverse) => {
283
+ const moves = [];
284
+ if (inverse) for (let index = length - 1; index >= 0; index -= 1) moves.push(INVERSE_MOVE_TO_STRING[solution[index]]);
285
+ else for (let index = 0; index < length; index += 1) moves.push(MOVE_TO_STRING[solution[index]]);
286
+ const tips = Array.from({ length: 4 }, () => 0);
287
+ unpackCornerOrient(state.tips, tips);
288
+ for (let tip = 0; tip < 4; tip += 1) {
289
+ const direction = tips[tip];
290
+ if (direction === 0) continue;
291
+ const tipMove = tip * 2 + direction - 1;
292
+ moves.push(inverse ? TIP_TO_STRING[tipMove] : INVERSE_TIP_TO_STRING[tipMove]);
293
+ }
294
+ return moves.join(" ");
295
+ };
296
+ var PyraminxSolver = class {
297
+ randomState(random) {
298
+ const tables = getTables();
299
+ let edgePerm;
300
+ for (let attempt = 0; attempt < MAX_EDGE_PERM_ATTEMPTS; attempt += 1) {
301
+ const sampledEdgePerm = nextCoordinate(random, "edgePerm", N_EDGE_PERM);
302
+ if (tables.prunPerm[sampledEdgePerm] === -1) continue;
303
+ edgePerm = sampledEdgePerm;
304
+ break;
305
+ }
306
+ if (edgePerm === void 0) throw new Error(`${ERROR_PREFIX}: could not sample a reachable Pyraminx edge permutation after ${MAX_EDGE_PERM_ATTEMPTS} attempts`);
307
+ const state = {
308
+ edgePerm,
309
+ edgeOrient: nextCoordinate(random, "edgeOrient", N_EDGE_ORIENT),
310
+ cornerOrient: nextCoordinate(random, "cornerOrient", N_CORNER_ORIENT),
311
+ tips: nextCoordinate(random, "tips", N_TIPS)
312
+ };
313
+ validateState(state);
314
+ return state;
315
+ }
316
+ solveIn(state, maxLength, includingTips, random) {
317
+ return this.solve(state, maxLength, false, false, includingTips, random);
318
+ }
319
+ generateExactly(state, length, includingTips, random) {
320
+ const scramble = this.solve(state, length, true, true, includingTips, random);
321
+ if (scramble === null) throw new Error(`${ERROR_PREFIX}: could not generate a Pyraminx scramble exactly ${length} moves long`);
322
+ return scramble;
323
+ }
324
+ solve(state, desiredLength, exactLength, inverse, includingTips, random) {
325
+ validateState(state);
326
+ validateLength(desiredLength);
327
+ const mainMoveDesiredLength = includingTips ? desiredLength - unsolvedTips(state.tips) : desiredLength;
328
+ if (mainMoveDesiredLength < 0) return null;
329
+ const tables = getTables();
330
+ const solution = Array.from({ length: MAX_LENGTH }, () => 0);
331
+ let length = exactLength ? mainMoveDesiredLength : 0;
332
+ while (length <= mainMoveDesiredLength) {
333
+ if (search({
334
+ edgePerm: state.edgePerm,
335
+ edgeOrient: state.edgeOrient,
336
+ cornerOrient: state.cornerOrient,
337
+ depth: 0,
338
+ length,
339
+ lastMove: 42,
340
+ solution,
341
+ random,
342
+ tables
343
+ })) return formatSolution(state, solution, length, inverse);
344
+ length += 1;
345
+ }
346
+ return null;
347
+ }
348
+ };
349
+ //#endregion
350
+ export { PyraminxSolver };
@@ -0,0 +1,15 @@
1
+ import { RandomSource } from "../random-source.mjs";
2
+
3
+ //#region .build/vendor/scramble-core/src/solvers/skewb-solver.d.ts
4
+ interface SkewbSolverState {
5
+ readonly perm: number;
6
+ readonly twst: number;
7
+ }
8
+ declare class SkewbSolver {
9
+ randomState(random: RandomSource): SkewbSolverState;
10
+ solveIn(state: SkewbSolverState, length: number, random: RandomSource): string | null;
11
+ generateExactly(state: SkewbSolverState, length: number, random: RandomSource): string;
12
+ private solve;
13
+ }
14
+ //#endregion
15
+ export { SkewbSolver, SkewbSolverState };