@cubingcenter/scrambler 0.3.0 → 0.4.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 (124) hide show
  1. package/README.md +46 -3
  2. package/dist/core/api.d.ts.map +1 -1
  3. package/dist/core/api.js +13 -6
  4. package/dist/core/index.d.ts +1 -1
  5. package/dist/core/index.d.ts.map +1 -1
  6. package/dist/core/types.d.ts +7 -0
  7. package/dist/core/types.d.ts.map +1 -1
  8. package/dist/puzzles/clock/index.d.ts +1 -0
  9. package/dist/puzzles/clock/index.d.ts.map +1 -1
  10. package/dist/puzzles/clock/index.js +4 -0
  11. package/dist/puzzles/clock/scrambler.js +2 -2
  12. package/dist/puzzles/cube2/index.d.ts +1 -0
  13. package/dist/puzzles/cube2/index.d.ts.map +1 -1
  14. package/dist/puzzles/cube2/index.js +4 -0
  15. package/dist/puzzles/cube2/scrambler.d.ts.map +1 -1
  16. package/dist/puzzles/cube2/scrambler.js +4 -6
  17. package/dist/puzzles/cube2/solver/browser-loader.d.ts.map +1 -1
  18. package/dist/puzzles/cube2/solver/browser-loader.js +4 -12
  19. package/dist/puzzles/cube2/solver/index.d.ts +1 -1
  20. package/dist/puzzles/cube2/solver/index.d.ts.map +1 -1
  21. package/dist/puzzles/cube2/solver/index.js +1 -1
  22. package/dist/puzzles/cube2/solver/search.d.ts +2 -0
  23. package/dist/puzzles/cube2/solver/search.d.ts.map +1 -1
  24. package/dist/puzzles/cube2/solver/search.js +26 -0
  25. package/dist/puzzles/cube2/validation.d.ts.map +1 -1
  26. package/dist/puzzles/cube2/validation.js +15 -3
  27. package/dist/puzzles/cube3/index.d.ts +1 -0
  28. package/dist/puzzles/cube3/index.d.ts.map +1 -1
  29. package/dist/puzzles/cube3/index.js +4 -0
  30. package/dist/puzzles/cube3/solver/browser-loader.d.ts.map +1 -1
  31. package/dist/puzzles/cube3/solver/browser-loader.js +5 -29
  32. package/dist/puzzles/cube4/index.d.ts +1 -0
  33. package/dist/puzzles/cube4/index.d.ts.map +1 -1
  34. package/dist/puzzles/cube4/index.js +4 -0
  35. package/dist/puzzles/cube5x5/index.d.ts +1 -0
  36. package/dist/puzzles/cube5x5/index.d.ts.map +1 -1
  37. package/dist/puzzles/cube5x5/index.js +4 -0
  38. package/dist/puzzles/cube6x6/index.d.ts +1 -0
  39. package/dist/puzzles/cube6x6/index.d.ts.map +1 -1
  40. package/dist/puzzles/cube6x6/index.js +4 -0
  41. package/dist/puzzles/cube7x7/index.d.ts +1 -0
  42. package/dist/puzzles/cube7x7/index.d.ts.map +1 -1
  43. package/dist/puzzles/cube7x7/index.js +4 -0
  44. package/dist/puzzles/megaminx/index.d.ts +1 -0
  45. package/dist/puzzles/megaminx/index.d.ts.map +1 -1
  46. package/dist/puzzles/megaminx/index.js +4 -0
  47. package/dist/puzzles/megaminx/scrambler.js +2 -2
  48. package/dist/puzzles/pyraminx/index.d.ts +3 -1
  49. package/dist/puzzles/pyraminx/index.d.ts.map +1 -1
  50. package/dist/puzzles/pyraminx/index.js +6 -1
  51. package/dist/puzzles/pyraminx/scrambler.d.ts.map +1 -1
  52. package/dist/puzzles/pyraminx/scrambler.js +26 -22
  53. package/dist/puzzles/pyraminx/solver/browser-loader.d.ts +14 -0
  54. package/dist/puzzles/pyraminx/solver/browser-loader.d.ts.map +1 -0
  55. package/dist/puzzles/pyraminx/solver/browser-loader.js +63 -0
  56. package/dist/puzzles/pyraminx/solver/generated/centers-table.bin +0 -0
  57. package/dist/puzzles/pyraminx/solver/generated/manifest.json +26 -0
  58. package/dist/puzzles/pyraminx/solver/generated/orientation-table.bin +0 -0
  59. package/dist/puzzles/pyraminx/solver/generated/permutation-table.bin +0 -0
  60. package/dist/puzzles/pyraminx/solver/generated/policy.bin +0 -0
  61. package/dist/puzzles/pyraminx/solver/generated-assets.d.ts +7 -0
  62. package/dist/puzzles/pyraminx/solver/generated-assets.d.ts.map +1 -0
  63. package/dist/puzzles/pyraminx/solver/generated-assets.js +24 -0
  64. package/dist/puzzles/pyraminx/solver/index.d.ts +5 -0
  65. package/dist/puzzles/pyraminx/solver/index.d.ts.map +1 -0
  66. package/dist/puzzles/pyraminx/solver/index.js +4 -0
  67. package/dist/puzzles/pyraminx/solver/node-loader.d.ts +7 -0
  68. package/dist/puzzles/pyraminx/solver/node-loader.d.ts.map +1 -0
  69. package/dist/puzzles/pyraminx/solver/node-loader.js +73 -0
  70. package/dist/puzzles/pyraminx/solver/search.d.ts +10 -0
  71. package/dist/puzzles/pyraminx/solver/search.d.ts.map +1 -0
  72. package/dist/puzzles/pyraminx/solver/search.js +82 -0
  73. package/dist/puzzles/pyraminx/solver/table-metadata.d.ts +20 -0
  74. package/dist/puzzles/pyraminx/solver/table-metadata.d.ts.map +1 -0
  75. package/dist/puzzles/pyraminx/solver/table-metadata.js +19 -0
  76. package/dist/puzzles/pyraminx/solver/tables.d.ts +43 -0
  77. package/dist/puzzles/pyraminx/solver/tables.d.ts.map +1 -0
  78. package/dist/puzzles/pyraminx/solver/tables.js +300 -0
  79. package/dist/puzzles/shared/compressed-fetch.d.ts +12 -0
  80. package/dist/puzzles/shared/compressed-fetch.d.ts.map +1 -0
  81. package/dist/puzzles/shared/compressed-fetch.js +68 -0
  82. package/dist/puzzles/skewb/index.d.ts +1 -0
  83. package/dist/puzzles/skewb/index.d.ts.map +1 -1
  84. package/dist/puzzles/skewb/index.js +4 -0
  85. package/dist/puzzles/skewb/scrambler.js +2 -2
  86. package/dist-cjs/core/api.js +46 -6
  87. package/dist-cjs/puzzles/clock/index.js +13 -4
  88. package/dist-cjs/puzzles/clock/scrambler.js +2 -2
  89. package/dist-cjs/puzzles/cube2/index.js +13 -4
  90. package/dist-cjs/puzzles/cube2/scrambler.js +2 -4
  91. package/dist-cjs/puzzles/cube2/solver/browser-loader.js +4 -12
  92. package/dist-cjs/puzzles/cube2/solver/index.js +3 -1
  93. package/dist-cjs/puzzles/cube2/solver/search.js +28 -0
  94. package/dist-cjs/puzzles/cube2/validation.js +14 -2
  95. package/dist-cjs/puzzles/cube3/index.js +13 -4
  96. package/dist-cjs/puzzles/cube3/solver/browser-loader.js +5 -29
  97. package/dist-cjs/puzzles/cube4/index.js +13 -4
  98. package/dist-cjs/puzzles/cube5x5/index.js +13 -4
  99. package/dist-cjs/puzzles/cube6x6/index.js +13 -4
  100. package/dist-cjs/puzzles/cube7x7/index.js +13 -4
  101. package/dist-cjs/puzzles/megaminx/index.js +13 -4
  102. package/dist-cjs/puzzles/megaminx/scrambler.js +2 -2
  103. package/dist-cjs/puzzles/pyraminx/index.js +50 -6
  104. package/dist-cjs/puzzles/pyraminx/scrambler.js +25 -21
  105. package/dist-cjs/puzzles/pyraminx/solver/browser-loader.js +68 -0
  106. package/dist-cjs/puzzles/pyraminx/solver/generated/centers-table.bin +0 -0
  107. package/dist-cjs/puzzles/pyraminx/solver/generated/manifest.json +26 -0
  108. package/dist-cjs/puzzles/pyraminx/solver/generated/orientation-table.bin +0 -0
  109. package/dist-cjs/puzzles/pyraminx/solver/generated/permutation-table.bin +0 -0
  110. package/dist-cjs/puzzles/pyraminx/solver/generated/policy.bin +0 -0
  111. package/dist-cjs/puzzles/pyraminx/solver/generated-assets.js +60 -0
  112. package/dist-cjs/puzzles/pyraminx/solver/index.js +23 -0
  113. package/dist-cjs/puzzles/pyraminx/solver/node-loader.js +79 -0
  114. package/dist-cjs/puzzles/pyraminx/solver/search.js +88 -0
  115. package/dist-cjs/puzzles/pyraminx/solver/table-metadata.js +22 -0
  116. package/dist-cjs/puzzles/pyraminx/solver/tables.js +327 -0
  117. package/dist-cjs/puzzles/shared/compressed-fetch.js +71 -0
  118. package/dist-cjs/puzzles/skewb/index.js +13 -4
  119. package/dist-cjs/puzzles/skewb/scrambler.js +2 -2
  120. package/package.json +17 -6
  121. package/dist/puzzles/pyraminx/solver.d.ts +0 -10
  122. package/dist/puzzles/pyraminx/solver.d.ts.map +0 -1
  123. package/dist/puzzles/pyraminx/solver.js +0 -160
  124. package/dist-cjs/puzzles/pyraminx/solver.js +0 -170
@@ -2,7 +2,7 @@ import { createRandomSource } from "../../random/index.js";
2
2
  import { MEGAMINX_R_MOVES, MEGAMINX_D_MOVES, SCRAMBLE_LINES, MOVES_PER_LINE } from "./types.js";
3
3
  export const megaminxScrambleGenerator = {
4
4
  info: {
5
- eventId: "mega",
5
+ eventId: "mgmx",
6
6
  name: "Megaminx",
7
7
  puzzle: "megaminx",
8
8
  quality: "random-move",
@@ -29,7 +29,7 @@ export function generateMegaminxScramble(options = {}) {
29
29
  }
30
30
  const scramble = formatMegaminxScramble(moves);
31
31
  const result = {
32
- eventId: "mega",
32
+ eventId: "mgmx",
33
33
  scramble,
34
34
  moves,
35
35
  quality: "random-move",
@@ -7,5 +7,7 @@ export { generateRandomPyraminxState } from "./random-state.js";
7
7
  export { pyraminxScrambleGenerator, generatePyraminxScramble } from "./scrambler.js";
8
8
  export { createSolvedPyraminxFacelets, formatPyraminxFacelets, getPyraminxFaceOrder, toPyraminxFacelets } from "./facelets.js";
9
9
  export type { PyraminxFacelets } from "./facelets.js";
10
- export { solvePyraminx } from "./solver.js";
10
+ export { solvePyraminx, solvePyraminxWithInfo } from "./solver/index.js";
11
+ export * as solver from "./solver/index.js";
12
+ export { generateScramble, generateScrambles, getEventInfo, getSupportedEvents, initializeScrambler } from "../../core/index.js";
11
13
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/puzzles/pyraminx/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,mBAAmB,EACnB,aAAa,EACd,MAAM,YAAY,CAAC;AACpB,YAAY,EACV,YAAY,EACZ,aAAa,EACb,gBAAgB,EAChB,eAAe,EACf,0BAA0B,EAC3B,MAAM,YAAY,CAAC;AACpB,OAAO,EACL,sBAAsB,EACtB,iBAAiB,EACjB,uBAAuB,EACvB,uBAAuB,EACvB,kBAAkB,EAClB,sBAAsB,EACtB,iBAAiB,EAClB,MAAM,YAAY,CAAC;AACpB,OAAO,EACL,kBAAkB,EAClB,yBAAyB,EACzB,mBAAmB,EACnB,qBAAqB,EACtB,MAAM,YAAY,CAAC;AACpB,OAAO,EACL,iBAAiB,EACjB,qBAAqB,EACrB,4BAA4B,EAC7B,MAAM,iBAAiB,CAAC;AACzB,OAAO,EACL,2BAA2B,EAC5B,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EACL,yBAAyB,EACzB,wBAAwB,EACzB,MAAM,gBAAgB,CAAC;AACxB,OAAO,EACL,4BAA4B,EAC5B,sBAAsB,EACtB,oBAAoB,EACpB,kBAAkB,EACnB,MAAM,eAAe,CAAC;AACvB,YAAY,EACV,gBAAgB,EACjB,MAAM,eAAe,CAAC;AACvB,OAAO,EACL,aAAa,EACd,MAAM,aAAa,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/puzzles/pyraminx/index.ts"],"names":[],"mappings":"AAKA,OAAO,EACL,mBAAmB,EACnB,aAAa,EACd,MAAM,YAAY,CAAC;AACpB,YAAY,EACV,YAAY,EACZ,aAAa,EACb,gBAAgB,EAChB,eAAe,EACf,0BAA0B,EAC3B,MAAM,YAAY,CAAC;AACpB,OAAO,EACL,sBAAsB,EACtB,iBAAiB,EACjB,uBAAuB,EACvB,uBAAuB,EACvB,kBAAkB,EAClB,sBAAsB,EACtB,iBAAiB,EAClB,MAAM,YAAY,CAAC;AACpB,OAAO,EACL,kBAAkB,EAClB,yBAAyB,EACzB,mBAAmB,EACnB,qBAAqB,EACtB,MAAM,YAAY,CAAC;AACpB,OAAO,EACL,iBAAiB,EACjB,qBAAqB,EACrB,4BAA4B,EAC7B,MAAM,iBAAiB,CAAC;AACzB,OAAO,EACL,2BAA2B,EAC5B,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EACL,yBAAyB,EACzB,wBAAwB,EACzB,MAAM,gBAAgB,CAAC;AACxB,OAAO,EACL,4BAA4B,EAC5B,sBAAsB,EACtB,oBAAoB,EACpB,kBAAkB,EACnB,MAAM,eAAe,CAAC;AACvB,YAAY,EACV,gBAAgB,EACjB,MAAM,eAAe,CAAC;AACvB,OAAO,EACL,aAAa,EACb,qBAAqB,EACtB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,KAAK,MAAM,MAAM,mBAAmB,CAAC;AAE5C,OAAO,EACL,gBAAgB,EAChB,iBAAiB,EACjB,YAAY,EACZ,kBAAkB,EAClB,mBAAmB,EACpB,MAAM,qBAAqB,CAAC"}
@@ -1,3 +1,6 @@
1
+ import { registerScrambleGenerator } from "../../core/index.js";
2
+ import { pyraminxScrambleGenerator } from "./scrambler.js";
3
+ registerScrambleGenerator(pyraminxScrambleGenerator);
1
4
  export { PYRAMINX_CORE_MOVES, PYRAMINX_TIPS } from "./types.js";
2
5
  export { applyPyraminxAlgorithm, applyPyraminxMove, formatPyraminxAlgorithm, invertPyraminxAlgorithm, invertPyraminxMove, parsePyraminxAlgorithm, parsePyraminxMove } from "./moves.js";
3
6
  export { clonePyraminxState, createSolvedPyraminxState, pyraminxStatesEqual, isSolvedPyraminxState } from "./state.js";
@@ -5,4 +8,6 @@ export { permutationParity, validatePyraminxState, isAllowedRandomPyraminxState
5
8
  export { generateRandomPyraminxState } from "./random-state.js";
6
9
  export { pyraminxScrambleGenerator, generatePyraminxScramble } from "./scrambler.js";
7
10
  export { createSolvedPyraminxFacelets, formatPyraminxFacelets, getPyraminxFaceOrder, toPyraminxFacelets } from "./facelets.js";
8
- export { solvePyraminx } from "./solver.js";
11
+ export { solvePyraminx, solvePyraminxWithInfo } from "./solver/index.js";
12
+ export * as solver from "./solver/index.js";
13
+ export { generateScramble, generateScrambles, getEventInfo, getSupportedEvents, initializeScrambler } from "../../core/index.js";
@@ -1 +1 @@
1
- {"version":3,"file":"scrambler.d.ts","sourceRoot":"","sources":["../../../src/puzzles/pyraminx/scrambler.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAQ9F,eAAO,MAAM,yBAAyB,EAAE,iBAYvC,CAAC;AAEF,wBAAsB,wBAAwB,CAC5C,OAAO,GAAE,eAAe,GAAG;IAAE,cAAc,CAAC,EAAE,OAAO,CAAA;CAAO,GAC3D,OAAO,CAAC,cAAc,CAAC,CA+CzB"}
1
+ {"version":3,"file":"scrambler.d.ts","sourceRoot":"","sources":["../../../src/puzzles/pyraminx/scrambler.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAW9F,eAAO,MAAM,yBAAyB,EAAE,iBAYvC,CAAC;AAEF,wBAAsB,wBAAwB,CAC5C,OAAO,GAAE,eAAe,GAAG;IAAE,cAAc,CAAC,EAAE,OAAO,CAAA;CAAO,GAC3D,OAAO,CAAC,cAAc,CAAC,CAkDzB"}
@@ -1,16 +1,18 @@
1
1
  import { generateRandomPyraminxState } from "./random-state.js";
2
- import { createSolvedPyraminxState } from "./state.js";
3
- import { applyPyraminxAlgorithm, invertPyraminxAlgorithm } from "./moves.js";
4
- import { solvePyraminx } from "./solver.js";
2
+ import { invertPyraminxAlgorithm } from "./moves.js";
3
+ import { solvePyraminx, verifyPyraminxScramble } from "./solver/index.js";
5
4
  import { formatPyraminxFacelets, toPyraminxFacelets } from "./facelets.js";
5
+ import { PYRAMINX_TIPS } from "./types.js";
6
+ // Face -> tip index (U,L,R,B order, same as PYRAMINX_TIPS).
7
+ const FACE_TIP_INDEX = { U: 0, L: 1, R: 2, B: 3 };
6
8
  export const pyraminxScrambleGenerator = {
7
9
  info: {
8
- eventId: "pyra",
10
+ eventId: "pymx",
9
11
  name: "Pyraminx",
10
12
  puzzle: "pyraminx",
11
13
  quality: "random-state",
12
- generator: "pyraminx-ida-star",
13
- description: "Random-state Pyraminx scramble generated by an optimal bidirectional BFS solver."
14
+ generator: "pyraminx-optimal",
15
+ description: "Random-state Pyraminx scramble generated by an optimal solver with precalculated tables."
14
16
  },
15
17
  generate(options = {}) {
16
18
  return generatePyraminxScramble(options);
@@ -19,38 +21,40 @@ export const pyraminxScrambleGenerator = {
19
21
  export async function generatePyraminxScramble(options = {}) {
20
22
  const state = generateRandomPyraminxState(options);
21
23
  // Solve the core edges and centers
22
- const solution = solvePyraminx(state);
24
+ const solution = await solvePyraminx(state);
23
25
  const scrambleMoves = invertPyraminxAlgorithm(solution);
24
26
  // Append tips: layer moves already rotate tips, so we need the delta
25
27
  // between the target tips and the tips produced by the core scramble.
26
- const coreState = applyPyraminxAlgorithm(createSolvedPyraminxState(), scrambleMoves);
28
+ // Computed arithmetically from the move sequence (no state replay).
29
+ const coreTips = [0, 0, 0, 0];
30
+ for (const move of scrambleMoves) {
31
+ const isInverse = move.endsWith("'");
32
+ const face = isInverse ? move.slice(0, -1) : move;
33
+ const tipIndex = FACE_TIP_INDEX[face];
34
+ if (tipIndex !== undefined) {
35
+ coreTips[tipIndex] = (coreTips[tipIndex] + (isInverse ? 2 : 1)) % 3;
36
+ }
37
+ }
27
38
  const finalMoves = [...scrambleMoves];
28
- const tipsNotation = ["u", "l", "r", "b"];
29
39
  for (let i = 0; i < 4; i++) {
30
- const delta = (state.tips[i] - coreState.tips[i] + 3) % 3;
40
+ const delta = (state.tips[i] - coreTips[i] + 3) % 3;
31
41
  if (delta === 1) {
32
- finalMoves.push(tipsNotation[i]);
42
+ finalMoves.push(PYRAMINX_TIPS[i]);
33
43
  }
34
44
  else if (delta === 2) {
35
- finalMoves.push(`${tipsNotation[i]}'`);
45
+ finalMoves.push(`${PYRAMINX_TIPS[i]}'`);
36
46
  }
37
47
  }
38
- if (!options.skipValidation) {
39
- const scrambledState = applyPyraminxAlgorithm(createSolvedPyraminxState(), finalMoves);
40
- if (scrambledState.edgesPerm.toString() !== state.edgesPerm.toString() ||
41
- scrambledState.edgesOrient.toString() !== state.edgesOrient.toString() ||
42
- scrambledState.centers.toString() !== state.centers.toString() ||
43
- scrambledState.tips.toString() !== state.tips.toString()) {
44
- throw new Error("Generated Pyraminx scramble does not reproduce the target random state.");
45
- }
48
+ if (!options.skipValidation && !verifyPyraminxScramble(state, finalMoves)) {
49
+ throw new Error("Generated Pyraminx scramble does not reproduce the target random state.");
46
50
  }
47
51
  const facelets = toPyraminxFacelets(state);
48
52
  return {
49
- eventId: "pyra",
53
+ eventId: "pymx",
50
54
  scramble: finalMoves.join(" "),
51
55
  moves: finalMoves,
52
56
  quality: "random-state",
53
- generator: "pyraminx-ida-star",
57
+ generator: "pyraminx-optimal",
54
58
  metadata: {
55
59
  state,
56
60
  facelets,
@@ -0,0 +1,14 @@
1
+ export declare function getCachedBrowserTables(): {
2
+ centersTable: Uint8Array;
3
+ permutationTable: Uint16Array;
4
+ orientationTable: Uint8Array;
5
+ policyTable: Uint8Array;
6
+ } | undefined;
7
+ export declare function clearCachedBrowserTables(): void;
8
+ export declare function loadBrowserTables(baseUrl?: string): Promise<{
9
+ centersTable: Uint8Array;
10
+ permutationTable: Uint16Array;
11
+ orientationTable: Uint8Array;
12
+ policyTable: Uint8Array;
13
+ }>;
14
+ //# sourceMappingURL=browser-loader.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"browser-loader.d.ts","sourceRoot":"","sources":["../../../../src/puzzles/pyraminx/solver/browser-loader.ts"],"names":[],"mappings":"AAUA,wBAAgB,sBAAsB;kBANtB,UAAU;sBACN,WAAW;sBACX,UAAU;iBACf,UAAU;cAKxB;AACD,wBAAgB,wBAAwB,IAAI,IAAI,CAE/C;AAED,wBAAsB,iBAAiB,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;IACjE,YAAY,EAAE,UAAU,CAAC;IACzB,gBAAgB,EAAE,WAAW,CAAC;IAC9B,gBAAgB,EAAE,UAAU,CAAC;IAC7B,WAAW,EAAE,UAAU,CAAC;CACzB,CAAC,CAYD"}
@@ -0,0 +1,63 @@
1
+ import { PYRAMINX_SOLVER_TABLE_METADATA } from "./table-metadata.js";
2
+ import { fetchTableBuffer as fetchCompressedTableBuffer } from "../../shared/compressed-fetch.js";
3
+ let cachedBrowserTables;
4
+ export function getCachedBrowserTables() {
5
+ return cachedBrowserTables;
6
+ }
7
+ export function clearCachedBrowserTables() {
8
+ cachedBrowserTables = undefined;
9
+ }
10
+ export async function loadBrowserTables(baseUrl) {
11
+ if (cachedBrowserTables)
12
+ return cachedBrowserTables;
13
+ const resolved = resolveBaseUrl(baseUrl);
14
+ const manifest = await fetchManifest(resolved);
15
+ const [centersTable, permutationTable, orientationTable, policyTable] = await Promise.all([
16
+ fetchUint8Table(resolved, manifest.files.centersTable, PYRAMINX_SOLVER_TABLE_METADATA.centersTable.entries),
17
+ fetchUint16Table(resolved, manifest.files.permutationTable, PYRAMINX_SOLVER_TABLE_METADATA.permutationTable.entries),
18
+ fetchUint8Table(resolved, manifest.files.orientationTable, PYRAMINX_SOLVER_TABLE_METADATA.orientationTable.entries),
19
+ fetchUint8Table(resolved, manifest.files.policyTable, PYRAMINX_SOLVER_TABLE_METADATA.policyTable.entries)
20
+ ]);
21
+ cachedBrowserTables = { centersTable, permutationTable, orientationTable, policyTable };
22
+ return cachedBrowserTables;
23
+ }
24
+ function resolveBaseUrl(provided) {
25
+ if (provided)
26
+ return provided.replace(/\/$/, "");
27
+ if (typeof document !== "undefined") {
28
+ const script = document.currentScript;
29
+ if (script?.src) {
30
+ const base = new URL(".", script.src).href;
31
+ return base.replace(/\/$/, "");
32
+ }
33
+ }
34
+ return ".";
35
+ }
36
+ async function fetchManifest(baseUrl) {
37
+ const url = `${baseUrl}/puzzles/pyraminx/solver/generated/manifest.json`;
38
+ const response = await fetch(url);
39
+ if (!response.ok)
40
+ throw new Error(`Failed to load pyraminx solver table manifest from ${url}: ${response.status} ${response.statusText}`);
41
+ const manifest = (await response.json());
42
+ if (manifest.version !== 1)
43
+ throw new Error(`Unsupported pyraminx solver table manifest version: ${manifest.version}`);
44
+ return manifest;
45
+ }
46
+ const TABLES_DIR = "puzzles/pyraminx/solver/generated";
47
+ const CACHE_NAME = "cubingcenter-scrambler-tables-v1";
48
+ async function fetchUint8Table(baseUrl, entry, expectedEntries) {
49
+ const buffer = await fetchCompressedTableBuffer(baseUrl, TABLES_DIR, entry.file, { cacheName: CACHE_NAME, compressed: entry.compressed !== false });
50
+ if (buffer.byteLength !== expectedEntries)
51
+ throw new Error(`Invalid byte size for ${entry.file}`);
52
+ return new Uint8Array(buffer);
53
+ }
54
+ async function fetchUint16Table(baseUrl, entry, expectedEntries) {
55
+ const buffer = await fetchCompressedTableBuffer(baseUrl, TABLES_DIR, entry.file, { cacheName: CACHE_NAME, compressed: entry.compressed !== false });
56
+ if (buffer.byteLength !== expectedEntries * 2)
57
+ throw new Error(`Invalid byte size for ${entry.file}`);
58
+ const values = new Uint16Array(expectedEntries);
59
+ const view = new DataView(buffer);
60
+ for (let i = 0; i < values.length; i++)
61
+ values[i] = view.getUint16(i * 2, true);
62
+ return values;
63
+ }
@@ -0,0 +1,26 @@
1
+ {
2
+ "version": 1,
3
+ "files": {
4
+ "centersTable": {
5
+ "file": "centers-table.bin",
6
+ "entries": 648,
7
+ "checksum": 4058180805
8
+ },
9
+ "permutationTable": {
10
+ "file": "permutation-table.bin",
11
+ "entries": 2880,
12
+ "checksum": 4161414597
13
+ },
14
+ "orientationTable": {
15
+ "file": "orientation-table.bin",
16
+ "entries": 256,
17
+ "checksum": 3608176069
18
+ },
19
+ "policyTable": {
20
+ "file": "policy.bin",
21
+ "entries": 349920,
22
+ "checksum": 4047562730,
23
+ "maxDepth": 11
24
+ }
25
+ }
26
+ }
@@ -0,0 +1,7 @@
1
+ export declare function loadGeneratedPyraminxSolverTables(): Promise<{
2
+ centersTable: Uint8Array;
3
+ permutationTable: Uint16Array;
4
+ orientationTable: Uint8Array;
5
+ policyTable: Uint8Array;
6
+ }>;
7
+ //# sourceMappingURL=generated-assets.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"generated-assets.d.ts","sourceRoot":"","sources":["../../../../src/puzzles/pyraminx/solver/generated-assets.ts"],"names":[],"mappings":"AAaA,wBAAsB,iCAAiC,IAAI,OAAO,CAAC;IACjE,YAAY,EAAE,UAAU,CAAC;IACzB,gBAAgB,EAAE,WAAW,CAAC;IAC9B,gBAAgB,EAAE,UAAU,CAAC;IAC7B,WAAW,EAAE,UAAU,CAAC;CACzB,CAAC,CAYD"}
@@ -0,0 +1,24 @@
1
+ import { getCachedBrowserTables } from "./browser-loader.js";
2
+ let cachedTables;
3
+ function isBrowser() {
4
+ return typeof self !== "undefined";
5
+ }
6
+ export async function loadGeneratedPyraminxSolverTables() {
7
+ if (isBrowser()) {
8
+ const browserTables = getCachedBrowserTables();
9
+ if (browserTables)
10
+ return browserTables;
11
+ throw new Error("Pyraminx solver tables are not loaded. " +
12
+ "In browser environments, call `initializeScrambler(baseUrl)` " +
13
+ "before generating scrambles.");
14
+ }
15
+ cachedTables ??= await loadNodeTables();
16
+ return cachedTables;
17
+ }
18
+ async function loadNodeTables() {
19
+ const loader = await import(
20
+ /* webpackIgnore: true */
21
+ /* @vite-ignore */
22
+ "./node-loader.js");
23
+ return loader.readGeneratedPyraminxSolverTables();
24
+ }
@@ -0,0 +1,5 @@
1
+ export * from "./tables.js";
2
+ export * from "./search.js";
3
+ export { PYRAMINX_SOLVER_TABLE_METADATA } from "./table-metadata.js";
4
+ export { loadGeneratedPyraminxSolverTables } from "./generated-assets.js";
5
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/puzzles/pyraminx/solver/index.ts"],"names":[],"mappings":"AAAA,cAAc,aAAa,CAAC;AAC5B,cAAc,aAAa,CAAC;AAC5B,OAAO,EAAE,8BAA8B,EAAE,MAAM,qBAAqB,CAAC;AACrE,OAAO,EAAE,iCAAiC,EAAE,MAAM,uBAAuB,CAAC"}
@@ -0,0 +1,4 @@
1
+ export * from "./tables.js";
2
+ export * from "./search.js";
3
+ export { PYRAMINX_SOLVER_TABLE_METADATA } from "./table-metadata.js";
4
+ export { loadGeneratedPyraminxSolverTables } from "./generated-assets.js";
@@ -0,0 +1,7 @@
1
+ export declare function readGeneratedPyraminxSolverTables(): {
2
+ centersTable: Uint8Array;
3
+ permutationTable: Uint16Array;
4
+ orientationTable: Uint8Array;
5
+ policyTable: Uint8Array;
6
+ };
7
+ //# sourceMappingURL=node-loader.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"node-loader.d.ts","sourceRoot":"","sources":["../../../../src/puzzles/pyraminx/solver/node-loader.ts"],"names":[],"mappings":"AAiBA,wBAAgB,iCAAiC,IAAI;IACnD,YAAY,EAAE,UAAU,CAAC;IACzB,gBAAgB,EAAE,WAAW,CAAC;IAC9B,gBAAgB,EAAE,UAAU,CAAC;IAC7B,WAAW,EAAE,UAAU,CAAC;CACzB,CAaA"}
@@ -0,0 +1,73 @@
1
+ import { existsSync, readFileSync } from "node:fs";
2
+ import { createRequire } from "node:module";
3
+ import path from "node:path";
4
+ import { PYRAMINX_SOLVER_TABLE_METADATA } from "./table-metadata.js";
5
+ const GENERATED_DIRECTORY = "puzzles/pyraminx/solver/generated";
6
+ export function readGeneratedPyraminxSolverTables() {
7
+ const assetDirectory = resolveGeneratedAssetDirectory();
8
+ const manifest = JSON.parse(readFileSync(path.join(assetDirectory, "manifest.json"), "utf8"));
9
+ if (manifest.version !== 1)
10
+ throw new Error(`Unsupported pyraminx solver table manifest version: ${manifest.version}`);
11
+ const centersTable = readUint8Table(assetDirectory, manifest.files.centersTable, PYRAMINX_SOLVER_TABLE_METADATA.centersTable.checksum);
12
+ const permutationTable = readUint16Table(assetDirectory, manifest.files.permutationTable, PYRAMINX_SOLVER_TABLE_METADATA.permutationTable.checksum);
13
+ const orientationTable = readUint8Table(assetDirectory, manifest.files.orientationTable, PYRAMINX_SOLVER_TABLE_METADATA.orientationTable.checksum);
14
+ const policyTable = readUint8Table(assetDirectory, manifest.files.policyTable, PYRAMINX_SOLVER_TABLE_METADATA.policyTable.checksum);
15
+ return { centersTable, permutationTable, orientationTable, policyTable };
16
+ }
17
+ function readUint8Table(assetDirectory, entry, expectedChecksum) {
18
+ const buffer = readFileSync(path.join(assetDirectory, entry.file));
19
+ if (buffer.length !== entry.entries)
20
+ throw new Error(`Invalid byte size for ${entry.file}`);
21
+ const values = new Uint8Array(buffer);
22
+ assertChecksum(entry.file, checksum(values), expectedChecksum);
23
+ return values;
24
+ }
25
+ function readUint16Table(assetDirectory, entry, expectedChecksum) {
26
+ const buffer = readFileSync(path.join(assetDirectory, entry.file));
27
+ if (buffer.length !== entry.entries * 2)
28
+ throw new Error(`Invalid byte size for ${entry.file}`);
29
+ const values = new Uint16Array(entry.entries);
30
+ for (let i = 0; i < values.length; i++)
31
+ values[i] = buffer.readUInt16LE(i * 2);
32
+ assertChecksum(entry.file, checksum(values), expectedChecksum);
33
+ return values;
34
+ }
35
+ function resolveGeneratedAssetDirectory() {
36
+ const envDirectory = process.env.CUBINGCENTER_SCRAMBLER_TABLES_DIR;
37
+ if (envDirectory && existsSync(path.join(envDirectory, "manifest.json")))
38
+ return envDirectory;
39
+ for (const candidate of getAssetDirectoryCandidates()) {
40
+ if (existsSync(path.join(candidate, "manifest.json")))
41
+ return candidate;
42
+ }
43
+ throw new Error("Unable to find generated pyraminx solver tables. Run pnpm pyraminx:tables.");
44
+ }
45
+ function getAssetDirectoryCandidates() {
46
+ const cwd = process.cwd();
47
+ const candidates = [
48
+ path.join(cwd, "src", GENERATED_DIRECTORY),
49
+ path.join(cwd, "dist", GENERATED_DIRECTORY),
50
+ path.join(cwd, "dist-cjs", GENERATED_DIRECTORY)
51
+ ];
52
+ try {
53
+ const requireFromCwd = createRequire(path.join(cwd, "package.json"));
54
+ const packageEntry = requireFromCwd.resolve("@cubingcenter/scrambler");
55
+ candidates.push(path.join(path.dirname(packageEntry), GENERATED_DIRECTORY));
56
+ }
57
+ catch {
58
+ // source-tree
59
+ }
60
+ return candidates;
61
+ }
62
+ function assertChecksum(file, actual, expected) {
63
+ if (actual !== expected)
64
+ throw new Error(`Checksum mismatch for ${file}: expected ${expected}, received ${actual}.`);
65
+ }
66
+ function checksum(values) {
67
+ let hash = 0x811c9dc5;
68
+ for (let i = 0; i < values.length; i++) {
69
+ hash ^= values[i];
70
+ hash = Math.imul(hash, 0x01000193);
71
+ }
72
+ return hash >>> 0;
73
+ }
@@ -0,0 +1,10 @@
1
+ import type { PyraminxMove, PyraminxState } from "../types.js";
2
+ export interface PyraminxSolution {
3
+ moves: PyraminxMove[];
4
+ depth: number;
5
+ }
6
+ export declare function solvePyraminx(state: PyraminxState): Promise<PyraminxMove[]>;
7
+ export declare function solvePyraminxWithInfo(state: PyraminxState): Promise<PyraminxSolution>;
8
+ export declare function solvePyraminxSync(state: PyraminxState): PyraminxMove[];
9
+ export declare function verifyPyraminxScramble(state: PyraminxState, finalMoves: readonly PyraminxMove[]): boolean;
10
+ //# sourceMappingURL=search.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"search.d.ts","sourceRoot":"","sources":["../../../../src/puzzles/pyraminx/solver/search.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAgB/D,MAAM,WAAW,gBAAgB;IAC/B,KAAK,EAAE,YAAY,EAAE,CAAC;IACtB,KAAK,EAAE,MAAM,CAAC;CACf;AAED,wBAAsB,aAAa,CAAC,KAAK,EAAE,aAAa,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC,CAGjF;AAED,wBAAsB,qBAAqB,CAAC,KAAK,EAAE,aAAa,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAG3F;AA8BD,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,aAAa,GAAG,YAAY,EAAE,CAGtE;AAaD,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,aAAa,EAAE,UAAU,EAAE,SAAS,YAAY,EAAE,GAAG,OAAO,CAsCzG"}
@@ -0,0 +1,82 @@
1
+ import { POLICY_TABLE, CENTERS_TABLE, PERMUTATION_TABLE, ORIENTATION_TABLE, PYRAMINX_MOVES, MOVE_COUNT, PERMUTATION_COUNT, getCentersIndex, getOrientationIndex, getPermutationCompactIndex, getPolicyMoveFromPacked, ensureTablesLoaded } from "./tables.js";
2
+ export async function solvePyraminx(state) {
3
+ await ensureTablesLoaded();
4
+ return solveWithTables(state).moves;
5
+ }
6
+ export async function solvePyraminxWithInfo(state) {
7
+ await ensureTablesLoaded();
8
+ return solveWithTables(state);
9
+ }
10
+ function solveWithTables(state) {
11
+ const centersTable = CENTERS_TABLE;
12
+ const permTable = PERMUTATION_TABLE;
13
+ const orientTable = ORIENTATION_TABLE;
14
+ const policy = POLICY_TABLE;
15
+ let c = getCentersIndex(state.centers);
16
+ let p = getPermutationCompactIndex(state.edgesPerm);
17
+ let o = getOrientationIndex(state.edgesOrient);
18
+ let stateIndex = c + 81 * (p + PERMUTATION_COUNT * o);
19
+ if (stateIndex === 0)
20
+ return { moves: [], depth: 0 };
21
+ const moves = [];
22
+ while (stateIndex !== 0) {
23
+ const m = getPolicyMoveFromPacked(policy, stateIndex);
24
+ moves.push(PYRAMINX_MOVES[m]);
25
+ c = centersTable[c * MOVE_COUNT + m];
26
+ p = permTable[p * MOVE_COUNT + m];
27
+ o = orientTable[o * MOVE_COUNT + m];
28
+ stateIndex = c + 81 * (p + PERMUTATION_COUNT * o);
29
+ }
30
+ return { moves, depth: moves.length };
31
+ }
32
+ // Synchronous variant for scripts that have already ensured tables are loaded
33
+ export function solvePyraminxSync(state) {
34
+ if (!POLICY_TABLE)
35
+ throw new Error("Pyraminx tables not loaded");
36
+ return solveWithTables(state).moves;
37
+ }
38
+ const MOVE_INDEX = {
39
+ "U": 0, "U'": 1,
40
+ "L": 2, "L'": 3,
41
+ "R": 4, "R'": 5,
42
+ "B": 6, "B'": 7
43
+ };
44
+ const FACE_TIP = { U: 0, L: 1, R: 2, B: 3 };
45
+ const TIP_MOVE = { u: 0, l: 1, r: 2, b: 3 };
46
+ // Applies a full scramble (core + tips) over compact coordinate indexes and
47
+ // compares against the target state. No full state clones; runs in O(moves).
48
+ export function verifyPyraminxScramble(state, finalMoves) {
49
+ const centersTable = CENTERS_TABLE;
50
+ const permTable = PERMUTATION_TABLE;
51
+ const orientTable = ORIENTATION_TABLE;
52
+ if (!centersTable || !permTable || !orientTable) {
53
+ throw new Error("Pyraminx solver tables not loaded. Call ensureTablesLoaded() first.");
54
+ }
55
+ let c = 0;
56
+ let p = 0;
57
+ let o = 0;
58
+ const tips = [0, 0, 0, 0];
59
+ for (const move of finalMoves) {
60
+ const isInverse = move.endsWith("'");
61
+ const base = isInverse ? move.slice(0, -1) : move;
62
+ const faceTip = FACE_TIP[base];
63
+ if (faceTip !== undefined) {
64
+ const m = MOVE_INDEX[move];
65
+ c = centersTable[c * MOVE_COUNT + m];
66
+ p = permTable[p * MOVE_COUNT + m];
67
+ o = orientTable[o * MOVE_COUNT + m];
68
+ tips[faceTip] = (tips[faceTip] + (isInverse ? 2 : 1)) % 3;
69
+ }
70
+ else {
71
+ const tipIndex = TIP_MOVE[base];
72
+ tips[tipIndex] = (tips[tipIndex] + (isInverse ? 2 : 1)) % 3;
73
+ }
74
+ }
75
+ return (c === getCentersIndex(state.centers) &&
76
+ p === getPermutationCompactIndex(state.edgesPerm) &&
77
+ o === getOrientationIndex(state.edgesOrient) &&
78
+ tips[0] === state.tips[0] &&
79
+ tips[1] === state.tips[1] &&
80
+ tips[2] === state.tips[2] &&
81
+ tips[3] === state.tips[3]);
82
+ }
@@ -0,0 +1,20 @@
1
+ export declare const PYRAMINX_SOLVER_TABLE_METADATA: {
2
+ readonly centersTable: {
3
+ readonly entries: 648;
4
+ readonly checksum: 4058180805;
5
+ };
6
+ readonly permutationTable: {
7
+ readonly entries: 2880;
8
+ readonly checksum: 4161414597;
9
+ };
10
+ readonly orientationTable: {
11
+ readonly entries: 256;
12
+ readonly checksum: 3608176069;
13
+ };
14
+ readonly policyTable: {
15
+ readonly entries: 349920;
16
+ readonly checksum: 4047562730;
17
+ readonly maxDepth: 11;
18
+ };
19
+ };
20
+ //# sourceMappingURL=table-metadata.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"table-metadata.d.ts","sourceRoot":"","sources":["../../../../src/puzzles/pyraminx/solver/table-metadata.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,8BAA8B;;;;;;;;;;;;;;;;;;CAkBjC,CAAC"}
@@ -0,0 +1,19 @@
1
+ export const PYRAMINX_SOLVER_TABLE_METADATA = {
2
+ centersTable: {
3
+ entries: 648,
4
+ checksum: 4058180805
5
+ },
6
+ permutationTable: {
7
+ entries: 2880,
8
+ checksum: 4161414597
9
+ },
10
+ orientationTable: {
11
+ entries: 256,
12
+ checksum: 3608176069
13
+ },
14
+ policyTable: {
15
+ entries: 349920,
16
+ checksum: 4047562730,
17
+ maxDepth: 11
18
+ }
19
+ };
@@ -0,0 +1,43 @@
1
+ import type { PyraminxMove, PyraminxState } from "../types.js";
2
+ export declare function getPermutationIndex(perm: readonly number[]): number;
3
+ export declare function getPermutationFromIndex(index: number, n: number): number[];
4
+ export declare function getOrientationIndex(orient: readonly number[]): number;
5
+ export declare function getOrientationFromIndex(index: number): number[];
6
+ export declare function getCentersIndex(centers: readonly number[]): number;
7
+ export declare function getCentersFromIndex(index: number): number[];
8
+ export declare function permutationParity(perm: readonly number[]): number;
9
+ export declare const PERMUTATION_FULL_COUNT = 720;
10
+ export declare const PERMUTATION_COUNT = 360;
11
+ export declare const PERM_720_TO_360: Int16Array<ArrayBuffer>;
12
+ export declare const PERM_360_TO_720: Uint16Array<ArrayBuffer>;
13
+ export declare function getPermutationCompactIndex(perm: readonly number[]): number;
14
+ export declare function getPermutationCompactFromFull(full: number): number;
15
+ export declare function getPermutationFullFromCompact(compact: number): number;
16
+ export declare function getStateIndex(state: PyraminxState): number;
17
+ export declare function getPyraminxStateFromIndex(index: number): PyraminxState;
18
+ export declare const CENTERS_COUNT = 81;
19
+ export declare const ORIENTATION_COUNT = 32;
20
+ export declare const MOVE_COUNT = 8;
21
+ export declare const STATE_COUNT: number;
22
+ export declare const POLICY_PACKED_ENTRIES: number;
23
+ export declare function getPolicyMoveFromPacked(packed: Uint8Array, stateIndex: number): number;
24
+ export declare const PYRAMINX_MOVES: readonly PyraminxMove[];
25
+ export declare function generateCentersTable(): Uint8Array;
26
+ export declare function generatePermutationTable(): Uint16Array;
27
+ export declare function generateOrientationTable(): Uint8Array;
28
+ export declare function generatePolicyTable(centersTable: Uint8Array, permTable: Uint16Array, orientTable: Uint8Array): {
29
+ packed: Uint8Array;
30
+ maxDepth: number;
31
+ };
32
+ export declare function checksum(values: ArrayLike<number>): number;
33
+ export declare let CENTERS_TABLE: Uint8Array | null;
34
+ export declare let PERMUTATION_TABLE: Uint16Array | null;
35
+ export declare let ORIENTATION_TABLE: Uint8Array | null;
36
+ export declare let POLICY_TABLE: Uint8Array | null;
37
+ export declare function ensureTablesLoaded(): Promise<void>;
38
+ export declare function getPolicyMove(stateIndex: number): number;
39
+ export declare function getCentersTransition(centerIdx: number, move: number): number;
40
+ export declare function getPermutationTransition(permIdx: number, move: number): number;
41
+ export declare function getOrientationTransition(orientIdx: number, move: number): number;
42
+ export declare function resetTablesForTests(): void;
43
+ //# sourceMappingURL=tables.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tables.d.ts","sourceRoot":"","sources":["../../../../src/puzzles/pyraminx/solver/tables.ts"],"names":[],"mappings":"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"}