@cubingcenter/scrambler 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +169 -0
- package/dist/cli/index.d.ts +3 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +10 -0
- package/dist/cli/run.d.ts +9 -0
- package/dist/cli/run.d.ts.map +1 -0
- package/dist/cli/run.js +139 -0
- package/dist/core/api.d.ts +19 -0
- package/dist/core/api.d.ts.map +1 -0
- package/dist/core/api.js +94 -0
- package/dist/core/errors.d.ts +21 -0
- package/dist/core/errors.d.ts.map +1 -0
- package/dist/core/errors.js +34 -0
- package/dist/core/index.d.ts +5 -0
- package/dist/core/index.d.ts.map +1 -0
- package/dist/core/index.js +3 -0
- package/dist/core/registry.d.ts +10 -0
- package/dist/core/registry.d.ts.map +1 -0
- package/dist/core/registry.js +35 -0
- package/dist/core/types.d.ts +34 -0
- package/dist/core/types.d.ts.map +1 -0
- package/dist/core/types.js +1 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +3 -0
- package/dist/puzzles/clock/index.d.ts +2 -0
- package/dist/puzzles/clock/index.d.ts.map +1 -0
- package/dist/puzzles/clock/index.js +1 -0
- package/dist/puzzles/clock/scrambler.d.ts +4 -0
- package/dist/puzzles/clock/scrambler.d.ts.map +1 -0
- package/dist/puzzles/clock/scrambler.js +50 -0
- package/dist/puzzles/cube2/facelets.d.ts +5 -0
- package/dist/puzzles/cube2/facelets.d.ts.map +1 -0
- package/dist/puzzles/cube2/facelets.js +53 -0
- package/dist/puzzles/cube2/index.d.ts +10 -0
- package/dist/puzzles/cube2/index.d.ts.map +1 -0
- package/dist/puzzles/cube2/index.js +8 -0
- package/dist/puzzles/cube2/moves.d.ts +9 -0
- package/dist/puzzles/cube2/moves.d.ts.map +1 -0
- package/dist/puzzles/cube2/moves.js +79 -0
- package/dist/puzzles/cube2/random-state.d.ts +3 -0
- package/dist/puzzles/cube2/random-state.d.ts.map +1 -0
- package/dist/puzzles/cube2/random-state.js +51 -0
- package/dist/puzzles/cube2/scrambler.d.ts +6 -0
- package/dist/puzzles/cube2/scrambler.d.ts.map +1 -0
- package/dist/puzzles/cube2/scrambler.js +54 -0
- package/dist/puzzles/cube2/solver/browser-loader.d.ts +12 -0
- package/dist/puzzles/cube2/solver/browser-loader.d.ts.map +1 -0
- package/dist/puzzles/cube2/solver/browser-loader.js +80 -0
- package/dist/puzzles/cube2/solver/generated/distances.bin +1 -0
- package/dist/puzzles/cube2/solver/generated/manifest.json +21 -0
- package/dist/puzzles/cube2/solver/generated/orientation-distances.bin +0 -0
- package/dist/puzzles/cube2/solver/generated/orientation-table.bin +0 -0
- package/dist/puzzles/cube2/solver/generated/permutation-distances.bin +0 -0
- package/dist/puzzles/cube2/solver/generated/permutation-table.bin +0 -0
- package/dist/puzzles/cube2/solver/generated-assets.d.ts +6 -0
- package/dist/puzzles/cube2/solver/generated-assets.d.ts.map +1 -0
- package/dist/puzzles/cube2/solver/generated-assets.js +25 -0
- package/dist/puzzles/cube2/solver/index.d.ts +3 -0
- package/dist/puzzles/cube2/solver/index.d.ts.map +1 -0
- package/dist/puzzles/cube2/solver/index.js +1 -0
- package/dist/puzzles/cube2/solver/node-loader.d.ts +6 -0
- package/dist/puzzles/cube2/solver/node-loader.d.ts.map +1 -0
- package/dist/puzzles/cube2/solver/node-loader.js +83 -0
- package/dist/puzzles/cube2/solver/search.d.ts +8 -0
- package/dist/puzzles/cube2/solver/search.d.ts.map +1 -0
- package/dist/puzzles/cube2/solver/search.js +50 -0
- package/dist/puzzles/cube2/solver/table-metadata.d.ts +16 -0
- package/dist/puzzles/cube2/solver/table-metadata.d.ts.map +1 -0
- package/dist/puzzles/cube2/solver/table-metadata.js +15 -0
- package/dist/puzzles/cube2/solver/tables.d.ts +14 -0
- package/dist/puzzles/cube2/solver/tables.d.ts.map +1 -0
- package/dist/puzzles/cube2/solver/tables.js +82 -0
- package/dist/puzzles/cube2/state.d.ts +6 -0
- package/dist/puzzles/cube2/state.d.ts.map +1 -0
- package/dist/puzzles/cube2/state.js +30 -0
- package/dist/puzzles/cube2/types.d.ts +23 -0
- package/dist/puzzles/cube2/types.d.ts.map +1 -0
- package/dist/puzzles/cube2/types.js +21 -0
- package/dist/puzzles/cube2/validation.d.ts +6 -0
- package/dist/puzzles/cube2/validation.d.ts.map +1 -0
- package/dist/puzzles/cube2/validation.js +72 -0
- package/dist/puzzles/cube3/facelets.d.ts +5 -0
- package/dist/puzzles/cube3/facelets.d.ts.map +1 -0
- package/dist/puzzles/cube3/facelets.js +89 -0
- package/dist/puzzles/cube3/index.d.ts +10 -0
- package/dist/puzzles/cube3/index.d.ts.map +1 -0
- package/dist/puzzles/cube3/index.js +8 -0
- package/dist/puzzles/cube3/moves.d.ts +9 -0
- package/dist/puzzles/cube3/moves.d.ts.map +1 -0
- package/dist/puzzles/cube3/moves.js +210 -0
- package/dist/puzzles/cube3/random-state.d.ts +3 -0
- package/dist/puzzles/cube3/random-state.d.ts.map +1 -0
- package/dist/puzzles/cube3/random-state.js +59 -0
- package/dist/puzzles/cube3/scrambler.d.ts +6 -0
- package/dist/puzzles/cube3/scrambler.d.ts.map +1 -0
- package/dist/puzzles/cube3/scrambler.js +59 -0
- package/dist/puzzles/cube3/solver/browser-loader.d.ts +5 -0
- package/dist/puzzles/cube3/solver/browser-loader.d.ts.map +1 -0
- package/dist/puzzles/cube3/solver/browser-loader.js +134 -0
- package/dist/puzzles/cube3/solver/browser-worker-pool.d.ts +31 -0
- package/dist/puzzles/cube3/solver/browser-worker-pool.d.ts.map +1 -0
- package/dist/puzzles/cube3/solver/browser-worker-pool.js +118 -0
- package/dist/puzzles/cube3/solver/browser-worker.d.ts +2 -0
- package/dist/puzzles/cube3/solver/browser-worker.d.ts.map +1 -0
- package/dist/puzzles/cube3/solver/browser-worker.js +71 -0
- package/dist/puzzles/cube3/solver/coordinates.d.ts +34 -0
- package/dist/puzzles/cube3/solver/coordinates.d.ts.map +1 -0
- package/dist/puzzles/cube3/solver/coordinates.js +266 -0
- package/dist/puzzles/cube3/solver/generated/manifest.json +404 -0
- package/dist/puzzles/cube3/solver/generated/move-cornerOrientation.bin +0 -0
- package/dist/puzzles/cube3/solver/generated/move-cornerPermutation.bin +0 -0
- package/dist/puzzles/cube3/solver/generated/move-edgeOrientation.bin +0 -0
- package/dist/puzzles/cube3/solver/generated/move-slicePermutation.bin +0 -0
- package/dist/puzzles/cube3/solver/generated/move-udEdgePermutation.bin +0 -0
- package/dist/puzzles/cube3/solver/generated/move-udSlice.bin +0 -0
- package/dist/puzzles/cube3/solver/generated/pruning-cornerOrientation.bin +1 -0
- package/dist/puzzles/cube3/solver/generated/pruning-cornerOrientationEdgeOrientation.bin +1 -0
- package/dist/puzzles/cube3/solver/generated/pruning-cornerPermutation.bin +1 -0
- package/dist/puzzles/cube3/solver/generated/pruning-cornerPermutationSlicePermutation.bin +1 -0
- package/dist/puzzles/cube3/solver/generated/pruning-edgeOrientation.bin +1 -0
- package/dist/puzzles/cube3/solver/generated/pruning-slicePermutation.bin +1 -0
- package/dist/puzzles/cube3/solver/generated/pruning-udEdgePermutation.bin +1 -0
- package/dist/puzzles/cube3/solver/generated/pruning-udEdgePermutationSlicePermutation.bin +1 -0
- package/dist/puzzles/cube3/solver/generated/pruning-udSlice.bin +0 -0
- package/dist/puzzles/cube3/solver/generated-assets.d.ts +5 -0
- package/dist/puzzles/cube3/solver/generated-assets.d.ts.map +1 -0
- package/dist/puzzles/cube3/solver/generated-assets.js +60 -0
- package/dist/puzzles/cube3/solver/index.d.ts +10 -0
- package/dist/puzzles/cube3/solver/index.d.ts.map +1 -0
- package/dist/puzzles/cube3/solver/index.js +5 -0
- package/dist/puzzles/cube3/solver/node-loader.d.ts +3 -0
- package/dist/puzzles/cube3/solver/node-loader.d.ts.map +1 -0
- package/dist/puzzles/cube3/solver/node-loader.js +120 -0
- package/dist/puzzles/cube3/solver/phase1.d.ts +28 -0
- package/dist/puzzles/cube3/solver/phase1.d.ts.map +1 -0
- package/dist/puzzles/cube3/solver/phase1.js +150 -0
- package/dist/puzzles/cube3/solver/phase2.d.ts +44 -0
- package/dist/puzzles/cube3/solver/phase2.d.ts.map +1 -0
- package/dist/puzzles/cube3/solver/phase2.js +270 -0
- package/dist/puzzles/cube3/solver/search-utils.d.ts +9 -0
- package/dist/puzzles/cube3/solver/search-utils.d.ts.map +1 -0
- package/dist/puzzles/cube3/solver/search-utils.js +41 -0
- package/dist/puzzles/cube3/solver/table-metadata.d.ts +97 -0
- package/dist/puzzles/cube3/solver/table-metadata.d.ts.map +1 -0
- package/dist/puzzles/cube3/solver/table-metadata.js +21 -0
- package/dist/puzzles/cube3/solver/tables.d.ts +72 -0
- package/dist/puzzles/cube3/solver/tables.d.ts.map +1 -0
- package/dist/puzzles/cube3/solver/tables.js +202 -0
- package/dist/puzzles/cube3/solver/worker-pool.d.ts +18 -0
- package/dist/puzzles/cube3/solver/worker-pool.d.ts.map +1 -0
- package/dist/puzzles/cube3/solver/worker-pool.js +116 -0
- package/dist/puzzles/cube3/solver/worker.d.ts +2 -0
- package/dist/puzzles/cube3/solver/worker.d.ts.map +1 -0
- package/dist/puzzles/cube3/solver/worker.js +73 -0
- package/dist/puzzles/cube3/state.d.ts +6 -0
- package/dist/puzzles/cube3/state.d.ts.map +1 -0
- package/dist/puzzles/cube3/state.js +40 -0
- package/dist/puzzles/cube3/subset-state.d.ts +4 -0
- package/dist/puzzles/cube3/subset-state.d.ts.map +1 -0
- package/dist/puzzles/cube3/subset-state.js +163 -0
- package/dist/puzzles/cube3/types.d.ts +29 -0
- package/dist/puzzles/cube3/types.d.ts.map +1 -0
- package/dist/puzzles/cube3/types.js +22 -0
- package/dist/puzzles/cube3/validation.d.ts +6 -0
- package/dist/puzzles/cube3/validation.d.ts.map +1 -0
- package/dist/puzzles/cube3/validation.js +83 -0
- package/dist/puzzles/cube4/facelets.d.ts +5 -0
- package/dist/puzzles/cube4/facelets.d.ts.map +1 -0
- package/dist/puzzles/cube4/facelets.js +135 -0
- package/dist/puzzles/cube4/index.d.ts +7 -0
- package/dist/puzzles/cube4/index.d.ts.map +1 -0
- package/dist/puzzles/cube4/index.js +8 -0
- package/dist/puzzles/cube4/moves.d.ts +37 -0
- package/dist/puzzles/cube4/moves.d.ts.map +1 -0
- package/dist/puzzles/cube4/moves.js +243 -0
- package/dist/puzzles/cube4/scrambler.d.ts +4 -0
- package/dist/puzzles/cube4/scrambler.d.ts.map +1 -0
- package/dist/puzzles/cube4/scrambler.js +98 -0
- package/dist/puzzles/cube4/state.d.ts +16 -0
- package/dist/puzzles/cube4/state.d.ts.map +1 -0
- package/dist/puzzles/cube4/state.js +84 -0
- package/dist/puzzles/cube4/types.d.ts +76 -0
- package/dist/puzzles/cube4/types.d.ts.map +1 -0
- package/dist/puzzles/cube4/types.js +62 -0
- package/dist/puzzles/cube5x5/index.d.ts +4 -0
- package/dist/puzzles/cube5x5/index.d.ts.map +1 -0
- package/dist/puzzles/cube5x5/index.js +2 -0
- package/dist/puzzles/cube5x5/scrambler.d.ts +4 -0
- package/dist/puzzles/cube5x5/scrambler.d.ts.map +1 -0
- package/dist/puzzles/cube5x5/scrambler.js +93 -0
- package/dist/puzzles/cube5x5/types.d.ts +4 -0
- package/dist/puzzles/cube5x5/types.d.ts.map +1 -0
- package/dist/puzzles/cube5x5/types.js +4 -0
- package/dist/puzzles/cube6x6/index.d.ts +4 -0
- package/dist/puzzles/cube6x6/index.d.ts.map +1 -0
- package/dist/puzzles/cube6x6/index.js +2 -0
- package/dist/puzzles/cube6x6/scrambler.d.ts +4 -0
- package/dist/puzzles/cube6x6/scrambler.d.ts.map +1 -0
- package/dist/puzzles/cube6x6/scrambler.js +105 -0
- package/dist/puzzles/cube6x6/types.d.ts +4 -0
- package/dist/puzzles/cube6x6/types.d.ts.map +1 -0
- package/dist/puzzles/cube6x6/types.js +8 -0
- package/dist/puzzles/cube7x7/index.d.ts +4 -0
- package/dist/puzzles/cube7x7/index.d.ts.map +1 -0
- package/dist/puzzles/cube7x7/index.js +2 -0
- package/dist/puzzles/cube7x7/scrambler.d.ts +4 -0
- package/dist/puzzles/cube7x7/scrambler.d.ts.map +1 -0
- package/dist/puzzles/cube7x7/scrambler.js +93 -0
- package/dist/puzzles/cube7x7/types.d.ts +4 -0
- package/dist/puzzles/cube7x7/types.d.ts.map +1 -0
- package/dist/puzzles/cube7x7/types.js +8 -0
- package/dist/puzzles/index.d.ts +10 -0
- package/dist/puzzles/index.d.ts.map +1 -0
- package/dist/puzzles/index.js +28 -0
- package/dist/puzzles/megaminx/index.d.ts +4 -0
- package/dist/puzzles/megaminx/index.d.ts.map +1 -0
- package/dist/puzzles/megaminx/index.js +2 -0
- package/dist/puzzles/megaminx/scrambler.d.ts +4 -0
- package/dist/puzzles/megaminx/scrambler.d.ts.map +1 -0
- package/dist/puzzles/megaminx/scrambler.js +56 -0
- package/dist/puzzles/megaminx/types.d.ts +6 -0
- package/dist/puzzles/megaminx/types.d.ts.map +1 -0
- package/dist/puzzles/megaminx/types.js +4 -0
- package/dist/puzzles/pyraminx/index.d.ts +9 -0
- package/dist/puzzles/pyraminx/index.d.ts.map +1 -0
- package/dist/puzzles/pyraminx/index.js +7 -0
- package/dist/puzzles/pyraminx/moves.d.ts +9 -0
- package/dist/puzzles/pyraminx/moves.d.ts.map +1 -0
- package/dist/puzzles/pyraminx/moves.js +117 -0
- package/dist/puzzles/pyraminx/random-state.d.ts +3 -0
- package/dist/puzzles/pyraminx/random-state.d.ts.map +1 -0
- package/dist/puzzles/pyraminx/random-state.js +53 -0
- package/dist/puzzles/pyraminx/scrambler.d.ts +6 -0
- package/dist/puzzles/pyraminx/scrambler.d.ts.map +1 -0
- package/dist/puzzles/pyraminx/scrambler.js +56 -0
- package/dist/puzzles/pyraminx/solver.d.ts +10 -0
- package/dist/puzzles/pyraminx/solver.d.ts.map +1 -0
- package/dist/puzzles/pyraminx/solver.js +160 -0
- package/dist/puzzles/pyraminx/state.d.ts +6 -0
- package/dist/puzzles/pyraminx/state.d.ts.map +1 -0
- package/dist/puzzles/pyraminx/state.js +32 -0
- package/dist/puzzles/pyraminx/types.d.ts +17 -0
- package/dist/puzzles/pyraminx/types.d.ts.map +1 -0
- package/dist/puzzles/pyraminx/types.js +7 -0
- package/dist/puzzles/pyraminx/validation.d.ts +8 -0
- package/dist/puzzles/pyraminx/validation.d.ts.map +1 -0
- package/dist/puzzles/pyraminx/validation.js +79 -0
- package/dist/random/index.d.ts +3 -0
- package/dist/random/index.d.ts.map +1 -0
- package/dist/random/index.js +1 -0
- package/dist/random/prng.d.ts +7 -0
- package/dist/random/prng.d.ts.map +1 -0
- package/dist/random/prng.js +60 -0
- package/dist-cjs/cli/index.js +12 -0
- package/dist-cjs/cli/run.js +142 -0
- package/dist-cjs/core/api.js +102 -0
- package/dist-cjs/core/errors.js +42 -0
- package/dist-cjs/core/index.js +19 -0
- package/dist-cjs/core/registry.js +39 -0
- package/dist-cjs/core/types.js +2 -0
- package/dist-cjs/index.js +19 -0
- package/dist-cjs/package.json +3 -0
- package/dist-cjs/puzzles/clock/index.js +6 -0
- package/dist-cjs/puzzles/clock/scrambler.js +54 -0
- package/dist-cjs/puzzles/cube2/facelets.js +58 -0
- package/dist-cjs/puzzles/cube2/index.js +67 -0
- package/dist-cjs/puzzles/cube2/moves.js +88 -0
- package/dist-cjs/puzzles/cube2/random-state.js +54 -0
- package/dist-cjs/puzzles/cube2/scrambler.js +58 -0
- package/dist-cjs/puzzles/cube2/solver/browser-loader.js +85 -0
- package/dist-cjs/puzzles/cube2/solver/generated/distances.bin +1 -0
- package/dist-cjs/puzzles/cube2/solver/generated/manifest.json +21 -0
- package/dist-cjs/puzzles/cube2/solver/generated/orientation-distances.bin +0 -0
- package/dist-cjs/puzzles/cube2/solver/generated/orientation-table.bin +0 -0
- package/dist-cjs/puzzles/cube2/solver/generated/permutation-distances.bin +0 -0
- package/dist-cjs/puzzles/cube2/solver/generated/permutation-table.bin +0 -0
- package/dist-cjs/puzzles/cube2/solver/generated-assets.js +61 -0
- package/dist-cjs/puzzles/cube2/solver/index.js +5 -0
- package/dist-cjs/puzzles/cube2/solver/node-loader.js +89 -0
- package/dist-cjs/puzzles/cube2/solver/search.js +53 -0
- package/dist-cjs/puzzles/cube2/solver/table-metadata.js +18 -0
- package/dist-cjs/puzzles/cube2/solver/tables.js +91 -0
- package/dist-cjs/puzzles/cube2/state.js +36 -0
- package/dist-cjs/puzzles/cube2/types.js +24 -0
- package/dist-cjs/puzzles/cube2/validation.js +78 -0
- package/dist-cjs/puzzles/cube3/facelets.js +94 -0
- package/dist-cjs/puzzles/cube3/index.js +68 -0
- package/dist-cjs/puzzles/cube3/moves.js +219 -0
- package/dist-cjs/puzzles/cube3/random-state.js +62 -0
- package/dist-cjs/puzzles/cube3/scrambler.js +63 -0
- package/dist-cjs/puzzles/cube3/solver/browser-loader.js +139 -0
- package/dist-cjs/puzzles/cube3/solver/coordinates.js +285 -0
- package/dist-cjs/puzzles/cube3/solver/generated/manifest.json +404 -0
- package/dist-cjs/puzzles/cube3/solver/generated/move-cornerOrientation.bin +0 -0
- package/dist-cjs/puzzles/cube3/solver/generated/move-cornerPermutation.bin +0 -0
- package/dist-cjs/puzzles/cube3/solver/generated/move-edgeOrientation.bin +0 -0
- package/dist-cjs/puzzles/cube3/solver/generated/move-slicePermutation.bin +0 -0
- package/dist-cjs/puzzles/cube3/solver/generated/move-udEdgePermutation.bin +0 -0
- package/dist-cjs/puzzles/cube3/solver/generated/move-udSlice.bin +0 -0
- package/dist-cjs/puzzles/cube3/solver/generated/pruning-cornerOrientation.bin +1 -0
- package/dist-cjs/puzzles/cube3/solver/generated/pruning-cornerOrientationEdgeOrientation.bin +1 -0
- package/dist-cjs/puzzles/cube3/solver/generated/pruning-cornerPermutation.bin +1 -0
- package/dist-cjs/puzzles/cube3/solver/generated/pruning-cornerPermutationSlicePermutation.bin +1 -0
- package/dist-cjs/puzzles/cube3/solver/generated/pruning-edgeOrientation.bin +1 -0
- package/dist-cjs/puzzles/cube3/solver/generated/pruning-slicePermutation.bin +1 -0
- package/dist-cjs/puzzles/cube3/solver/generated/pruning-udEdgePermutation.bin +1 -0
- package/dist-cjs/puzzles/cube3/solver/generated/pruning-udEdgePermutationSlicePermutation.bin +1 -0
- package/dist-cjs/puzzles/cube3/solver/generated/pruning-udSlice.bin +0 -0
- package/dist-cjs/puzzles/cube3/solver/generated-assets.js +98 -0
- package/dist-cjs/puzzles/cube3/solver/index.js +49 -0
- package/dist-cjs/puzzles/cube3/solver/node-loader.js +126 -0
- package/dist-cjs/puzzles/cube3/solver/phase1.js +158 -0
- package/dist-cjs/puzzles/cube3/solver/phase2.js +279 -0
- package/dist-cjs/puzzles/cube3/solver/search-utils.js +49 -0
- package/dist-cjs/puzzles/cube3/solver/table-metadata.js +24 -0
- package/dist-cjs/puzzles/cube3/solver/tables.js +216 -0
- package/dist-cjs/puzzles/cube3/state.js +46 -0
- package/dist-cjs/puzzles/cube3/subset-state.js +166 -0
- package/dist-cjs/puzzles/cube3/types.js +25 -0
- package/dist-cjs/puzzles/cube3/validation.js +89 -0
- package/dist-cjs/puzzles/cube4/facelets.js +140 -0
- package/dist-cjs/puzzles/cube4/index.js +45 -0
- package/dist-cjs/puzzles/cube4/moves.js +251 -0
- package/dist-cjs/puzzles/cube4/scrambler.js +135 -0
- package/dist-cjs/puzzles/cube4/state.js +92 -0
- package/dist-cjs/puzzles/cube4/types.js +65 -0
- package/dist-cjs/puzzles/cube5x5/index.js +9 -0
- package/dist-cjs/puzzles/cube5x5/scrambler.js +97 -0
- package/dist-cjs/puzzles/cube5x5/types.js +7 -0
- package/dist-cjs/puzzles/cube6x6/index.js +9 -0
- package/dist-cjs/puzzles/cube6x6/scrambler.js +109 -0
- package/dist-cjs/puzzles/cube6x6/types.js +11 -0
- package/dist-cjs/puzzles/cube7x7/index.js +9 -0
- package/dist-cjs/puzzles/cube7x7/scrambler.js +97 -0
- package/dist-cjs/puzzles/cube7x7/types.js +11 -0
- package/dist-cjs/puzzles/index.js +64 -0
- package/dist-cjs/puzzles/megaminx/index.js +11 -0
- package/dist-cjs/puzzles/megaminx/scrambler.js +60 -0
- package/dist-cjs/puzzles/megaminx/types.js +7 -0
- package/dist-cjs/puzzles/pyraminx/index.js +30 -0
- package/dist-cjs/puzzles/pyraminx/moves.js +126 -0
- package/dist-cjs/puzzles/pyraminx/random-state.js +56 -0
- package/dist-cjs/puzzles/pyraminx/scrambler.js +60 -0
- package/dist-cjs/puzzles/pyraminx/solver.js +170 -0
- package/dist-cjs/puzzles/pyraminx/state.js +38 -0
- package/dist-cjs/puzzles/pyraminx/types.js +10 -0
- package/dist-cjs/puzzles/pyraminx/validation.js +84 -0
- package/dist-cjs/random/index.js +5 -0
- package/dist-cjs/random/prng.js +63 -0
- package/docs/cubingcenter-integration.md +69 -0
- package/docs/development.md +44 -0
- package/docs/facelets.md +64 -0
- package/docs/getting-started.md +73 -0
- package/examples/cli-json.md +30 -0
- package/examples/commonjs.cjs +11 -0
- package/examples/esm.mjs +9 -0
- package/examples/timer-preview.mjs +29 -0
- package/package.json +53 -0
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.getPermutationIndex = getPermutationIndex;
|
|
4
|
+
exports.getPermutationFromIndex = getPermutationFromIndex;
|
|
5
|
+
exports.getOrientationIndex = getOrientationIndex;
|
|
6
|
+
exports.getOrientationFromIndex = getOrientationFromIndex;
|
|
7
|
+
exports.getCentersIndex = getCentersIndex;
|
|
8
|
+
exports.getCentersFromIndex = getCentersFromIndex;
|
|
9
|
+
exports.getStateIndex = getStateIndex;
|
|
10
|
+
exports.solvePyraminx = solvePyraminx;
|
|
11
|
+
const moves_js_1 = require("./moves.js");
|
|
12
|
+
const state_js_1 = require("./state.js");
|
|
13
|
+
// Fast state-to-index encoder/decoder to allow optimal BFS solving
|
|
14
|
+
// Factorials for permutation encoding
|
|
15
|
+
const FACT = [1, 1, 2, 6, 24, 120, 720];
|
|
16
|
+
function getPermutationIndex(perm) {
|
|
17
|
+
let index = 0;
|
|
18
|
+
const n = perm.length;
|
|
19
|
+
for (let i = 0; i < n; i++) {
|
|
20
|
+
let count = 0;
|
|
21
|
+
for (let j = i + 1; j < n; j++) {
|
|
22
|
+
if (perm[j] < perm[i])
|
|
23
|
+
count++;
|
|
24
|
+
}
|
|
25
|
+
index += count * FACT[n - 1 - i];
|
|
26
|
+
}
|
|
27
|
+
return index;
|
|
28
|
+
}
|
|
29
|
+
function getPermutationFromIndex(index, n) {
|
|
30
|
+
const perm = Array(n).fill(0);
|
|
31
|
+
const temp = Array.from({ length: n }, (_, i) => i);
|
|
32
|
+
let val = index;
|
|
33
|
+
for (let i = 0; i < n; i++) {
|
|
34
|
+
const f = FACT[n - 1 - i];
|
|
35
|
+
const choice = Math.floor(val / f);
|
|
36
|
+
val %= f;
|
|
37
|
+
perm[i] = temp[choice];
|
|
38
|
+
temp.splice(choice, 1);
|
|
39
|
+
}
|
|
40
|
+
return perm;
|
|
41
|
+
}
|
|
42
|
+
function getOrientationIndex(orient) {
|
|
43
|
+
let index = 0;
|
|
44
|
+
for (let i = 0; i < 5; i++) {
|
|
45
|
+
index = (index << 1) | orient[i];
|
|
46
|
+
}
|
|
47
|
+
return index;
|
|
48
|
+
}
|
|
49
|
+
function getOrientationFromIndex(index) {
|
|
50
|
+
const orient = Array(6).fill(0);
|
|
51
|
+
let temp = index;
|
|
52
|
+
let sum = 0;
|
|
53
|
+
for (let i = 4; i >= 0; i--) {
|
|
54
|
+
const bit = temp & 1;
|
|
55
|
+
orient[i] = bit;
|
|
56
|
+
sum += bit;
|
|
57
|
+
temp >>= 1;
|
|
58
|
+
}
|
|
59
|
+
orient[5] = sum % 2 === 0 ? 0 : 1;
|
|
60
|
+
return orient;
|
|
61
|
+
}
|
|
62
|
+
function getCentersIndex(centers) {
|
|
63
|
+
return centers[0] + 3 * centers[1] + 9 * centers[2] + 27 * centers[3];
|
|
64
|
+
}
|
|
65
|
+
function getCentersFromIndex(index) {
|
|
66
|
+
let temp = index;
|
|
67
|
+
const centers = Array(4).fill(0);
|
|
68
|
+
for (let i = 0; i < 4; i++) {
|
|
69
|
+
centers[i] = temp % 3;
|
|
70
|
+
temp = Math.floor(temp / 3);
|
|
71
|
+
}
|
|
72
|
+
return centers;
|
|
73
|
+
}
|
|
74
|
+
function getStateIndex(state) {
|
|
75
|
+
const c = getCentersIndex(state.centers);
|
|
76
|
+
const p = getPermutationIndex(state.edgesPerm);
|
|
77
|
+
const o = getOrientationIndex(state.edgesOrient);
|
|
78
|
+
// c is 0..80, p is 0..719, o is 0..31
|
|
79
|
+
return c + 81 * (p + 720 * o);
|
|
80
|
+
}
|
|
81
|
+
// Bidirectional BFS solver
|
|
82
|
+
const MOVES = ["U", "U'", "L", "L'", "R", "R'", "B", "B'"];
|
|
83
|
+
function solvePyraminx(state) {
|
|
84
|
+
const startIdx = getStateIndex(state);
|
|
85
|
+
const solvedIdx = getStateIndex((0, state_js_1.createSolvedPyraminxState)());
|
|
86
|
+
if (startIdx === solvedIdx)
|
|
87
|
+
return [];
|
|
88
|
+
// Bidirectional BFS:
|
|
89
|
+
// forwardMap and backwardMap store the move that led to this index and the parent index
|
|
90
|
+
const forwardMap = new Map();
|
|
91
|
+
const backwardMap = new Map();
|
|
92
|
+
const forwardQueue = [startIdx];
|
|
93
|
+
const backwardQueue = [solvedIdx];
|
|
94
|
+
forwardMap.set(startIdx, { move: "", parent: -1 });
|
|
95
|
+
backwardMap.set(solvedIdx, { move: "", parent: -1 });
|
|
96
|
+
while (forwardQueue.length > 0 && backwardQueue.length > 0) {
|
|
97
|
+
// Expand forward
|
|
98
|
+
const fSize = forwardQueue.length;
|
|
99
|
+
for (let i = 0; i < Math.min(fSize, 1000); i++) {
|
|
100
|
+
const currIdx = forwardQueue.shift();
|
|
101
|
+
const currState = getPyraminxStateFromIndex(currIdx);
|
|
102
|
+
for (const move of MOVES) {
|
|
103
|
+
const nextState = (0, moves_js_1.applyPyraminxMove)(currState, move);
|
|
104
|
+
const nextIdx = getStateIndex(nextState);
|
|
105
|
+
if (!forwardMap.has(nextIdx)) {
|
|
106
|
+
forwardMap.set(nextIdx, { move, parent: currIdx });
|
|
107
|
+
if (backwardMap.has(nextIdx)) {
|
|
108
|
+
return reconstructPath(nextIdx, forwardMap, backwardMap);
|
|
109
|
+
}
|
|
110
|
+
forwardQueue.push(nextIdx);
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
// Expand backward
|
|
115
|
+
const bSize = backwardQueue.length;
|
|
116
|
+
for (let i = 0; i < Math.min(bSize, 1000); i++) {
|
|
117
|
+
const currIdx = backwardQueue.shift();
|
|
118
|
+
const currState = getPyraminxStateFromIndex(currIdx);
|
|
119
|
+
for (const move of MOVES) {
|
|
120
|
+
const nextState = (0, moves_js_1.applyPyraminxMove)(currState, move);
|
|
121
|
+
const nextIdx = getStateIndex(nextState);
|
|
122
|
+
if (!backwardMap.has(nextIdx)) {
|
|
123
|
+
// Note: we record the inverse move since we are searching from solved
|
|
124
|
+
const invMove = move.endsWith("'") ? move.slice(0, -1) : `${move}'`;
|
|
125
|
+
backwardMap.set(nextIdx, { move: invMove, parent: currIdx });
|
|
126
|
+
if (forwardMap.has(nextIdx)) {
|
|
127
|
+
return reconstructPath(nextIdx, forwardMap, backwardMap);
|
|
128
|
+
}
|
|
129
|
+
backwardQueue.push(nextIdx);
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
throw new Error("Pyraminx state is unsolvable");
|
|
135
|
+
}
|
|
136
|
+
function getPyraminxStateFromIndex(index) {
|
|
137
|
+
let val = index;
|
|
138
|
+
const centersIdx = val % 81;
|
|
139
|
+
val = Math.floor(val / 81);
|
|
140
|
+
const permIdx = val % 720;
|
|
141
|
+
const orientIdx = Math.floor(val / 720);
|
|
142
|
+
return {
|
|
143
|
+
centers: getCentersFromIndex(centersIdx),
|
|
144
|
+
edgesPerm: getPermutationFromIndex(permIdx, 6),
|
|
145
|
+
edgesOrient: getOrientationFromIndex(orientIdx),
|
|
146
|
+
tips: [0, 0, 0, 0] // tips are solved separately
|
|
147
|
+
};
|
|
148
|
+
}
|
|
149
|
+
function reconstructPath(meetingIdx, forwardMap, backwardMap) {
|
|
150
|
+
const path = [];
|
|
151
|
+
// Reconstruct forward path
|
|
152
|
+
let curr = meetingIdx;
|
|
153
|
+
while (curr !== -1) {
|
|
154
|
+
const edge = forwardMap.get(curr);
|
|
155
|
+
if (edge.parent !== -1) {
|
|
156
|
+
path.unshift(edge.move);
|
|
157
|
+
}
|
|
158
|
+
curr = edge.parent;
|
|
159
|
+
}
|
|
160
|
+
// Reconstruct backward path
|
|
161
|
+
curr = meetingIdx;
|
|
162
|
+
while (curr !== -1) {
|
|
163
|
+
const edge = backwardMap.get(curr);
|
|
164
|
+
if (edge.parent !== -1) {
|
|
165
|
+
path.push(edge.move);
|
|
166
|
+
}
|
|
167
|
+
curr = edge.parent;
|
|
168
|
+
}
|
|
169
|
+
return path;
|
|
170
|
+
}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.createSolvedPyraminxState = createSolvedPyraminxState;
|
|
4
|
+
exports.clonePyraminxState = clonePyraminxState;
|
|
5
|
+
exports.pyraminxStatesEqual = pyraminxStatesEqual;
|
|
6
|
+
exports.isSolvedPyraminxState = isSolvedPyraminxState;
|
|
7
|
+
function createSolvedPyraminxState() {
|
|
8
|
+
return {
|
|
9
|
+
centers: [0, 0, 0, 0],
|
|
10
|
+
edgesPerm: [0, 1, 2, 3, 4, 5],
|
|
11
|
+
edgesOrient: [0, 0, 0, 0, 0, 0],
|
|
12
|
+
tips: [0, 0, 0, 0]
|
|
13
|
+
};
|
|
14
|
+
}
|
|
15
|
+
function clonePyraminxState(state) {
|
|
16
|
+
return {
|
|
17
|
+
centers: [...state.centers],
|
|
18
|
+
edgesPerm: [...state.edgesPerm],
|
|
19
|
+
edgesOrient: [...state.edgesOrient],
|
|
20
|
+
tips: [...state.tips]
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
function pyraminxStatesEqual(left, right) {
|
|
24
|
+
return (arraysEqual(left.centers, right.centers) &&
|
|
25
|
+
arraysEqual(left.edgesPerm, right.edgesPerm) &&
|
|
26
|
+
arraysEqual(left.edgesOrient, right.edgesOrient) &&
|
|
27
|
+
arraysEqual(left.tips, right.tips));
|
|
28
|
+
}
|
|
29
|
+
function isSolvedPyraminxState(state) {
|
|
30
|
+
return (state.centers.every(c => c === 0) &&
|
|
31
|
+
state.edgesPerm.every((e, idx) => e === idx) &&
|
|
32
|
+
state.edgesOrient.every(o => o === 0)
|
|
33
|
+
// tips don't have to be 0 for the core to be solved in the state-matching, but for full solved they do
|
|
34
|
+
);
|
|
35
|
+
}
|
|
36
|
+
function arraysEqual(left, right) {
|
|
37
|
+
return left.length === right.length && left.every((value, index) => value === right[index]);
|
|
38
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.PYRAMINX_TIPS = exports.PYRAMINX_CORE_MOVES = void 0;
|
|
4
|
+
exports.PYRAMINX_CORE_MOVES = [
|
|
5
|
+
"U", "U'",
|
|
6
|
+
"L", "L'",
|
|
7
|
+
"R", "R'",
|
|
8
|
+
"B", "B'"
|
|
9
|
+
];
|
|
10
|
+
exports.PYRAMINX_TIPS = ["u", "l", "r", "b"];
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.validatePyraminxState = validatePyraminxState;
|
|
4
|
+
exports.permutationParity = permutationParity;
|
|
5
|
+
exports.isAllowedRandomPyraminxState = isAllowedRandomPyraminxState;
|
|
6
|
+
const state_js_1 = require("./state.js");
|
|
7
|
+
function validatePyraminxState(state) {
|
|
8
|
+
const errors = [];
|
|
9
|
+
// 1. Centers validation
|
|
10
|
+
if (state.centers.length !== 4) {
|
|
11
|
+
errors.push("Centers must contain 4 values.");
|
|
12
|
+
}
|
|
13
|
+
else {
|
|
14
|
+
for (const val of state.centers) {
|
|
15
|
+
if (val < 0 || val > 2 || !Number.isInteger(val)) {
|
|
16
|
+
errors.push(`Center orientation out of range: ${val}`);
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
// 2. Tips validation
|
|
21
|
+
if (state.tips.length !== 4) {
|
|
22
|
+
errors.push("Tips must contain 4 values.");
|
|
23
|
+
}
|
|
24
|
+
else {
|
|
25
|
+
for (const val of state.tips) {
|
|
26
|
+
if (val < 0 || val > 2 || !Number.isInteger(val)) {
|
|
27
|
+
errors.push(`Tip orientation out of range: ${val}`);
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
// 3. Edges Permutation validation
|
|
32
|
+
if (state.edgesPerm.length !== 6) {
|
|
33
|
+
errors.push("Edges permutation must contain 6 values.");
|
|
34
|
+
}
|
|
35
|
+
else {
|
|
36
|
+
const seen = new Set();
|
|
37
|
+
for (const val of state.edgesPerm) {
|
|
38
|
+
if (val < 0 || val > 5 || !Number.isInteger(val) || seen.has(val)) {
|
|
39
|
+
errors.push(`Invalid edge permutation value: ${val}`);
|
|
40
|
+
}
|
|
41
|
+
seen.add(val);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
// 4. Edges Orientation validation
|
|
45
|
+
if (state.edgesOrient.length !== 6) {
|
|
46
|
+
errors.push("Edges orientation must contain 6 values.");
|
|
47
|
+
}
|
|
48
|
+
else {
|
|
49
|
+
let sumOrient = 0;
|
|
50
|
+
for (const val of state.edgesOrient) {
|
|
51
|
+
if (val < 0 || val > 1 || !Number.isInteger(val)) {
|
|
52
|
+
errors.push(`Edge orientation out of range: ${val}`);
|
|
53
|
+
}
|
|
54
|
+
sumOrient += val;
|
|
55
|
+
}
|
|
56
|
+
if (sumOrient % 2 !== 0) {
|
|
57
|
+
errors.push("Edge orientation sum must be even.");
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
// 5. Permutation parity validation
|
|
61
|
+
if (errors.length === 0) {
|
|
62
|
+
if (permutationParity(state.edgesPerm) !== 0) {
|
|
63
|
+
errors.push("Edge permutation parity must be even.");
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
return {
|
|
67
|
+
valid: errors.length === 0,
|
|
68
|
+
errors
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
function permutationParity(permutation) {
|
|
72
|
+
let inversions = 0;
|
|
73
|
+
for (let left = 0; left < permutation.length; left += 1) {
|
|
74
|
+
for (let right = left + 1; right < permutation.length; right += 1) {
|
|
75
|
+
if (permutation[left] > permutation[right]) {
|
|
76
|
+
inversions += 1;
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
return inversions % 2;
|
|
81
|
+
}
|
|
82
|
+
function isAllowedRandomPyraminxState(state) {
|
|
83
|
+
return validatePyraminxState(state).valid && !(0, state_js_1.isSolvedPyraminxState)(state);
|
|
84
|
+
}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.createRandomSource = void 0;
|
|
4
|
+
var prng_js_1 = require("./prng.js");
|
|
5
|
+
Object.defineProperty(exports, "createRandomSource", { enumerable: true, get: function () { return prng_js_1.createRandomSource; } });
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.createRandomSource = createRandomSource;
|
|
4
|
+
const node_crypto_1 = require("node:crypto");
|
|
5
|
+
function createRandomSource(seed) {
|
|
6
|
+
if (seed === undefined) {
|
|
7
|
+
return new CryptoRandomSource();
|
|
8
|
+
}
|
|
9
|
+
return new SeededRandomSource(hashSeed(seed));
|
|
10
|
+
}
|
|
11
|
+
class CryptoRandomSource {
|
|
12
|
+
next() {
|
|
13
|
+
const value = (0, node_crypto_1.randomBytes)(6).readUIntBE(0, 6);
|
|
14
|
+
return value / 0x1000000000000;
|
|
15
|
+
}
|
|
16
|
+
nextInt(maxExclusive) {
|
|
17
|
+
validateMax(maxExclusive);
|
|
18
|
+
return Math.floor(this.next() * maxExclusive);
|
|
19
|
+
}
|
|
20
|
+
choice(items) {
|
|
21
|
+
if (items.length === 0) {
|
|
22
|
+
throw new RangeError("Cannot choose from an empty collection.");
|
|
23
|
+
}
|
|
24
|
+
return items[this.nextInt(items.length)];
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
class SeededRandomSource {
|
|
28
|
+
state;
|
|
29
|
+
constructor(seed) {
|
|
30
|
+
this.state = seed >>> 0;
|
|
31
|
+
}
|
|
32
|
+
next() {
|
|
33
|
+
this.state += 0x6d2b79f5;
|
|
34
|
+
let value = this.state;
|
|
35
|
+
value = Math.imul(value ^ (value >>> 15), value | 1);
|
|
36
|
+
value ^= value + Math.imul(value ^ (value >>> 7), value | 61);
|
|
37
|
+
return ((value ^ (value >>> 14)) >>> 0) / 0x100000000;
|
|
38
|
+
}
|
|
39
|
+
nextInt(maxExclusive) {
|
|
40
|
+
validateMax(maxExclusive);
|
|
41
|
+
return Math.floor(this.next() * maxExclusive);
|
|
42
|
+
}
|
|
43
|
+
choice(items) {
|
|
44
|
+
if (items.length === 0) {
|
|
45
|
+
throw new RangeError("Cannot choose from an empty collection.");
|
|
46
|
+
}
|
|
47
|
+
return items[this.nextInt(items.length)];
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
function validateMax(maxExclusive) {
|
|
51
|
+
if (!Number.isInteger(maxExclusive) || maxExclusive < 1) {
|
|
52
|
+
throw new RangeError(`maxExclusive must be a positive integer. Received: ${maxExclusive}`);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
function hashSeed(seed) {
|
|
56
|
+
const text = String(seed);
|
|
57
|
+
let hash = 0x811c9dc5;
|
|
58
|
+
for (let index = 0; index < text.length; index += 1) {
|
|
59
|
+
hash ^= text.charCodeAt(index);
|
|
60
|
+
hash = Math.imul(hash, 0x01000193);
|
|
61
|
+
}
|
|
62
|
+
return hash >>> 0;
|
|
63
|
+
}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
# CubingCenter Integration
|
|
2
|
+
|
|
3
|
+
Use the root API for timer-facing scramble generation.
|
|
4
|
+
|
|
5
|
+
## Generate One Scramble
|
|
6
|
+
|
|
7
|
+
```ts
|
|
8
|
+
import { generateScramble } from "@cubingcenter/scrambler";
|
|
9
|
+
|
|
10
|
+
const result = generateScramble("222", { seed: "session-42" });
|
|
11
|
+
// or
|
|
12
|
+
const result3x3 = generateScramble("333", { seed: "session-42" });
|
|
13
|
+
|
|
14
|
+
const scrambleText = result.scramble;
|
|
15
|
+
const moves = result.moves;
|
|
16
|
+
const metadata = result.metadata;
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
### 2x2 (`222`) metadata
|
|
20
|
+
|
|
21
|
+
- `state`: target cubie state.
|
|
22
|
+
- `facelets`: six row-major faces keyed by `U R F D L B`.
|
|
23
|
+
- `faceletString`: 24-character string in `U R F D L B` face order.
|
|
24
|
+
- `solutionMoves`: internal solver solution from target state to solved.
|
|
25
|
+
- `solutionDepth`: solver move count.
|
|
26
|
+
|
|
27
|
+
### 3x3 (`333`) metadata
|
|
28
|
+
|
|
29
|
+
- `state`: target cubie state.
|
|
30
|
+
- `facelets`: six row-major faces keyed by `U R F D L B`.
|
|
31
|
+
- `faceletString`: 54-character string in `U R F D L B` face order.
|
|
32
|
+
- `solutionMoves`: internal solver solution from target state to solved.
|
|
33
|
+
- `solutionDepth`, `phase1Depth`, `phase2Depth`, `visitedNodes`: diagnostics.
|
|
34
|
+
|
|
35
|
+
## Timer Preview Flow
|
|
36
|
+
|
|
37
|
+
The recommended timer flow is:
|
|
38
|
+
|
|
39
|
+
1. Call `generateScramble("222")` or `generateScramble("333")`.
|
|
40
|
+
2. Show `result.scramble` as the scramble text.
|
|
41
|
+
3. Render `metadata.facelets` directly for the preview.
|
|
42
|
+
4. Map letters to the user's color scheme in the UI layer.
|
|
43
|
+
|
|
44
|
+
The timer should not need to recompute the cube state from the scramble unless it wants an independent verification path.
|
|
45
|
+
|
|
46
|
+
## Validation Flow
|
|
47
|
+
|
|
48
|
+
The generator already verifies that applying `result.moves` to solved reaches the target state. If CubingCenter wants an extra check during development:
|
|
49
|
+
|
|
50
|
+
```ts
|
|
51
|
+
import { cube2, generateScramble } from "@cubingcenter/scrambler";
|
|
52
|
+
import type { Cube2Move, Cube2State } from "@cubingcenter/scrambler";
|
|
53
|
+
|
|
54
|
+
const result = generateScramble("222", { seed: "debug" });
|
|
55
|
+
const metadata = result.metadata as { state: Cube2State };
|
|
56
|
+
const state = cube2.applyCube2Algorithm(
|
|
57
|
+
cube2.createSolvedCube2State(),
|
|
58
|
+
result.moves as Cube2Move[]
|
|
59
|
+
);
|
|
60
|
+
|
|
61
|
+
console.log(cube2.cube2StatesEqual(state, metadata.state));
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
## Error Handling
|
|
65
|
+
|
|
66
|
+
Unsupported events throw a `ScramblerError` subclass. Treat those as user/configuration errors and avoid retrying the same event id.
|
|
67
|
+
|
|
68
|
+
Generator failures should be treated as operational errors. For local development, log the seed and event id so the case can be reproduced.
|
|
69
|
+
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
# Development
|
|
2
|
+
|
|
3
|
+
## Commands
|
|
4
|
+
|
|
5
|
+
```sh
|
|
6
|
+
pnpm install
|
|
7
|
+
pnpm lint
|
|
8
|
+
pnpm test
|
|
9
|
+
pnpm build
|
|
10
|
+
pnpm package:check
|
|
11
|
+
pnpm verify
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
- `pnpm lint`: TypeScript type check without emitting files.
|
|
15
|
+
- `pnpm test`: Node test runner with `tsx`.
|
|
16
|
+
- `pnpm build`: ESM build, CJS build, CJS package marker, generated asset copy.
|
|
17
|
+
- `pnpm package:check`: local package and consumption checks.
|
|
18
|
+
- `pnpm verify`: full local verification for normal development.
|
|
19
|
+
|
|
20
|
+
## Solver Tables
|
|
21
|
+
|
|
22
|
+
3x3 solver tables are committed as generated binary assets under the cube3 solver generated directory.
|
|
23
|
+
|
|
24
|
+
Regenerate them only when coordinates, moves, pruning logic, or table encoding changes:
|
|
25
|
+
|
|
26
|
+
```sh
|
|
27
|
+
pnpm cube3:tables
|
|
28
|
+
pnpm cube3:tables:check
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
The build copies those assets into both `dist` and `dist-cjs`. Package checks fail if required generated assets are missing from the packed output.
|
|
32
|
+
|
|
33
|
+
## Public API Expectations
|
|
34
|
+
|
|
35
|
+
Root exports are the supported library entrypoint:
|
|
36
|
+
|
|
37
|
+
```ts
|
|
38
|
+
import { generateScramble, generateScrambles, cube3 } from "@cubingcenter/scrambler";
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
The `cube3` module is available for advanced tooling, tests, and integration helpers. Normal app code should call `generateScramble("333")` instead of calling the solver directly.
|
|
42
|
+
|
|
43
|
+
The `cube3.solver` namespace is advanced API. It is useful for diagnostics and development, but timer code should not depend on it for normal rendering.
|
|
44
|
+
|
package/docs/facelets.md
ADDED
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
# Facelets
|
|
2
|
+
|
|
3
|
+
3x3 facelets are exposed so a timer can draw the target scramble state without recomputing cubies.
|
|
4
|
+
|
|
5
|
+
## Face Order
|
|
6
|
+
|
|
7
|
+
The formatted facelet string uses this face order:
|
|
8
|
+
|
|
9
|
+
```txt
|
|
10
|
+
U R F D L B
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
Each face has nine stickers in row-major order:
|
|
14
|
+
|
|
15
|
+
```txt
|
|
16
|
+
0 1 2
|
|
17
|
+
3 4 5
|
|
18
|
+
6 7 8
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
The solved formatted string is:
|
|
22
|
+
|
|
23
|
+
```txt
|
|
24
|
+
UUUUUUUUURRRRRRRRRFFFFFFFFFDDDDDDDDDLLLLLLLLLBBBBBBBBB
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
## Object Shape
|
|
28
|
+
|
|
29
|
+
```ts
|
|
30
|
+
type Cube3Facelets = {
|
|
31
|
+
U: Cube3Sticker[];
|
|
32
|
+
R: Cube3Sticker[];
|
|
33
|
+
F: Cube3Sticker[];
|
|
34
|
+
D: Cube3Sticker[];
|
|
35
|
+
L: Cube3Sticker[];
|
|
36
|
+
B: Cube3Sticker[];
|
|
37
|
+
};
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
Every face array has exactly nine entries. A legal 3x3 state has exactly nine stickers of each letter across the whole object.
|
|
41
|
+
|
|
42
|
+
## Color Mapping
|
|
43
|
+
|
|
44
|
+
The package returns face letters, not UI colors. CubingCenter should map letters to the selected color scheme:
|
|
45
|
+
|
|
46
|
+
```ts
|
|
47
|
+
const colors = {
|
|
48
|
+
U: "#ffffff",
|
|
49
|
+
R: "#d82929",
|
|
50
|
+
F: "#2f9e44",
|
|
51
|
+
D: "#ffd43b",
|
|
52
|
+
L: "#f08c00",
|
|
53
|
+
B: "#1c7ed6"
|
|
54
|
+
};
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
If a user's physical cube uses a different scheme, keep the generated letters unchanged and change only the UI mapping.
|
|
58
|
+
|
|
59
|
+
## Legal States And Appearance
|
|
60
|
+
|
|
61
|
+
Visual appearance is not a legality rule. A face can have repeated colors, blocks, lines, or recognizable patterns and still be a legal random-state scramble target.
|
|
62
|
+
|
|
63
|
+
Legality is checked through cubie permutation parity, corner orientation sum, edge orientation sum, and valid permutations.
|
|
64
|
+
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
# Getting Started
|
|
2
|
+
|
|
3
|
+
This guide shows how to build and consume `@cubingcenter/scrambler` as a local library.
|
|
4
|
+
|
|
5
|
+
## Build The Package
|
|
6
|
+
|
|
7
|
+
```sh
|
|
8
|
+
pnpm install
|
|
9
|
+
pnpm build
|
|
10
|
+
pnpm package:check
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
`pnpm build` writes ESM output to `dist`, CommonJS output to `dist-cjs`, declaration files to `dist`, and copies the generated 3x3 solver assets into both output trees.
|
|
14
|
+
|
|
15
|
+
`pnpm package:check` verifies that the built package can be consumed through ESM and CommonJS and that the package contents include the required runtime assets.
|
|
16
|
+
|
|
17
|
+
## Consume From Another Local Project
|
|
18
|
+
|
|
19
|
+
Use the workflow that best matches your setup:
|
|
20
|
+
|
|
21
|
+
```sh
|
|
22
|
+
pnpm add ../cubingcenter-scrambler
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
or, in a pnpm workspace, add the package as a workspace dependency:
|
|
26
|
+
|
|
27
|
+
```json
|
|
28
|
+
{
|
|
29
|
+
"dependencies": {
|
|
30
|
+
"@cubingcenter/scrambler": "workspace:*"
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
For tarball-style testing:
|
|
36
|
+
|
|
37
|
+
```sh
|
|
38
|
+
pnpm build
|
|
39
|
+
npm pack
|
|
40
|
+
pnpm add ./cubingcenter-scrambler-0.1.0.tgz
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
## Basic Usage
|
|
44
|
+
|
|
45
|
+
```ts
|
|
46
|
+
import { generateScramble } from "@cubingcenter/scrambler";
|
|
47
|
+
|
|
48
|
+
const result2 = generateScramble("222", { seed: "demo" });
|
|
49
|
+
const result3 = generateScramble("333", { seed: "demo" });
|
|
50
|
+
|
|
51
|
+
console.log(result2.scramble);
|
|
52
|
+
console.log(result2.moves);
|
|
53
|
+
console.log(result2.metadata?.faceletString);
|
|
54
|
+
|
|
55
|
+
console.log(result3.scramble);
|
|
56
|
+
console.log(result3.moves);
|
|
57
|
+
console.log(result3.metadata?.faceletString);
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
## Batch Usage
|
|
61
|
+
|
|
62
|
+
```ts
|
|
63
|
+
import { generateScrambles } from "@cubingcenter/scrambler";
|
|
64
|
+
|
|
65
|
+
const scrambles = generateScrambles("333", 5, { seed: "session-1" });
|
|
66
|
+
|
|
67
|
+
for (const item of scrambles) {
|
|
68
|
+
console.log(item.seed, item.scramble);
|
|
69
|
+
}
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
When a seed is provided for a batch, each item derives a stable seed with `seed:index`.
|
|
73
|
+
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
# CLI JSON Shape
|
|
2
|
+
|
|
3
|
+
```sh
|
|
4
|
+
cubingcenter-scrambler 333 --seed demo --json
|
|
5
|
+
```
|
|
6
|
+
|
|
7
|
+
The command prints one object for a single scramble:
|
|
8
|
+
|
|
9
|
+
```json
|
|
10
|
+
{
|
|
11
|
+
"eventId": "333",
|
|
12
|
+
"scramble": "R U R'",
|
|
13
|
+
"moves": ["R", "U", "R'"],
|
|
14
|
+
"quality": "random-state",
|
|
15
|
+
"generator": "cube3-two-phase",
|
|
16
|
+
"seed": "demo",
|
|
17
|
+
"facelets": {
|
|
18
|
+
"U": ["U", "U", "U", "U", "U", "U", "U", "U", "U"],
|
|
19
|
+
"R": ["R", "R", "R", "R", "R", "R", "R", "R", "R"],
|
|
20
|
+
"F": ["F", "F", "F", "F", "F", "F", "F", "F", "F"],
|
|
21
|
+
"D": ["D", "D", "D", "D", "D", "D", "D", "D", "D"],
|
|
22
|
+
"L": ["L", "L", "L", "L", "L", "L", "L", "L", "L"],
|
|
23
|
+
"B": ["B", "B", "B", "B", "B", "B", "B", "B", "B"]
|
|
24
|
+
},
|
|
25
|
+
"faceletString": "UUUUUUUUURRRRRRRRRFFFFFFFFFDDDDDDDDDLLLLLLLLLBBBBBBBBB"
|
|
26
|
+
}
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
The scramble and facelets above are illustrative. Real output depends on the seed.
|
|
30
|
+
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
const { generateScramble } = require("../dist-cjs/index.js");
|
|
2
|
+
|
|
3
|
+
(async () => {
|
|
4
|
+
const result2 = await generateScramble("222", { seed: "commonjs-example-2x2" });
|
|
5
|
+
console.log("2x2:", result2.scramble);
|
|
6
|
+
console.log("2x2 facelets:", result2.metadata.faceletString);
|
|
7
|
+
|
|
8
|
+
const result3 = await generateScramble("333", { seed: "commonjs-example-3x3" });
|
|
9
|
+
console.log("3x3:", result3.scramble);
|
|
10
|
+
console.log("3x3 facelets:", result3.metadata.faceletString);
|
|
11
|
+
})();
|
package/examples/esm.mjs
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { generateScramble } from "../dist/index.js";
|
|
2
|
+
|
|
3
|
+
const result2 = await generateScramble("222", { seed: "esm-example-2x2" });
|
|
4
|
+
console.log("2x2:", result2.scramble);
|
|
5
|
+
console.log("2x2 facelets:", result2.metadata.faceletString);
|
|
6
|
+
|
|
7
|
+
const result3 = await generateScramble("333", { seed: "esm-example-3x3" });
|
|
8
|
+
console.log("3x3:", result3.scramble);
|
|
9
|
+
console.log("3x3 facelets:", result3.metadata.faceletString);
|