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
package/NOTICE ADDED
@@ -0,0 +1,11 @@
1
+ cubegin
2
+
3
+ This package re-exports Cubegin TNoodle-compatible scramble packages:
4
+
5
+ - @cubegin/scramble-core
6
+ - @cubegin/scramble-image
7
+ - @cubegin/scramble-puzzle
8
+
9
+ Those packages port behavior from thewca/tnoodle-lib lib-scrambles v0.19.2,
10
+ which is distributed under GPL-v3.0. Cubegin is not an official WCA scramble
11
+ program.
package/README.md ADDED
@@ -0,0 +1,49 @@
1
+ # cubegin
2
+
3
+ Public Cubegin npm entrypoints for TNoodle-compatible scramble generation,
4
+ scramble SVG rendering, and puzzle notation/state helpers.
5
+
6
+ The package intentionally does not expose a root API. Import one of the
7
+ published subpaths instead:
8
+
9
+ ```ts
10
+ import { createDefaultScrambleGenerator } from 'cubegin/scramble-core';
11
+ import { renderScrambleImage } from 'cubegin/scramble-image';
12
+ import { WCA_EVENT_IDS } from 'cubegin/scramble-puzzle';
13
+ ```
14
+
15
+ ## Entrypoints
16
+
17
+ - `cubegin/scramble-core` bundles the `@cubegin/scramble-core` implementation.
18
+ - `cubegin/scramble-image` bundles the `@cubegin/scramble-image` implementation.
19
+ - `cubegin/scramble-puzzle` bundles the `@cubegin/scramble-puzzle` implementation.
20
+
21
+ The package root is reserved and not listed in `exports`.
22
+
23
+ ## Adding Entrypoints
24
+
25
+ Add a `cubegin.publicSubpath` field to the source package:
26
+
27
+ ```json
28
+ {
29
+ "cubegin": {
30
+ "publicSubpath": "scramble-core"
31
+ }
32
+ }
33
+ ```
34
+
35
+ `pnpm --filter cubegin build` scans those markers, syncs `exports`, vendors the
36
+ source package into a temporary build tree, and emits module-split ESM under
37
+ `dist`.
38
+
39
+ ## Development
40
+
41
+ ```bash
42
+ pnpm --filter cubegin test
43
+ pnpm --filter cubegin typecheck
44
+ pnpm --filter cubegin build
45
+ ```
46
+
47
+ ## License
48
+
49
+ GPL-3.0-only. See [`LICENSE`](./LICENSE) and [`NOTICE`](./NOTICE).
@@ -0,0 +1,18 @@
1
+ //#region .build/vendor/scramble-core/src/batch.ts
2
+ const ERROR_PREFIX = "@cubegin/scramble-core";
3
+ const generateUniqueScrambleBatch = async (count, generate, options = {}) => {
4
+ if (!Number.isSafeInteger(count) || count < 0) throw new Error(`${ERROR_PREFIX}: batch count must be a non-negative safe integer`);
5
+ const maxAttempts = options.maxAttempts ?? Math.max(count * 10, 100);
6
+ const results = [];
7
+ const seen = /* @__PURE__ */ new Set();
8
+ for (let attempts = 0; results.length < count && attempts < maxAttempts; attempts += 1) {
9
+ const scrambleResult = await generate();
10
+ if (seen.has(scrambleResult.scramble)) continue;
11
+ seen.add(scrambleResult.scramble);
12
+ results.push(scrambleResult);
13
+ }
14
+ if (results.length < count) throw new Error(`${ERROR_PREFIX}: generated ${results.length} unique scrambles after ${maxAttempts} attempts`);
15
+ return results;
16
+ };
17
+ //#endregion
18
+ export { generateUniqueScrambleBatch };
@@ -0,0 +1,35 @@
1
+ import { WcaEventId } from "../../scramble-puzzle/src/events.mjs";
2
+ import { RandomSource } from "./random-source.mjs";
3
+
4
+ //#region .build/vendor/scramble-core/src/generator.d.ts
5
+ interface GenerateOptions {
6
+ random?: RandomSource;
7
+ multiBlindCubeCount?: number;
8
+ }
9
+ interface ScrambleResult {
10
+ eventId: WcaEventId;
11
+ scramble: string;
12
+ }
13
+ type EventScrambleGenerator = (options: GenerateOptions & {
14
+ random: RandomSource;
15
+ }) => ScrambleResult | Promise<ScrambleResult>;
16
+ interface ScrambleGeneratorOptions {
17
+ random: RandomSource;
18
+ generators: Partial<Record<WcaEventId, EventScrambleGenerator>>;
19
+ }
20
+ interface DefaultScrambleGeneratorOptions {
21
+ random: RandomSource;
22
+ }
23
+ interface ScrambleGenerator {
24
+ generate(eventId: WcaEventId, options?: GenerateOptions): Promise<ScrambleResult>;
25
+ generateBatch(eventId: WcaEventId, count: number, options?: GenerateOptions): Promise<readonly ScrambleResult[]>;
26
+ }
27
+ declare const createScrambleGenerator: ({
28
+ random,
29
+ generators
30
+ }: ScrambleGeneratorOptions) => ScrambleGenerator;
31
+ declare const createDefaultScrambleGenerator: ({
32
+ random
33
+ }: DefaultScrambleGeneratorOptions) => ScrambleGenerator;
34
+ //#endregion
35
+ export { DefaultScrambleGeneratorOptions, EventScrambleGenerator, GenerateOptions, ScrambleGenerator, ScrambleGeneratorOptions, ScrambleResult, createDefaultScrambleGenerator, createScrambleGenerator };
@@ -0,0 +1,136 @@
1
+ import { generateUniqueScrambleBatch } from "./batch.mjs";
2
+ import { generateClockScramble } from "./generators/clock.mjs";
3
+ import { generateCubeRandomTurnScramble } from "./generators/cube-random-turns.mjs";
4
+ import { generateFourByFourNoInspectionScramble, generateFourByFourScramble } from "./generators/four-by-four.mjs";
5
+ import { generateMegaminxScramble } from "./generators/megaminx.mjs";
6
+ import { generatePyraminxScramble } from "./generators/pyraminx.mjs";
7
+ import { generateSkewbScramble } from "./generators/skewb.mjs";
8
+ import { generateSquareOneScramble } from "./generators/square1.mjs";
9
+ import { generateMultiBlindScramble, generateThreeByThreeFewestMovesScramble, generateThreeByThreeNoInspectionScramble, generateThreeByThreeScramble } from "./generators/three-by-three.mjs";
10
+ import { generateTwoByTwoScramble } from "./generators/two-by-two.mjs";
11
+ //#region .build/vendor/scramble-core/src/generator.ts
12
+ const ERROR_PREFIX = "@cubegin/scramble-core";
13
+ const createScrambleGenerator = ({ random, generators }) => {
14
+ const api = {
15
+ async generate(eventId, options = {}) {
16
+ const generator = generators[eventId];
17
+ if (!generator) throw new Error(`${ERROR_PREFIX}: event '${eventId}' has no generator`);
18
+ return await generator({
19
+ ...options,
20
+ random: options.random ?? random
21
+ });
22
+ },
23
+ async generateBatch(eventId, count, options = {}) {
24
+ return generateUniqueScrambleBatch(count, () => api.generate(eventId, options));
25
+ }
26
+ };
27
+ return api;
28
+ };
29
+ const createDefaultScrambleGenerator = ({ random }) => createScrambleGenerator({
30
+ random,
31
+ generators: DEFAULT_GENERATORS
32
+ });
33
+ const DEFAULT_GENERATORS = {
34
+ 333: ({ random }) => result("333", generateThreeByThreeScramble({ random })),
35
+ 222: ({ random }) => result("222", generateTwoByTwoScramble({ random })),
36
+ 444: ({ random }) => result("444", generateFourByFourScramble({ random })),
37
+ 555: ({ random }) => result("555", generateCubeRandomTurnScramble({
38
+ random,
39
+ size: 5,
40
+ length: 60
41
+ })),
42
+ 666: ({ random }) => result("666", generateCubeRandomTurnScramble({
43
+ random,
44
+ size: 6,
45
+ length: 80
46
+ })),
47
+ 777: ({ random }) => result("777", generateCubeRandomTurnScramble({
48
+ random,
49
+ size: 7,
50
+ length: 100
51
+ })),
52
+ "333bld": ({ random }) => result("333bld", generateThreeByThreeNoInspectionScramble({ random })),
53
+ "333fm": ({ random }) => result("333fm", generateThreeByThreeFewestMovesScramble({ random })),
54
+ "333oh": ({ random }) => result("333oh", generateThreeByThreeScramble({ random })),
55
+ clock: ({ random }) => result("clock", generateClockScramble({ random })),
56
+ minx: ({ random }) => result("minx", generateMegaminxScramble({ random })),
57
+ pyram: ({ random }) => result("pyram", generatePyraminxScramble({ random })),
58
+ skewb: ({ random }) => result("skewb", generateSkewbScramble({ random })),
59
+ sq1: ({ random }) => result("sq1", generateSquareOneScramble({ random })),
60
+ "444bld": ({ random }) => result("444bld", generateFourByFourNoInspectionScramble({ random })),
61
+ "555bld": ({ random }) => result("555bld", generateFiveByFiveNoInspectionScramble(random)),
62
+ "333mbld": ({ random, multiBlindCubeCount }) => {
63
+ if (multiBlindCubeCount === void 0) throw new Error(`${ERROR_PREFIX}: event '333mbld' requires multiBlindCubeCount`);
64
+ return result("333mbld", generateMultiBlindScramble({
65
+ random,
66
+ cubeCount: multiBlindCubeCount
67
+ }));
68
+ }
69
+ };
70
+ const FIVE_BY_FIVE_NO_INSPECTION_ORIENTATION_SEQUENCES = [
71
+ [],
72
+ ["3Uw"],
73
+ ["3Uw2"],
74
+ ["3Uw'"],
75
+ ["3Rw"],
76
+ ["3Rw", "3Uw"],
77
+ ["3Rw", "3Uw2"],
78
+ ["3Rw", "3Uw'"],
79
+ ["3Rw2"],
80
+ ["3Rw2", "3Uw"],
81
+ ["3Rw2", "3Uw2"],
82
+ ["3Rw2", "3Uw'"],
83
+ ["3Rw'"],
84
+ ["3Rw'", "3Uw"],
85
+ ["3Rw'", "3Uw2"],
86
+ ["3Rw'", "3Uw'"],
87
+ ["3Fw"],
88
+ ["3Fw", "3Uw"],
89
+ ["3Fw", "3Uw2"],
90
+ ["3Fw", "3Uw'"],
91
+ ["3Fw'"],
92
+ ["3Fw'", "3Uw"],
93
+ ["3Fw'", "3Uw2"],
94
+ ["3Fw'", "3Uw'"]
95
+ ];
96
+ const generateFiveByFiveNoInspectionScramble = (random) => {
97
+ const orientation = chooseFiveByFiveOrientation(random);
98
+ return [...trimRedundantTail(generateCubeRandomTurnScramble({
99
+ random,
100
+ size: 5,
101
+ length: 60
102
+ }), orientation[0]), ...orientation].join(" ");
103
+ };
104
+ const chooseFiveByFiveOrientation = (random) => {
105
+ const index = random.nextInt(FIVE_BY_FIVE_NO_INSPECTION_ORIENTATION_SEQUENCES.length);
106
+ const orientation = FIVE_BY_FIVE_NO_INSPECTION_ORIENTATION_SEQUENCES[index];
107
+ if (orientation === void 0) throw new RangeError(`${ERROR_PREFIX}: random source returned ${index} for max ${FIVE_BY_FIVE_NO_INSPECTION_ORIENTATION_SEQUENCES.length}`);
108
+ return orientation;
109
+ };
110
+ const trimRedundantTail = (scramble, firstOrientationMove) => {
111
+ const moves = scramble.trim().length === 0 ? [] : scramble.trim().split(/\s+/);
112
+ const orientationAxis = firstOrientationMove === void 0 ? void 0 : axisForMove(firstOrientationMove);
113
+ while (moves.length > 0 && orientationAxis !== void 0 && axisForMove(moves.at(-1)) === orientationAxis) moves.pop();
114
+ return moves;
115
+ };
116
+ const axisForMove = (move) => {
117
+ const match = move.match(/(?:\d+)?([RUFLDB])w?|([xyz])/);
118
+ switch (match?.[1] ?? match?.[2]) {
119
+ case "R":
120
+ case "L":
121
+ case "x": return 0;
122
+ case "U":
123
+ case "D":
124
+ case "y": return 1;
125
+ case "F":
126
+ case "B":
127
+ case "z": return 2;
128
+ default: return;
129
+ }
130
+ };
131
+ const result = (eventId, scramble) => ({
132
+ eventId,
133
+ scramble
134
+ });
135
+ //#endregion
136
+ export { createDefaultScrambleGenerator, createScrambleGenerator };
@@ -0,0 +1,11 @@
1
+ import { RandomSource } from "../random-source.mjs";
2
+
3
+ //#region .build/vendor/scramble-core/src/generators/clock.d.ts
4
+ interface ClockScrambleOptions {
5
+ random: RandomSource;
6
+ }
7
+ declare const generateClockScramble: ({
8
+ random
9
+ }: ClockScrambleOptions) => string;
10
+ //#endregion
11
+ export { ClockScrambleOptions, generateClockScramble };
@@ -0,0 +1,32 @@
1
+ //#region .build/vendor/scramble-core/src/generators/clock.ts
2
+ const CLOCK_FIRST_SIDE_MOVES = [
3
+ "UR",
4
+ "DR",
5
+ "DL",
6
+ "UL",
7
+ "U",
8
+ "R",
9
+ "D",
10
+ "L",
11
+ "ALL"
12
+ ];
13
+ const CLOCK_SECOND_SIDE_MOVES = [
14
+ "U",
15
+ "R",
16
+ "D",
17
+ "L",
18
+ "ALL"
19
+ ];
20
+ const nextClockTurn = (move, random) => {
21
+ const turn = random.nextInt(12) - 5;
22
+ return `${move}${Math.abs(turn)}${turn >= 0 ? "+" : "-"}`;
23
+ };
24
+ const generateClockScramble = ({ random }) => {
25
+ return [
26
+ ...CLOCK_FIRST_SIDE_MOVES.map((move) => nextClockTurn(move, random)),
27
+ "y2",
28
+ ...CLOCK_SECOND_SIDE_MOVES.map((move) => nextClockTurn(move, random))
29
+ ].join(" ");
30
+ };
31
+ //#endregion
32
+ export { generateClockScramble };
@@ -0,0 +1,11 @@
1
+ import { RandomSource } from "../random-source.mjs";
2
+
3
+ //#region .build/vendor/scramble-core/src/generators/cube-random-turns.d.ts
4
+ interface CubeRandomTurnOptions {
5
+ size: number;
6
+ length: number;
7
+ random: RandomSource;
8
+ }
9
+ declare const generateCubeRandomTurnScramble: (options: CubeRandomTurnOptions) => string;
10
+ //#endregion
11
+ export { CubeRandomTurnOptions, generateCubeRandomTurnScramble };
@@ -0,0 +1,54 @@
1
+ //#region .build/vendor/scramble-core/src/generators/cube-random-turns.ts
2
+ const FACES = [
3
+ "R",
4
+ "U",
5
+ "F",
6
+ "L",
7
+ "D",
8
+ "B"
9
+ ];
10
+ const SUFFIXES = [
11
+ "",
12
+ "2",
13
+ "'"
14
+ ];
15
+ const SUPPORTED_SIZES = new Set([
16
+ 5,
17
+ 6,
18
+ 7
19
+ ]);
20
+ const FACE_CHOICES = FACES.map((face, index) => ({
21
+ face,
22
+ axis: index % 3
23
+ }));
24
+ const validateOptions = ({ size, length }) => {
25
+ if (!Number.isSafeInteger(size) || !SUPPORTED_SIZES.has(size)) throw new Error("@cubegin/scramble-core: cube random-turn size must be 5, 6, or 7");
26
+ if (!Number.isSafeInteger(length) || length < 0) throw new Error("@cubegin/scramble-core: cube random-turn length must be a non-negative safe integer");
27
+ };
28
+ const chooseFace = (previousAxis, random) => {
29
+ const allowedFaces = previousAxis === void 0 ? FACE_CHOICES : FACE_CHOICES.filter(({ axis }) => axis !== previousAxis);
30
+ return allowedFaces[random.nextInt(allowedFaces.length)];
31
+ };
32
+ const chooseWideFace = (face, size, random) => {
33
+ const maxWidth = Math.floor(size / 2);
34
+ const width = random.nextInt(maxWidth) + 1;
35
+ if (width === 1) return face;
36
+ if (width === 2) return `${face}w`;
37
+ return `${width}${face}w`;
38
+ };
39
+ const generateCubeRandomTurnScramble = (options) => {
40
+ validateOptions(options);
41
+ const { size, length, random } = options;
42
+ const moves = [];
43
+ let previousAxis;
44
+ while (moves.length < length) {
45
+ const { axis, face } = chooseFace(previousAxis, random);
46
+ previousAxis = axis;
47
+ const wideFace = chooseWideFace(face, size, random);
48
+ const suffix = SUFFIXES[random.nextInt(SUFFIXES.length)];
49
+ moves.push(`${wideFace}${suffix}`);
50
+ }
51
+ return moves.join(" ");
52
+ };
53
+ //#endregion
54
+ export { generateCubeRandomTurnScramble };
@@ -0,0 +1,14 @@
1
+ import { RandomSource } from "../random-source.mjs";
2
+
3
+ //#region .build/vendor/scramble-core/src/generators/four-by-four.d.ts
4
+ interface FourByFourScrambleOptions {
5
+ random: RandomSource;
6
+ }
7
+ declare const generateFourByFourScramble: ({
8
+ random
9
+ }: FourByFourScrambleOptions) => string;
10
+ declare const generateFourByFourNoInspectionScramble: ({
11
+ random
12
+ }: FourByFourScrambleOptions) => string;
13
+ //#endregion
14
+ export { FourByFourScrambleOptions, generateFourByFourNoInspectionScramble, generateFourByFourScramble };
@@ -0,0 +1,43 @@
1
+ import { Search } from "../solvers/threephase/search.mjs";
2
+ //#region .build/vendor/scramble-core/src/generators/four-by-four.ts
3
+ const ORIENTATION_SEQUENCES = [
4
+ [],
5
+ ["y"],
6
+ ["y2"],
7
+ ["y'"],
8
+ ["x"],
9
+ ["x", "y"],
10
+ ["x", "y2"],
11
+ ["x", "y'"],
12
+ ["x2"],
13
+ ["x2", "y"],
14
+ ["x2", "y2"],
15
+ ["x2", "y'"],
16
+ ["x'"],
17
+ ["x'", "y"],
18
+ ["x'", "y2"],
19
+ ["x'", "y'"],
20
+ ["z"],
21
+ ["z", "y"],
22
+ ["z", "y2"],
23
+ ["z", "y'"],
24
+ ["z'"],
25
+ ["z'", "y"],
26
+ ["z'", "y2"],
27
+ ["z'", "y'"]
28
+ ];
29
+ const generateFourByFourScramble = ({ random }) => {
30
+ return new Search().randomState(random).trim();
31
+ };
32
+ const generateFourByFourNoInspectionScramble = ({ random }) => {
33
+ const orientation = chooseOrientation(random);
34
+ return [...generateFourByFourScramble({ random }).split(/\s+/), ...orientation].join(" ").trim();
35
+ };
36
+ const chooseOrientation = (random) => {
37
+ const index = random.nextInt(ORIENTATION_SEQUENCES.length);
38
+ const orientation = ORIENTATION_SEQUENCES[index];
39
+ if (orientation === void 0) throw new RangeError(`@cubegin/scramble-core: random source returned ${index} for max ${ORIENTATION_SEQUENCES.length}`);
40
+ return orientation;
41
+ };
42
+ //#endregion
43
+ export { generateFourByFourNoInspectionScramble, generateFourByFourScramble };
@@ -0,0 +1,11 @@
1
+ import { RandomSource } from "../random-source.mjs";
2
+
3
+ //#region .build/vendor/scramble-core/src/generators/megaminx.d.ts
4
+ interface MegaminxScrambleOptions {
5
+ random: RandomSource;
6
+ }
7
+ declare const generateMegaminxScramble: ({
8
+ random
9
+ }: MegaminxScrambleOptions) => string;
10
+ //#endregion
11
+ export { MegaminxScrambleOptions, generateMegaminxScramble };
@@ -0,0 +1,18 @@
1
+ //#region .build/vendor/scramble-core/src/generators/megaminx.ts
2
+ const generateMegaminxScramble = ({ random }) => {
3
+ const rows = [];
4
+ for (let row = 0; row < 7; row += 1) {
5
+ const moves = [];
6
+ let lastDirection = 0;
7
+ for (let column = 0; column < 10; column += 1) {
8
+ const side = column % 2 === 0 ? "R" : "D";
9
+ lastDirection = random.nextInt(2);
10
+ moves.push(`${side}${lastDirection === 0 ? "++" : "--"}`);
11
+ }
12
+ moves.push(lastDirection === 0 ? "U" : "U'");
13
+ rows.push(moves.join(" "));
14
+ }
15
+ return rows.join("\n");
16
+ };
17
+ //#endregion
18
+ export { generateMegaminxScramble };
@@ -0,0 +1,11 @@
1
+ import { RandomSource } from "../random-source.mjs";
2
+
3
+ //#region .build/vendor/scramble-core/src/generators/pyraminx.d.ts
4
+ interface PyraminxScrambleOptions {
5
+ random: RandomSource;
6
+ }
7
+ declare const generatePyraminxScramble: ({
8
+ random
9
+ }: PyraminxScrambleOptions) => string;
10
+ //#endregion
11
+ export { PyraminxScrambleOptions, generatePyraminxScramble };
@@ -0,0 +1,17 @@
1
+ import { PyraminxSolver } from "../solvers/pyraminx-solver.mjs";
2
+ //#region .build/vendor/scramble-core/src/generators/pyraminx.ts
3
+ const ERROR_PREFIX = "@cubegin/scramble-core";
4
+ const SCRAMBLE_LENGTH = 11;
5
+ const WCA_MIN_SCRAMBLE_DISTANCE = 6;
6
+ const MAX_WCA_ATTEMPTS = 100;
7
+ const generatePyraminxScramble = ({ random }) => {
8
+ const solver = new PyraminxSolver();
9
+ for (let attempt = 0; attempt < MAX_WCA_ATTEMPTS; attempt += 1) {
10
+ const state = solver.randomState(random);
11
+ if (solver.solveIn(state, WCA_MIN_SCRAMBLE_DISTANCE - 1, true, random) !== null) continue;
12
+ return solver.generateExactly(state, SCRAMBLE_LENGTH, false, random);
13
+ }
14
+ throw new Error(`${ERROR_PREFIX}: could not generate a Pyraminx WCA scramble after ${MAX_WCA_ATTEMPTS} attempts`);
15
+ };
16
+ //#endregion
17
+ export { generatePyraminxScramble };
@@ -0,0 +1,11 @@
1
+ import { RandomSource } from "../random-source.mjs";
2
+
3
+ //#region .build/vendor/scramble-core/src/generators/skewb.d.ts
4
+ interface SkewbScrambleOptions {
5
+ random: RandomSource;
6
+ }
7
+ declare const generateSkewbScramble: ({
8
+ random
9
+ }: SkewbScrambleOptions) => string;
10
+ //#endregion
11
+ export { SkewbScrambleOptions, generateSkewbScramble };
@@ -0,0 +1,17 @@
1
+ import { SkewbSolver } from "../solvers/skewb-solver.mjs";
2
+ //#region .build/vendor/scramble-core/src/generators/skewb.ts
3
+ const ERROR_PREFIX = "@cubegin/scramble-core";
4
+ const SCRAMBLE_LENGTH = 11;
5
+ const WCA_MIN_SCRAMBLE_DISTANCE = 7;
6
+ const MAX_WCA_ATTEMPTS = 100;
7
+ const generateSkewbScramble = ({ random }) => {
8
+ const solver = new SkewbSolver();
9
+ for (let attempt = 0; attempt < MAX_WCA_ATTEMPTS; attempt += 1) {
10
+ const state = solver.randomState(random);
11
+ if (solver.solveIn(state, WCA_MIN_SCRAMBLE_DISTANCE - 1, random) !== null) continue;
12
+ return solver.generateExactly(state, SCRAMBLE_LENGTH, random);
13
+ }
14
+ throw new Error(`${ERROR_PREFIX}: could not generate a Skewb WCA scramble after ${MAX_WCA_ATTEMPTS} attempts`);
15
+ };
16
+ //#endregion
17
+ export { generateSkewbScramble };
@@ -0,0 +1,11 @@
1
+ import { RandomSource } from "../random-source.mjs";
2
+
3
+ //#region .build/vendor/scramble-core/src/generators/square1.d.ts
4
+ interface SquareOneScrambleOptions {
5
+ random: RandomSource;
6
+ }
7
+ declare const generateSquareOneScramble: ({
8
+ random
9
+ }: SquareOneScrambleOptions) => string;
10
+ //#endregion
11
+ export { SquareOneScrambleOptions, generateSquareOneScramble };
@@ -0,0 +1,28 @@
1
+ import { parseSquareOneAlgorithm } from "../../../scramble-puzzle/src/square1/square1-parser.mjs";
2
+ import { applySquareOneMove, createSolvedSquareOneState } from "../../../scramble-puzzle/src/square1/square1-state.mjs";
3
+ import "../../../scramble-puzzle/src/index.mjs";
4
+ import { FullCube } from "../solvers/sq12phase/full-cube.mjs";
5
+ import { Search, solveSquareOneStateIn } from "../solvers/sq12phase/search.mjs";
6
+ //#region .build/vendor/scramble-core/src/generators/square1.ts
7
+ const ERROR_PREFIX = "@cubegin/scramble-core";
8
+ const WCA_MIN_SCRAMBLE_DISTANCE = 11;
9
+ const MAX_WCA_ATTEMPTS = 100;
10
+ const generateSquareOneScramble = ({ random }) => {
11
+ const search = new Search();
12
+ for (let attempt = 0; attempt < MAX_WCA_ATTEMPTS; attempt += 1) {
13
+ const randomState = FullCube.randomCube(random);
14
+ const solution = search.solution(randomState, 2);
15
+ if (solution === null) continue;
16
+ const scramble = solution.trim();
17
+ if (solveSquareOneStateIn(applyScrambleToSolvedState(scramble), WCA_MIN_SCRAMBLE_DISTANCE - 1) !== null) continue;
18
+ return scramble;
19
+ }
20
+ throw new Error(`${ERROR_PREFIX}: could not generate a Square-1 WCA scramble after ${MAX_WCA_ATTEMPTS} attempts`);
21
+ };
22
+ const applyScrambleToSolvedState = (scramble) => {
23
+ let state = createSolvedSquareOneState();
24
+ for (const move of parseSquareOneAlgorithm(scramble)) state = applySquareOneMove(state, move);
25
+ return state;
26
+ };
27
+ //#endregion
28
+ export { generateSquareOneScramble };
@@ -0,0 +1,25 @@
1
+ import { RandomSource } from "../random-source.mjs";
2
+
3
+ //#region .build/vendor/scramble-core/src/generators/three-by-three.d.ts
4
+ interface ThreeByThreeScrambleOptions {
5
+ random: RandomSource;
6
+ }
7
+ interface MultiBlindScrambleOptions {
8
+ random: RandomSource;
9
+ cubeCount: number;
10
+ }
11
+ declare const generateThreeByThreeScramble: ({
12
+ random
13
+ }: ThreeByThreeScrambleOptions) => string;
14
+ declare const generateThreeByThreeNoInspectionScramble: ({
15
+ random
16
+ }: ThreeByThreeScrambleOptions) => string;
17
+ declare const generateThreeByThreeFewestMovesScramble: ({
18
+ random
19
+ }: ThreeByThreeScrambleOptions) => string;
20
+ declare const generateMultiBlindScramble: ({
21
+ random,
22
+ cubeCount
23
+ }: MultiBlindScrambleOptions) => string;
24
+ //#endregion
25
+ export { MultiBlindScrambleOptions, ThreeByThreeScrambleOptions, generateMultiBlindScramble, generateThreeByThreeFewestMovesScramble, generateThreeByThreeNoInspectionScramble, generateThreeByThreeScramble };