@cubingcenter/scrambler 0.5.3 → 0.6.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 +24 -9
- package/dist/cli/index.js +0 -0
- package/dist/core/api.d.ts.map +1 -1
- package/dist/core/api.js +11 -1
- package/dist/core/types.d.ts +1 -1
- package/dist/core/types.d.ts.map +1 -1
- package/dist/puzzles/cube4/index.d.ts +4 -2
- package/dist/puzzles/cube4/index.d.ts.map +1 -1
- package/dist/puzzles/cube4/index.js +3 -1
- package/dist/puzzles/cube4/random-state.d.ts +16 -0
- package/dist/puzzles/cube4/random-state.d.ts.map +1 -0
- package/dist/puzzles/cube4/random-state.js +76 -0
- package/dist/puzzles/cube4/reduction/browser-loader.d.ts +18 -0
- package/dist/puzzles/cube4/reduction/browser-loader.d.ts.map +1 -0
- package/dist/puzzles/cube4/reduction/browser-loader.js +95 -0
- package/dist/puzzles/cube4/reduction/center1.d.ts +65 -0
- package/dist/puzzles/cube4/reduction/center1.d.ts.map +1 -0
- package/dist/puzzles/cube4/reduction/center1.js +245 -0
- package/dist/puzzles/cube4/reduction/center2.d.ts +91 -0
- package/dist/puzzles/cube4/reduction/center2.d.ts.map +1 -0
- package/dist/puzzles/cube4/reduction/center2.js +449 -0
- package/dist/puzzles/cube4/reduction/center3.d.ts +47 -0
- package/dist/puzzles/cube4/reduction/center3.d.ts.map +1 -0
- package/dist/puzzles/cube4/reduction/center3.js +278 -0
- package/dist/puzzles/cube4/reduction/edge3.d.ts +100 -0
- package/dist/puzzles/cube4/reduction/edge3.d.ts.map +1 -0
- package/dist/puzzles/cube4/reduction/edge3.js +511 -0
- package/dist/puzzles/cube4/reduction/generated/center1-distance.bin +1 -0
- package/dist/puzzles/cube4/reduction/generated/center1-manifest.json +46 -0
- package/dist/puzzles/cube4/reduction/generated/center1-move-maps.bin +0 -0
- package/dist/puzzles/cube4/reduction/generated/center2-ct-move.bin +0 -0
- package/dist/puzzles/cube4/reduction/generated/center2-manifest.json +87 -0
- package/dist/puzzles/cube4/reduction/generated/center2-pruning.bin +1 -0
- package/dist/puzzles/cube4/reduction/generated/center2-rl-move.bin +0 -0
- package/dist/puzzles/cube4/reduction/generated/center3-manifest.json +40 -0
- package/dist/puzzles/cube4/reduction/generated/center3-move.bin +0 -0
- package/dist/puzzles/cube4/reduction/generated/center3-pruning.bin +0 -0
- package/dist/puzzles/cube4/reduction/generated/edge3-distances.bin +1 -0
- package/dist/puzzles/cube4/reduction/generated/edge3-manifest.json +12 -0
- package/dist/puzzles/cube4/reduction/geometry.d.ts +33 -0
- package/dist/puzzles/cube4/reduction/geometry.d.ts.map +1 -0
- package/dist/puzzles/cube4/reduction/geometry.js +302 -0
- package/dist/puzzles/cube4/reduction/node-loader.d.ts +17 -0
- package/dist/puzzles/cube4/reduction/node-loader.d.ts.map +1 -0
- package/dist/puzzles/cube4/reduction/node-loader.js +98 -0
- package/dist/puzzles/cube4/reduction/pairing-coordinate.d.ts +130 -0
- package/dist/puzzles/cube4/reduction/pairing-coordinate.d.ts.map +1 -0
- package/dist/puzzles/cube4/reduction/pairing-coordinate.js +281 -0
- package/dist/puzzles/cube4/reduction/phase3-search.d.ts +42 -0
- package/dist/puzzles/cube4/reduction/phase3-search.d.ts.map +1 -0
- package/dist/puzzles/cube4/reduction/phase3-search.js +133 -0
- package/dist/puzzles/cube4/reduction/phase3.d.ts +34 -0
- package/dist/puzzles/cube4/reduction/phase3.d.ts.map +1 -0
- package/dist/puzzles/cube4/reduction/phase3.js +83 -0
- package/dist/puzzles/cube4/reduction/phase4.d.ts +35 -0
- package/dist/puzzles/cube4/reduction/phase4.d.ts.map +1 -0
- package/dist/puzzles/cube4/reduction/phase4.js +82 -0
- package/dist/puzzles/cube4/reduction/solve.d.ts +31 -0
- package/dist/puzzles/cube4/reduction/solve.d.ts.map +1 -0
- package/dist/puzzles/cube4/reduction/solve.js +311 -0
- package/dist/puzzles/cube4/scrambler.d.ts +9 -1
- package/dist/puzzles/cube4/scrambler.d.ts.map +1 -1
- package/dist/puzzles/cube4/scrambler.js +123 -81
- package/dist/puzzles/cube4/types.d.ts +6 -0
- package/dist/puzzles/cube4/types.d.ts.map +1 -1
- package/dist/puzzles/cube4/validation.d.ts +6 -0
- package/dist/puzzles/cube4/validation.d.ts.map +1 -0
- package/dist/puzzles/cube4/validation.js +91 -0
- package/dist/puzzles/fto/coordinates.d.ts +53 -0
- package/dist/puzzles/fto/coordinates.d.ts.map +1 -0
- package/dist/puzzles/fto/coordinates.js +228 -0
- package/dist/puzzles/fto/facelets.d.ts +6 -0
- package/dist/puzzles/fto/facelets.d.ts.map +1 -0
- package/dist/puzzles/fto/facelets.js +99 -0
- package/dist/puzzles/fto/index.d.ts +12 -0
- package/dist/puzzles/fto/index.d.ts.map +1 -0
- package/dist/puzzles/fto/index.js +13 -0
- package/dist/puzzles/fto/moves.d.ts +12 -0
- package/dist/puzzles/fto/moves.d.ts.map +1 -0
- package/dist/puzzles/fto/moves.js +115 -0
- package/dist/puzzles/fto/random-state.d.ts +17 -0
- package/dist/puzzles/fto/random-state.d.ts.map +1 -0
- package/dist/puzzles/fto/random-state.js +40 -0
- package/dist/puzzles/fto/scrambler.d.ts +6 -0
- package/dist/puzzles/fto/scrambler.d.ts.map +1 -0
- package/dist/puzzles/fto/scrambler.js +49 -0
- package/dist/puzzles/fto/solver/engine.d.ts +18 -0
- package/dist/puzzles/fto/solver/engine.d.ts.map +1 -0
- package/dist/puzzles/fto/solver/engine.js +1168 -0
- package/dist/puzzles/fto/solver/index.d.ts +2 -0
- package/dist/puzzles/fto/solver/index.d.ts.map +1 -0
- package/dist/puzzles/fto/solver/index.js +1 -0
- package/dist/puzzles/fto/state.d.ts +16 -0
- package/dist/puzzles/fto/state.d.ts.map +1 -0
- package/dist/puzzles/fto/state.js +61 -0
- package/dist/puzzles/fto/types.d.ts +32 -0
- package/dist/puzzles/fto/types.d.ts.map +1 -0
- package/dist/puzzles/fto/types.js +46 -0
- package/dist/puzzles/fto/validation.d.ts +19 -0
- package/dist/puzzles/fto/validation.d.ts.map +1 -0
- package/dist/puzzles/fto/validation.js +143 -0
- package/dist/puzzles/index.d.ts +2 -0
- package/dist/puzzles/index.d.ts.map +1 -1
- package/dist/puzzles/index.js +6 -0
- package/dist/puzzles/skewb/index.d.ts +1 -1
- package/dist/puzzles/skewb/index.d.ts.map +1 -1
- package/dist/puzzles/skewb/index.js +1 -1
- package/dist/puzzles/skewb/random-state.d.ts.map +1 -1
- package/dist/puzzles/skewb/random-state.js +4 -1
- package/dist/puzzles/sq1/facelets.d.ts +12 -0
- package/dist/puzzles/sq1/facelets.d.ts.map +1 -0
- package/dist/puzzles/sq1/facelets.js +26 -0
- package/dist/puzzles/sq1/index.d.ts +10 -0
- package/dist/puzzles/sq1/index.d.ts.map +1 -0
- package/dist/puzzles/sq1/index.js +11 -0
- package/dist/puzzles/sq1/moves.d.ts +55 -0
- package/dist/puzzles/sq1/moves.d.ts.map +1 -0
- package/dist/puzzles/sq1/moves.js +220 -0
- package/dist/puzzles/sq1/random-state.d.ts +6 -0
- package/dist/puzzles/sq1/random-state.d.ts.map +1 -0
- package/dist/puzzles/sq1/random-state.js +49 -0
- package/dist/puzzles/sq1/scrambler.d.ts +10 -0
- package/dist/puzzles/sq1/scrambler.d.ts.map +1 -0
- package/dist/puzzles/sq1/scrambler.js +90 -0
- package/dist/puzzles/sq1/solver/browser-loader.d.ts +5 -0
- package/dist/puzzles/sq1/solver/browser-loader.d.ts.map +1 -0
- package/dist/puzzles/sq1/solver/browser-loader.js +92 -0
- package/dist/puzzles/sq1/solver/full-cube.d.ts +53 -0
- package/dist/puzzles/sq1/solver/full-cube.d.ts.map +1 -0
- package/dist/puzzles/sq1/solver/full-cube.js +281 -0
- package/dist/puzzles/sq1/solver/generated/manifest.json +50 -0
- package/dist/puzzles/sq1/solver/generated/shape-bottom-move.bin +0 -0
- package/dist/puzzles/sq1/solver/generated/shape-idx.bin +0 -0
- package/dist/puzzles/sq1/solver/generated/shape-prun.bin +0 -0
- package/dist/puzzles/sq1/solver/generated/shape-top-move.bin +0 -0
- package/dist/puzzles/sq1/solver/generated/shape-twist-move.bin +0 -0
- package/dist/puzzles/sq1/solver/generated/square-bottom-move.bin +0 -0
- package/dist/puzzles/sq1/solver/generated/square-prun.bin +0 -0
- package/dist/puzzles/sq1/solver/generated/square-top-move.bin +0 -0
- package/dist/puzzles/sq1/solver/generated/square-twist-move.bin +0 -0
- package/dist/puzzles/sq1/solver/index.d.ts +5 -0
- package/dist/puzzles/sq1/solver/index.d.ts.map +1 -0
- package/dist/puzzles/sq1/solver/index.js +4 -0
- package/dist/puzzles/sq1/solver/node-loader.d.ts +4 -0
- package/dist/puzzles/sq1/solver/node-loader.d.ts.map +1 -0
- package/dist/puzzles/sq1/solver/node-loader.js +113 -0
- package/dist/puzzles/sq1/solver/search.d.ts +27 -0
- package/dist/puzzles/sq1/solver/search.d.ts.map +1 -0
- package/dist/puzzles/sq1/solver/search.js +225 -0
- package/dist/puzzles/sq1/solver/shape.d.ts +22 -0
- package/dist/puzzles/sq1/solver/shape.d.ts.map +1 -0
- package/dist/puzzles/sq1/solver/shape.js +185 -0
- package/dist/puzzles/sq1/solver/square.d.ts +10 -0
- package/dist/puzzles/sq1/solver/square.d.ts.map +1 -0
- package/dist/puzzles/sq1/solver/square.js +90 -0
- package/dist/puzzles/sq1/solver/table-metadata.d.ts +48 -0
- package/dist/puzzles/sq1/solver/table-metadata.d.ts.map +1 -0
- package/dist/puzzles/sq1/solver/table-metadata.js +47 -0
- package/dist/puzzles/sq1/solver/tables.d.ts +17 -0
- package/dist/puzzles/sq1/solver/tables.d.ts.map +1 -0
- package/dist/puzzles/sq1/solver/tables.js +66 -0
- package/dist/puzzles/sq1/state.d.ts +10 -0
- package/dist/puzzles/sq1/state.d.ts.map +1 -0
- package/dist/puzzles/sq1/state.js +74 -0
- package/dist/puzzles/sq1/types.d.ts +32 -0
- package/dist/puzzles/sq1/types.d.ts.map +1 -0
- package/dist/puzzles/sq1/types.js +1 -0
- package/dist/puzzles/sq1/validation.d.ts +7 -0
- package/dist/puzzles/sq1/validation.d.ts.map +1 -0
- package/dist/puzzles/sq1/validation.js +64 -0
- package/dist/random/prng.d.ts.map +1 -1
- package/dist/random/prng.js +9 -4
- package/dist-cjs/core/api.js +11 -1
- package/dist-cjs/puzzles/cube4/index.js +11 -4
- package/dist-cjs/puzzles/cube4/random-state.js +79 -0
- package/dist-cjs/puzzles/cube4/reduction/browser-loader.js +100 -0
- package/dist-cjs/puzzles/cube4/reduction/center1.js +258 -0
- package/dist-cjs/puzzles/cube4/reduction/center2.js +462 -0
- package/dist-cjs/puzzles/cube4/reduction/center3.js +284 -0
- package/dist-cjs/puzzles/cube4/reduction/edge3.js +522 -0
- package/dist-cjs/puzzles/cube4/reduction/generated/center1-distance.bin +1 -0
- package/dist-cjs/puzzles/cube4/reduction/generated/center1-manifest.json +46 -0
- package/dist-cjs/puzzles/cube4/reduction/generated/center1-move-maps.bin +0 -0
- package/dist-cjs/puzzles/cube4/reduction/generated/center2-ct-move.bin +0 -0
- package/dist-cjs/puzzles/cube4/reduction/generated/center2-manifest.json +87 -0
- package/dist-cjs/puzzles/cube4/reduction/generated/center2-pruning.bin +1 -0
- package/dist-cjs/puzzles/cube4/reduction/generated/center2-rl-move.bin +0 -0
- package/dist-cjs/puzzles/cube4/reduction/generated/center3-manifest.json +40 -0
- package/dist-cjs/puzzles/cube4/reduction/generated/center3-move.bin +0 -0
- package/dist-cjs/puzzles/cube4/reduction/generated/center3-pruning.bin +0 -0
- package/dist-cjs/puzzles/cube4/reduction/generated/edge3-distances.bin +1 -0
- package/dist-cjs/puzzles/cube4/reduction/generated/edge3-manifest.json +12 -0
- package/dist-cjs/puzzles/cube4/reduction/geometry.js +308 -0
- package/dist-cjs/puzzles/cube4/reduction/node-loader.js +104 -0
- package/dist-cjs/puzzles/cube4/reduction/pairing-coordinate.js +294 -0
- package/dist-cjs/puzzles/cube4/reduction/phase3-search.js +138 -0
- package/dist-cjs/puzzles/cube4/reduction/phase3.js +86 -0
- package/dist-cjs/puzzles/cube4/reduction/phase4.js +87 -0
- package/dist-cjs/puzzles/cube4/reduction/solve.js +314 -0
- package/dist-cjs/puzzles/cube4/scrambler.js +122 -79
- package/dist-cjs/puzzles/cube4/validation.js +97 -0
- package/dist-cjs/puzzles/fto/coordinates.js +240 -0
- package/dist-cjs/puzzles/fto/facelets.js +104 -0
- package/dist-cjs/puzzles/fto/index.js +68 -0
- package/dist-cjs/puzzles/fto/moves.js +126 -0
- package/dist-cjs/puzzles/fto/random-state.js +43 -0
- package/dist-cjs/puzzles/fto/scrambler.js +53 -0
- package/dist-cjs/puzzles/fto/solver/engine.js +1175 -0
- package/dist-cjs/puzzles/fto/solver/index.js +9 -0
- package/dist-cjs/puzzles/fto/state.js +69 -0
- package/dist-cjs/puzzles/fto/types.js +49 -0
- package/dist-cjs/puzzles/fto/validation.js +147 -0
- package/dist-cjs/puzzles/index.js +7 -1
- package/dist-cjs/puzzles/skewb/index.js +2 -1
- package/dist-cjs/puzzles/skewb/random-state.js +4 -1
- package/dist-cjs/puzzles/sq1/facelets.js +30 -0
- package/dist-cjs/puzzles/sq1/index.js +52 -0
- package/dist-cjs/puzzles/sq1/moves.js +234 -0
- package/dist-cjs/puzzles/sq1/random-state.js +52 -0
- package/dist-cjs/puzzles/sq1/scrambler.js +95 -0
- package/dist-cjs/puzzles/sq1/solver/browser-loader.js +97 -0
- package/dist-cjs/puzzles/sq1/solver/full-cube.js +289 -0
- package/dist-cjs/puzzles/sq1/solver/generated/manifest.json +50 -0
- package/dist-cjs/puzzles/sq1/solver/generated/shape-bottom-move.bin +0 -0
- package/dist-cjs/puzzles/sq1/solver/generated/shape-idx.bin +0 -0
- package/dist-cjs/puzzles/sq1/solver/generated/shape-prun.bin +0 -0
- package/dist-cjs/puzzles/sq1/solver/generated/shape-top-move.bin +0 -0
- package/dist-cjs/puzzles/sq1/solver/generated/shape-twist-move.bin +0 -0
- package/dist-cjs/puzzles/sq1/solver/generated/square-bottom-move.bin +0 -0
- package/dist-cjs/puzzles/sq1/solver/generated/square-prun.bin +0 -0
- package/dist-cjs/puzzles/sq1/solver/generated/square-top-move.bin +0 -0
- package/dist-cjs/puzzles/sq1/solver/generated/square-twist-move.bin +0 -0
- package/dist-cjs/puzzles/sq1/solver/index.js +18 -0
- package/dist-cjs/puzzles/sq1/solver/node-loader.js +120 -0
- package/dist-cjs/puzzles/sq1/solver/search.js +229 -0
- package/dist-cjs/puzzles/sq1/solver/shape.js +191 -0
- package/dist-cjs/puzzles/sq1/solver/square.js +93 -0
- package/dist-cjs/puzzles/sq1/solver/table-metadata.js +50 -0
- package/dist-cjs/puzzles/sq1/solver/tables.js +106 -0
- package/dist-cjs/puzzles/sq1/state.js +81 -0
- package/dist-cjs/puzzles/sq1/types.js +2 -0
- package/dist-cjs/puzzles/sq1/validation.js +68 -0
- package/dist-cjs/random/prng.js +9 -4
- package/package.json +43 -14
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import { generateShapeTables } from "./shape.js";
|
|
2
|
+
import { generateSquareTables } from "./square.js";
|
|
3
|
+
let cachedTables;
|
|
4
|
+
let tableLoadPromise;
|
|
5
|
+
export function areSquare1TablesLoaded() {
|
|
6
|
+
return cachedTables !== undefined;
|
|
7
|
+
}
|
|
8
|
+
export function getSquare1SolverTablesSync() {
|
|
9
|
+
if (!cachedTables) {
|
|
10
|
+
// Check if running in Node.js
|
|
11
|
+
if (typeof process !== "undefined" && process.versions?.node) {
|
|
12
|
+
try {
|
|
13
|
+
const { readGeneratedSquare1SolverTables } = require("./node-loader.js");
|
|
14
|
+
cachedTables = readGeneratedSquare1SolverTables();
|
|
15
|
+
return cachedTables;
|
|
16
|
+
}
|
|
17
|
+
catch {
|
|
18
|
+
// Fall back to on-the-fly generation
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
// Generate on the fly
|
|
22
|
+
cachedTables = generateSquare1SolverTables();
|
|
23
|
+
}
|
|
24
|
+
return cachedTables;
|
|
25
|
+
}
|
|
26
|
+
export async function ensureSquare1TablesLoaded(baseUrl) {
|
|
27
|
+
if (cachedTables) {
|
|
28
|
+
return cachedTables;
|
|
29
|
+
}
|
|
30
|
+
if (tableLoadPromise) {
|
|
31
|
+
return tableLoadPromise;
|
|
32
|
+
}
|
|
33
|
+
tableLoadPromise = (async () => {
|
|
34
|
+
if (typeof window !== "undefined" || typeof self !== "undefined" && typeof self.importScripts === "function") {
|
|
35
|
+
try {
|
|
36
|
+
const { loadBrowserTables } = await import("./browser-loader.js");
|
|
37
|
+
cachedTables = await loadBrowserTables(baseUrl);
|
|
38
|
+
return cachedTables;
|
|
39
|
+
}
|
|
40
|
+
catch {
|
|
41
|
+
// Fall back to on-the-fly generation
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
cachedTables = getSquare1SolverTablesSync();
|
|
45
|
+
return cachedTables;
|
|
46
|
+
})();
|
|
47
|
+
return tableLoadPromise;
|
|
48
|
+
}
|
|
49
|
+
export function generateSquare1SolverTables() {
|
|
50
|
+
const shape = generateShapeTables();
|
|
51
|
+
const square = generateSquareTables();
|
|
52
|
+
return {
|
|
53
|
+
shapeIdx: shape.shapeIdx,
|
|
54
|
+
shapePrun: shape.shapePrun,
|
|
55
|
+
shapeTopMove: shape.shapeTopMove,
|
|
56
|
+
shapeBottomMove: shape.shapeBottomMove,
|
|
57
|
+
shapeTwistMove: shape.shapeTwistMove,
|
|
58
|
+
squareTwistMove: square.squareTwistMove,
|
|
59
|
+
squareTopMove: square.squareTopMove,
|
|
60
|
+
squareBottomMove: square.squareBottomMove,
|
|
61
|
+
squarePrun: square.squarePrun
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
export function setCachedSquare1Tables(tables) {
|
|
65
|
+
cachedTables = tables;
|
|
66
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { Square1Slot, Square1State } from "./types.js";
|
|
2
|
+
export declare const WEDGE_DEFS: Square1Slot[];
|
|
3
|
+
/**
|
|
4
|
+
* Creates a solved Square-1 state aligned with the standard WCA visualization.
|
|
5
|
+
*/
|
|
6
|
+
export declare function createSolvedSquare1State(): Square1State;
|
|
7
|
+
export declare function cloneSquare1State(state: Square1State): Square1State;
|
|
8
|
+
export declare function statesEqual(a: Square1State, b: Square1State): boolean;
|
|
9
|
+
export declare function isSolvedSquare1State(state: Square1State): boolean;
|
|
10
|
+
//# sourceMappingURL=state.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"state.d.ts","sourceRoot":"","sources":["../../../src/puzzles/sq1/state.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAE5D,eAAO,MAAM,UAAU,EAAE,WAAW,EA2BnC,CAAC;AAEF;;GAEG;AACH,wBAAgB,wBAAwB,IAAI,YAAY,CAQvD;AAED,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,YAAY,GAAG,YAAY,CAMnE;AAED,wBAAgB,WAAW,CAAC,CAAC,EAAE,YAAY,EAAE,CAAC,EAAE,YAAY,GAAG,OAAO,CA0BrE;AAED,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,YAAY,GAAG,OAAO,CAGjE"}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
export const WEDGE_DEFS = [
|
|
2
|
+
// Top layer (0..11) - Yellow (D in WCA_COLORS):
|
|
3
|
+
{ pieceId: 0, isCorner: true, partIndex: 0, faceColor: "D", sideColor: "R" }, // 0
|
|
4
|
+
{ pieceId: 0, isCorner: true, partIndex: 1, faceColor: "D", sideColor: "B" }, // 1
|
|
5
|
+
{ pieceId: 9, isCorner: false, partIndex: 0, faceColor: "D", sideColor: "B" }, // 2
|
|
6
|
+
{ pieceId: 1, isCorner: true, partIndex: 0, faceColor: "D", sideColor: "B" }, // 3
|
|
7
|
+
{ pieceId: 1, isCorner: true, partIndex: 1, faceColor: "D", sideColor: "L" }, // 4
|
|
8
|
+
{ pieceId: 10, isCorner: false, partIndex: 0, faceColor: "D", sideColor: "L" }, // 5
|
|
9
|
+
{ pieceId: 2, isCorner: true, partIndex: 0, faceColor: "D", sideColor: "L" }, // 6
|
|
10
|
+
{ pieceId: 2, isCorner: true, partIndex: 1, faceColor: "D", sideColor: "F" }, // 7
|
|
11
|
+
{ pieceId: 11, isCorner: false, partIndex: 0, faceColor: "D", sideColor: "F" }, // 8
|
|
12
|
+
{ pieceId: 3, isCorner: true, partIndex: 0, faceColor: "D", sideColor: "F" }, // 9
|
|
13
|
+
{ pieceId: 3, isCorner: true, partIndex: 1, faceColor: "D", sideColor: "R" }, // 10
|
|
14
|
+
{ pieceId: 8, isCorner: false, partIndex: 0, faceColor: "D", sideColor: "R" }, // 11
|
|
15
|
+
// Bottom layer (12..23) - White (U in WCA_COLORS):
|
|
16
|
+
{ pieceId: 12, isCorner: false, partIndex: 0, faceColor: "U", sideColor: "R" }, // 12
|
|
17
|
+
{ pieceId: 4, isCorner: true, partIndex: 0, faceColor: "U", sideColor: "R" }, // 13
|
|
18
|
+
{ pieceId: 4, isCorner: true, partIndex: 1, faceColor: "U", sideColor: "F" }, // 14
|
|
19
|
+
{ pieceId: 13, isCorner: false, partIndex: 0, faceColor: "U", sideColor: "F" }, // 15
|
|
20
|
+
{ pieceId: 5, isCorner: true, partIndex: 0, faceColor: "U", sideColor: "F" }, // 16
|
|
21
|
+
{ pieceId: 5, isCorner: true, partIndex: 1, faceColor: "U", sideColor: "L" }, // 17
|
|
22
|
+
{ pieceId: 14, isCorner: false, partIndex: 0, faceColor: "U", sideColor: "L" }, // 18
|
|
23
|
+
{ pieceId: 6, isCorner: true, partIndex: 0, faceColor: "U", sideColor: "L" }, // 19
|
|
24
|
+
{ pieceId: 6, isCorner: true, partIndex: 1, faceColor: "U", sideColor: "B" }, // 20
|
|
25
|
+
{ pieceId: 15, isCorner: false, partIndex: 0, faceColor: "U", sideColor: "B" }, // 21
|
|
26
|
+
{ pieceId: 7, isCorner: true, partIndex: 0, faceColor: "U", sideColor: "B" }, // 22
|
|
27
|
+
{ pieceId: 7, isCorner: true, partIndex: 1, faceColor: "U", sideColor: "R" }, // 23
|
|
28
|
+
];
|
|
29
|
+
/**
|
|
30
|
+
* Creates a solved Square-1 state aligned with the standard WCA visualization.
|
|
31
|
+
*/
|
|
32
|
+
export function createSolvedSquare1State() {
|
|
33
|
+
const top = Array.from({ length: 12 }, (_, i) => ({ ...WEDGE_DEFS[i] }));
|
|
34
|
+
const bottom = Array.from({ length: 12 }, (_, i) => ({ ...WEDGE_DEFS[12 + i] }));
|
|
35
|
+
return {
|
|
36
|
+
top,
|
|
37
|
+
bottom,
|
|
38
|
+
middle: 0,
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
export function cloneSquare1State(state) {
|
|
42
|
+
return {
|
|
43
|
+
top: state.top.map((s) => ({ ...s })),
|
|
44
|
+
bottom: state.bottom.map((s) => ({ ...s })),
|
|
45
|
+
middle: state.middle,
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
export function statesEqual(a, b) {
|
|
49
|
+
if (a.middle !== b.middle)
|
|
50
|
+
return false;
|
|
51
|
+
for (let i = 0; i < 12; i++) {
|
|
52
|
+
const at = a.top[i];
|
|
53
|
+
const bt = b.top[i];
|
|
54
|
+
if (at.pieceId !== bt.pieceId ||
|
|
55
|
+
at.partIndex !== bt.partIndex ||
|
|
56
|
+
at.faceColor !== bt.faceColor ||
|
|
57
|
+
at.sideColor !== bt.sideColor) {
|
|
58
|
+
return false;
|
|
59
|
+
}
|
|
60
|
+
const ab = a.bottom[i];
|
|
61
|
+
const bb = b.bottom[i];
|
|
62
|
+
if (ab.pieceId !== bb.pieceId ||
|
|
63
|
+
ab.partIndex !== bb.partIndex ||
|
|
64
|
+
ab.faceColor !== bb.faceColor ||
|
|
65
|
+
ab.sideColor !== bb.sideColor) {
|
|
66
|
+
return false;
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
return true;
|
|
70
|
+
}
|
|
71
|
+
export function isSolvedSquare1State(state) {
|
|
72
|
+
const solved = createSolvedSquare1State();
|
|
73
|
+
return statesEqual(state, solved);
|
|
74
|
+
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
export type Square1Color = "U" | "D" | "F" | "R" | "B" | "L";
|
|
2
|
+
export interface Square1Slot {
|
|
3
|
+
pieceId: number;
|
|
4
|
+
isCorner: boolean;
|
|
5
|
+
partIndex: 0 | 1;
|
|
6
|
+
faceColor: Square1Color;
|
|
7
|
+
sideColor: Square1Color;
|
|
8
|
+
}
|
|
9
|
+
export interface Square1State {
|
|
10
|
+
top: Square1Slot[];
|
|
11
|
+
bottom: Square1Slot[];
|
|
12
|
+
middle: number;
|
|
13
|
+
}
|
|
14
|
+
export interface Square1Facelets {
|
|
15
|
+
top: string[];
|
|
16
|
+
topSides: string[];
|
|
17
|
+
bottom: string[];
|
|
18
|
+
bottomSides: string[];
|
|
19
|
+
middle: number;
|
|
20
|
+
topSlots?: Square1Slot[];
|
|
21
|
+
bottomSlots?: Square1Slot[];
|
|
22
|
+
}
|
|
23
|
+
export interface Square1RandomStateOptions {
|
|
24
|
+
seed?: string | number;
|
|
25
|
+
rejectTrivial?: boolean;
|
|
26
|
+
}
|
|
27
|
+
export interface Square1ValidationResult {
|
|
28
|
+
valid: boolean;
|
|
29
|
+
errors: string[];
|
|
30
|
+
}
|
|
31
|
+
export type Square1Move = string;
|
|
32
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/puzzles/sq1/types.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,YAAY,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,CAAC;AAE7D,MAAM,WAAW,WAAW;IAC1B,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,OAAO,CAAC;IAClB,SAAS,EAAE,CAAC,GAAG,CAAC,CAAC;IACjB,SAAS,EAAE,YAAY,CAAC;IACxB,SAAS,EAAE,YAAY,CAAC;CACzB;AAED,MAAM,WAAW,YAAY;IAC3B,GAAG,EAAE,WAAW,EAAE,CAAC;IACnB,MAAM,EAAE,WAAW,EAAE,CAAC;IACtB,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,eAAe;IAC9B,GAAG,EAAE,MAAM,EAAE,CAAC;IACd,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,WAAW,EAAE,MAAM,EAAE,CAAC;IACtB,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,WAAW,EAAE,CAAC;IACzB,WAAW,CAAC,EAAE,WAAW,EAAE,CAAC;CAC7B;AAED,MAAM,WAAW,yBAAyB;IACxC,IAAI,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IACvB,aAAa,CAAC,EAAE,OAAO,CAAC;CACzB;AAED,MAAM,WAAW,uBAAuB;IACtC,KAAK,EAAE,OAAO,CAAC;IACf,MAAM,EAAE,MAAM,EAAE,CAAC;CAClB;AAED,MAAM,MAAM,WAAW,GAAG,MAAM,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { Square1State, Square1ValidationResult } from "./types.js";
|
|
2
|
+
/**
|
|
3
|
+
* Validates whether a given Square-1 state is physically and mathematically legal.
|
|
4
|
+
*/
|
|
5
|
+
export declare function validateSquare1State(state: Square1State): Square1ValidationResult;
|
|
6
|
+
export declare function isTrivialSquare1State(state: Square1State): boolean;
|
|
7
|
+
//# sourceMappingURL=validation.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validation.d.ts","sourceRoot":"","sources":["../../../src/puzzles/sq1/validation.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,uBAAuB,EAAE,MAAM,YAAY,CAAC;AAIxE;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,YAAY,GAAG,uBAAuB,CA+DjF;AAED,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,YAAY,GAAG,OAAO,CAElE"}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import { isSolvedSquare1State } from "./state.js";
|
|
2
|
+
/**
|
|
3
|
+
* Validates whether a given Square-1 state is physically and mathematically legal.
|
|
4
|
+
*/
|
|
5
|
+
export function validateSquare1State(state) {
|
|
6
|
+
const errors = [];
|
|
7
|
+
if (!state || !Array.isArray(state.top) || !Array.isArray(state.bottom)) {
|
|
8
|
+
return { valid: false, errors: ["Invalid state structure: top and bottom must be arrays."] };
|
|
9
|
+
}
|
|
10
|
+
if (state.top.length !== 12) {
|
|
11
|
+
errors.push(`Top layer must have 12 slots, found ${state.top.length}.`);
|
|
12
|
+
}
|
|
13
|
+
if (state.bottom.length !== 12) {
|
|
14
|
+
errors.push(`Bottom layer must have 12 slots, found ${state.bottom.length}.`);
|
|
15
|
+
}
|
|
16
|
+
if (state.middle !== 0 && state.middle !== 1) {
|
|
17
|
+
errors.push(`Middle layer must be 0 or 1, found ${state.middle}.`);
|
|
18
|
+
}
|
|
19
|
+
if (errors.length > 0) {
|
|
20
|
+
return { valid: false, errors };
|
|
21
|
+
}
|
|
22
|
+
// Count pieces
|
|
23
|
+
const cornerParts = {};
|
|
24
|
+
const edges = {};
|
|
25
|
+
const checkSlot = (slot, layer, idx) => {
|
|
26
|
+
if (typeof slot.pieceId !== "number" || typeof slot.isCorner !== "boolean") {
|
|
27
|
+
errors.push(`Invalid slot at ${layer}[${idx}].`);
|
|
28
|
+
return;
|
|
29
|
+
}
|
|
30
|
+
if (slot.isCorner) {
|
|
31
|
+
if (slot.pieceId < 0 || slot.pieceId > 7) {
|
|
32
|
+
errors.push(`Invalid corner pieceId ${slot.pieceId} at ${layer}[${idx}].`);
|
|
33
|
+
}
|
|
34
|
+
cornerParts[slot.pieceId] = (cornerParts[slot.pieceId] || 0) + 1;
|
|
35
|
+
}
|
|
36
|
+
else {
|
|
37
|
+
if (slot.pieceId < 8 || slot.pieceId > 15) {
|
|
38
|
+
errors.push(`Invalid edge pieceId ${slot.pieceId} at ${layer}[${idx}].`);
|
|
39
|
+
}
|
|
40
|
+
edges[slot.pieceId] = (edges[slot.pieceId] || 0) + 1;
|
|
41
|
+
}
|
|
42
|
+
};
|
|
43
|
+
for (let i = 0; i < 12; i++)
|
|
44
|
+
checkSlot(state.top[i], "top", i);
|
|
45
|
+
for (let i = 0; i < 12; i++)
|
|
46
|
+
checkSlot(state.bottom[i], "bottom", i);
|
|
47
|
+
for (let c = 0; c < 8; c++) {
|
|
48
|
+
if (cornerParts[c] !== 2) {
|
|
49
|
+
errors.push(`Corner ${c} must appear exactly twice (2 parts), found ${cornerParts[c] || 0}.`);
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
for (let e = 8; e <= 15; e++) {
|
|
53
|
+
if (edges[e] !== 1) {
|
|
54
|
+
errors.push(`Edge ${e} must appear exactly once, found ${edges[e] || 0}.`);
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
if (errors.length > 0) {
|
|
58
|
+
return { valid: false, errors };
|
|
59
|
+
}
|
|
60
|
+
return { valid: true, errors: [] };
|
|
61
|
+
}
|
|
62
|
+
export function isTrivialSquare1State(state) {
|
|
63
|
+
return isSolvedSquare1State(state);
|
|
64
|
+
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"prng.d.ts","sourceRoot":"","sources":["../../src/random/prng.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"prng.d.ts","sourceRoot":"","sources":["../../src/random/prng.ts"],"names":[],"mappings":"AAQA,MAAM,WAAW,YAAY;IAC3B,IAAI,IAAI,MAAM,CAAC;IACf,OAAO,CAAC,YAAY,EAAE,MAAM,GAAG,MAAM,CAAC;IACtC,MAAM,CAAC,CAAC,EAAE,KAAK,EAAE,SAAS,CAAC,EAAE,GAAG,CAAC,CAAC;CACnC;AAED,wBAAgB,kBAAkB,CAAC,IAAI,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,YAAY,CAOvE"}
|
package/dist/random/prng.js
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { randomBytes } from "node:crypto";
|
|
2
1
|
// 4096 bytes per refill (~682 values per syscall).
|
|
3
2
|
const CRYPTO_BUFFER_BYTES = 4096;
|
|
4
3
|
// Shared unseeded source: the crypto refill costs a syscall per buffer, so a
|
|
@@ -16,10 +15,16 @@ class CryptoRandomSource {
|
|
|
16
15
|
buffer = null;
|
|
17
16
|
offset = 0;
|
|
18
17
|
next() {
|
|
19
|
-
// Batch the crypto calls: one randomBytes per move is ~2 orders of
|
|
20
|
-
// magnitude slower in Node (syscall per call). Refill lazily.
|
|
21
18
|
if (this.buffer === null || this.offset + 6 > CRYPTO_BUFFER_BYTES) {
|
|
22
|
-
this.buffer =
|
|
19
|
+
this.buffer = new Uint8Array(CRYPTO_BUFFER_BYTES);
|
|
20
|
+
if (typeof globalThis.crypto?.getRandomValues === "function") {
|
|
21
|
+
globalThis.crypto.getRandomValues(this.buffer);
|
|
22
|
+
}
|
|
23
|
+
else {
|
|
24
|
+
for (let i = 0; i < CRYPTO_BUFFER_BYTES; i++) {
|
|
25
|
+
this.buffer[i] = Math.floor(Math.random() * 256);
|
|
26
|
+
}
|
|
27
|
+
}
|
|
23
28
|
this.offset = 0;
|
|
24
29
|
}
|
|
25
30
|
const bytes = this.buffer;
|
package/dist-cjs/core/api.js
CHANGED
|
@@ -75,12 +75,22 @@ async function initializeScrambler(baseUrl, eventId) {
|
|
|
75
75
|
const { loadBrowserTables } = await Promise.resolve().then(() => __importStar(require("../puzzles/skewb/solver/browser-loader.js")));
|
|
76
76
|
await loadBrowserTables(baseUrl);
|
|
77
77
|
}
|
|
78
|
+
else if (eventId === "sq1") {
|
|
79
|
+
const { loadBrowserTables } = await Promise.resolve().then(() => __importStar(require("../puzzles/sq1/solver/browser-loader.js")));
|
|
80
|
+
await loadBrowserTables(baseUrl);
|
|
81
|
+
}
|
|
82
|
+
else if (eventId === "444") {
|
|
83
|
+
const { loadCube4ReductionTablesBrowser } = await Promise.resolve().then(() => __importStar(require("../puzzles/cube4/reduction/browser-loader.js")));
|
|
84
|
+
await loadCube4ReductionTablesBrowser(baseUrl);
|
|
85
|
+
}
|
|
78
86
|
else if (!eventId) {
|
|
79
87
|
await Promise.all([
|
|
80
88
|
Promise.resolve().then(() => __importStar(require("../puzzles/cube2/solver/browser-loader.js"))).then((m) => m.loadBrowserTables(baseUrl)),
|
|
81
89
|
Promise.resolve().then(() => __importStar(require("../puzzles/cube3/solver/browser-loader.js"))).then((m) => m.loadBrowserTables(baseUrl)),
|
|
82
90
|
Promise.resolve().then(() => __importStar(require("../puzzles/pyraminx/solver/browser-loader.js"))).then((m) => m.loadBrowserTables(baseUrl)),
|
|
83
|
-
Promise.resolve().then(() => __importStar(require("../puzzles/skewb/solver/browser-loader.js"))).then((m) => m.loadBrowserTables(baseUrl))
|
|
91
|
+
Promise.resolve().then(() => __importStar(require("../puzzles/skewb/solver/browser-loader.js"))).then((m) => m.loadBrowserTables(baseUrl)),
|
|
92
|
+
Promise.resolve().then(() => __importStar(require("../puzzles/sq1/solver/browser-loader.js"))).then((m) => m.loadBrowserTables(baseUrl)),
|
|
93
|
+
Promise.resolve().then(() => __importStar(require("../puzzles/cube4/reduction/browser-loader.js"))).then((m) => m.loadCube4ReductionTablesBrowser(baseUrl))
|
|
84
94
|
]);
|
|
85
95
|
}
|
|
86
96
|
}
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
// cube4 barrel exports
|
|
4
4
|
// ---------------------------------------------------------------------------
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.initializeScrambler = exports.getSupportedEvents = exports.getEventInfo = exports.generateScrambles = exports.generateScramble = exports.getCube4FaceOrder = exports.formatCube4Facelets = exports.toCube4Facelets = exports.
|
|
6
|
+
exports.initializeScrambler = exports.getSupportedEvents = exports.getEventInfo = exports.generateScrambles = exports.generateScramble = exports.getCube4FaceOrder = exports.formatCube4Facelets = exports.toCube4Facelets = exports.isAllowedRandomCube4State = exports.isTrivialCube4State = exports.isOneMoveFromSolvedCube4State = exports.validateCube4State = exports.generateRandomCube4State = exports.FACE_MOVE_EFFECTS = exports.parseMove = exports.parseCube4Move = exports.parseCube4Algorithm = exports.formatCube4Algorithm = exports.invertCube4Algorithm = exports.invertCube4Move = exports.applyCube4Algorithm = exports.applyCube4Move = exports.generateCube4Scramble = exports.cube4ScrambleGenerator = exports.areWingsPaired = exports.areCentersReduced = exports.isSolvedCube4State = exports.cube4StatesEqual = exports.cloneCube4State = exports.createSolvedCube4State = exports.CUBE4_OUTER_MOVES = exports.CUBE4_ALL_MOVES = exports.CUBE4_FACE_MOVES = exports.B = exports.L = exports.D = exports.F = exports.R = exports.U = exports.CENTERS_PER_FACE = exports.FACE_COUNT = exports.CENTER_COUNT = exports.WING_COUNT = exports.CORNER_COUNT = void 0;
|
|
7
7
|
const index_js_1 = require("../../core/index.js");
|
|
8
8
|
const scrambler_js_1 = require("./scrambler.js");
|
|
9
9
|
(0, index_js_1.registerScrambleGenerator)(scrambler_js_1.cube4ScrambleGenerator);
|
|
@@ -29,6 +29,9 @@ Object.defineProperty(exports, "cube4StatesEqual", { enumerable: true, get: func
|
|
|
29
29
|
Object.defineProperty(exports, "isSolvedCube4State", { enumerable: true, get: function () { return state_js_1.isSolvedCube4State; } });
|
|
30
30
|
Object.defineProperty(exports, "areCentersReduced", { enumerable: true, get: function () { return state_js_1.areCentersReduced; } });
|
|
31
31
|
Object.defineProperty(exports, "areWingsPaired", { enumerable: true, get: function () { return state_js_1.areWingsPaired; } });
|
|
32
|
+
var scrambler_js_2 = require("./scrambler.js");
|
|
33
|
+
Object.defineProperty(exports, "cube4ScrambleGenerator", { enumerable: true, get: function () { return scrambler_js_2.cube4ScrambleGenerator; } });
|
|
34
|
+
Object.defineProperty(exports, "generateCube4Scramble", { enumerable: true, get: function () { return scrambler_js_2.generateCube4Scramble; } });
|
|
32
35
|
var moves_js_1 = require("./moves.js");
|
|
33
36
|
Object.defineProperty(exports, "applyCube4Move", { enumerable: true, get: function () { return moves_js_1.applyCube4Move; } });
|
|
34
37
|
Object.defineProperty(exports, "applyCube4Algorithm", { enumerable: true, get: function () { return moves_js_1.applyCube4Algorithm; } });
|
|
@@ -39,9 +42,13 @@ Object.defineProperty(exports, "parseCube4Algorithm", { enumerable: true, get: f
|
|
|
39
42
|
Object.defineProperty(exports, "parseCube4Move", { enumerable: true, get: function () { return moves_js_1.parseCube4Move; } });
|
|
40
43
|
Object.defineProperty(exports, "parseMove", { enumerable: true, get: function () { return moves_js_1.parseMove; } });
|
|
41
44
|
Object.defineProperty(exports, "FACE_MOVE_EFFECTS", { enumerable: true, get: function () { return moves_js_1.FACE_MOVE_EFFECTS; } });
|
|
42
|
-
var
|
|
43
|
-
Object.defineProperty(exports, "
|
|
44
|
-
|
|
45
|
+
var random_state_js_1 = require("./random-state.js");
|
|
46
|
+
Object.defineProperty(exports, "generateRandomCube4State", { enumerable: true, get: function () { return random_state_js_1.generateRandomCube4State; } });
|
|
47
|
+
var validation_js_1 = require("./validation.js");
|
|
48
|
+
Object.defineProperty(exports, "validateCube4State", { enumerable: true, get: function () { return validation_js_1.validateCube4State; } });
|
|
49
|
+
Object.defineProperty(exports, "isOneMoveFromSolvedCube4State", { enumerable: true, get: function () { return validation_js_1.isOneMoveFromSolvedCube4State; } });
|
|
50
|
+
Object.defineProperty(exports, "isTrivialCube4State", { enumerable: true, get: function () { return validation_js_1.isTrivialCube4State; } });
|
|
51
|
+
Object.defineProperty(exports, "isAllowedRandomCube4State", { enumerable: true, get: function () { return validation_js_1.isAllowedRandomCube4State; } });
|
|
45
52
|
var facelets_js_1 = require("./facelets.js");
|
|
46
53
|
Object.defineProperty(exports, "toCube4Facelets", { enumerable: true, get: function () { return facelets_js_1.toCube4Facelets; } });
|
|
47
54
|
Object.defineProperty(exports, "formatCube4Facelets", { enumerable: true, get: function () { return facelets_js_1.formatCube4Facelets; } });
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Uniform random-state generation for 4x4x4.
|
|
4
|
+
*
|
|
5
|
+
* Samples uniformly from the reachable states of the normal (non-super) 4x4:
|
|
6
|
+
* - corner permutation 8! + orientation with sum ≡ 0 (mod 3)
|
|
7
|
+
* - wing permutation 24! (wings have no orientation)
|
|
8
|
+
* - centers: 24!/(4!)^6 (any arrangement with 4 centers of each color)
|
|
9
|
+
*
|
|
10
|
+
* On a normal 4x4 the corner and wing permutation parities are independent
|
|
11
|
+
* (a single face turn changes corner parity while leaving wing parity even),
|
|
12
|
+
* so no cross-parity constraint is applied here — the reduction solver must
|
|
13
|
+
* be able to reduce states with all four parity combinations.
|
|
14
|
+
*/
|
|
15
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
16
|
+
exports.generateRandomCube4State = generateRandomCube4State;
|
|
17
|
+
const index_js_1 = require("../../random/index.js");
|
|
18
|
+
const types_js_1 = require("./types.js");
|
|
19
|
+
const validation_js_1 = require("./validation.js");
|
|
20
|
+
function generateRandomCube4State(options = {}) {
|
|
21
|
+
const random = (0, index_js_1.createRandomSource)(options.seed);
|
|
22
|
+
const rejectTrivial = options.rejectTrivial ?? true;
|
|
23
|
+
for (let attempt = 0; attempt < 100; attempt += 1) {
|
|
24
|
+
// The state is legal by construction (permutations shuffled, corner
|
|
25
|
+
// orientation sum fixed, 4 centers per color), so the only meaningful
|
|
26
|
+
// rejection is the trivial set (solved + the 36 single-move states).
|
|
27
|
+
const state = createLegalRandomState(random);
|
|
28
|
+
if (!rejectTrivial || !(0, validation_js_1.isTrivialCube4State)(state)) {
|
|
29
|
+
return state;
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
throw new Error("Unable to generate a non-trivial random 4x4 state.");
|
|
33
|
+
}
|
|
34
|
+
function createLegalRandomState(random) {
|
|
35
|
+
const cp = shuffledRange(types_js_1.CORNER_COUNT, random);
|
|
36
|
+
const wp = shuffledRange(types_js_1.WING_COUNT, random);
|
|
37
|
+
return {
|
|
38
|
+
cp,
|
|
39
|
+
co: randomOrientations(types_js_1.CORNER_COUNT, 3, random),
|
|
40
|
+
wp,
|
|
41
|
+
centers: shuffledCenters(random)
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
function shuffledRange(length, random) {
|
|
45
|
+
const values = Uint8Array.from({ length }, (_, index) => index);
|
|
46
|
+
for (let index = values.length - 1; index > 0; index -= 1) {
|
|
47
|
+
const swapIndex = random.nextInt(index + 1);
|
|
48
|
+
const temporary = values[index];
|
|
49
|
+
values[index] = values[swapIndex];
|
|
50
|
+
values[swapIndex] = temporary;
|
|
51
|
+
}
|
|
52
|
+
return values;
|
|
53
|
+
}
|
|
54
|
+
function randomOrientations(length, modulo, random) {
|
|
55
|
+
const orientations = new Uint8Array(length);
|
|
56
|
+
let total = 0;
|
|
57
|
+
for (let index = 0; index < length - 1; index += 1) {
|
|
58
|
+
const orientation = random.nextInt(modulo);
|
|
59
|
+
orientations[index] = orientation;
|
|
60
|
+
total += orientation;
|
|
61
|
+
}
|
|
62
|
+
orientations[length - 1] = (modulo - (total % modulo)) % modulo;
|
|
63
|
+
return orientations;
|
|
64
|
+
}
|
|
65
|
+
function shuffledCenters(random) {
|
|
66
|
+
const centers = new Uint8Array(types_js_1.CENTER_COUNT);
|
|
67
|
+
for (let face = 0; face < types_js_1.FACE_COUNT; face += 1) {
|
|
68
|
+
for (let index = 0; index < types_js_1.CENTERS_PER_FACE; index += 1) {
|
|
69
|
+
centers[face * types_js_1.CENTERS_PER_FACE + index] = face;
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
for (let index = centers.length - 1; index > 0; index -= 1) {
|
|
73
|
+
const swapIndex = random.nextInt(index + 1);
|
|
74
|
+
const temporary = centers[index];
|
|
75
|
+
centers[index] = centers[swapIndex];
|
|
76
|
+
centers[swapIndex] = temporary;
|
|
77
|
+
}
|
|
78
|
+
return centers;
|
|
79
|
+
}
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Browser loader for the cube4 reduction tables (the committed .bin files).
|
|
4
|
+
* The manifests are per-phase (`center1-manifest.json`, ...).
|
|
5
|
+
*/
|
|
6
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
+
exports.getCachedCube4Tables = getCachedCube4Tables;
|
|
8
|
+
exports.clearCachedCube4Tables = clearCachedCube4Tables;
|
|
9
|
+
exports.loadCube4ReductionTablesBrowser = loadCube4ReductionTablesBrowser;
|
|
10
|
+
const edge3_js_1 = require("./edge3.js");
|
|
11
|
+
const compressed_fetch_js_1 = require("../../shared/compressed-fetch.js");
|
|
12
|
+
const GENERATED_DIRECTORY = "puzzles/cube4/reduction/generated";
|
|
13
|
+
const CACHE_NAME = "cubingcenter-scrambler-tables-v1";
|
|
14
|
+
let cachedTables;
|
|
15
|
+
function getCachedCube4Tables() {
|
|
16
|
+
return cachedTables;
|
|
17
|
+
}
|
|
18
|
+
function clearCachedCube4Tables() {
|
|
19
|
+
cachedTables = undefined;
|
|
20
|
+
}
|
|
21
|
+
function resolveBaseUrl(provided) {
|
|
22
|
+
if (provided) {
|
|
23
|
+
return provided.replace(/\/$/, "");
|
|
24
|
+
}
|
|
25
|
+
if (typeof document !== "undefined") {
|
|
26
|
+
const script = document.currentScript;
|
|
27
|
+
if (script?.src) {
|
|
28
|
+
const base = new URL(".", script.src).href;
|
|
29
|
+
return base.replace(/\/$/, "");
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
return ".";
|
|
33
|
+
}
|
|
34
|
+
async function loadCube4ReductionTablesBrowser(baseUrl) {
|
|
35
|
+
if (cachedTables) {
|
|
36
|
+
return cachedTables;
|
|
37
|
+
}
|
|
38
|
+
const resolved = resolveBaseUrl(baseUrl);
|
|
39
|
+
const [center1, center2, center3, edge3] = await Promise.all([
|
|
40
|
+
loadCenter1(resolved),
|
|
41
|
+
loadCenter2(resolved),
|
|
42
|
+
loadCenter3(resolved),
|
|
43
|
+
loadEdge3(resolved)
|
|
44
|
+
]);
|
|
45
|
+
cachedTables = { center1, center2, center3, edge3 };
|
|
46
|
+
return cachedTables;
|
|
47
|
+
}
|
|
48
|
+
async function fetchJson(baseUrl, file) {
|
|
49
|
+
const url = `${baseUrl}/${GENERATED_DIRECTORY}/${file}`;
|
|
50
|
+
const response = await fetch(url);
|
|
51
|
+
if (!response.ok) {
|
|
52
|
+
throw new Error(`Failed to load ${file}: ${response.status} ${response.statusText}`);
|
|
53
|
+
}
|
|
54
|
+
return response.json();
|
|
55
|
+
}
|
|
56
|
+
async function loadCenter1(baseUrl) {
|
|
57
|
+
const manifest = await fetchJson(baseUrl, "center1-manifest.json");
|
|
58
|
+
const [distanceBuffer, moveMapsBuffer] = await Promise.all([
|
|
59
|
+
(0, compressed_fetch_js_1.fetchTableBuffer)(baseUrl, GENERATED_DIRECTORY, manifest.distanceTable.file, { cacheName: CACHE_NAME, compressed: manifest.distanceTable.compressed !== false }),
|
|
60
|
+
(0, compressed_fetch_js_1.fetchTableBuffer)(baseUrl, GENERATED_DIRECTORY, manifest.moveMaps.file, { cacheName: CACHE_NAME, compressed: manifest.moveMaps.compressed !== false })
|
|
61
|
+
]);
|
|
62
|
+
return {
|
|
63
|
+
distance: new Uint8Array(distanceBuffer),
|
|
64
|
+
moveMaps: new Int32Array(moveMapsBuffer)
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
async function loadCenter2(baseUrl) {
|
|
68
|
+
const manifest = await fetchJson(baseUrl, "center2-manifest.json");
|
|
69
|
+
const [ctMoveBuffer, rlMoveBuffer, pruningBuffer] = await Promise.all([
|
|
70
|
+
(0, compressed_fetch_js_1.fetchTableBuffer)(baseUrl, GENERATED_DIRECTORY, manifest.ctMove.file, { cacheName: CACHE_NAME, compressed: manifest.ctMove.compressed !== false }),
|
|
71
|
+
(0, compressed_fetch_js_1.fetchTableBuffer)(baseUrl, GENERATED_DIRECTORY, manifest.rlMove.file, { cacheName: CACHE_NAME, compressed: manifest.rlMove.compressed !== false }),
|
|
72
|
+
(0, compressed_fetch_js_1.fetchTableBuffer)(baseUrl, GENERATED_DIRECTORY, manifest.pruningTable.file, { cacheName: CACHE_NAME, compressed: manifest.pruningTable.compressed !== false })
|
|
73
|
+
]);
|
|
74
|
+
const ctMove = new Int32Array(ctMoveBuffer);
|
|
75
|
+
const rlMove = new Int32Array(rlMoveBuffer);
|
|
76
|
+
const pruningPacked = new Uint8Array(pruningBuffer);
|
|
77
|
+
const pruning = new Uint8Array(450450);
|
|
78
|
+
for (let i = 0; i < 450450; i++) {
|
|
79
|
+
const byte = pruningPacked[i >> 1];
|
|
80
|
+
pruning[i] = (i & 1) === 0 ? byte & 0x0f : byte >> 4;
|
|
81
|
+
}
|
|
82
|
+
return { ctMove, rlMove, pruning };
|
|
83
|
+
}
|
|
84
|
+
async function loadCenter3(baseUrl) {
|
|
85
|
+
const manifest = await fetchJson(baseUrl, "center3-manifest.json");
|
|
86
|
+
const [moveTableBuffer, pruningBuffer] = await Promise.all([
|
|
87
|
+
(0, compressed_fetch_js_1.fetchTableBuffer)(baseUrl, GENERATED_DIRECTORY, manifest.moveTable.file, { cacheName: CACHE_NAME, compressed: manifest.moveTable.compressed !== false }),
|
|
88
|
+
(0, compressed_fetch_js_1.fetchTableBuffer)(baseUrl, GENERATED_DIRECTORY, manifest.pruningTable.file, { cacheName: CACHE_NAME, compressed: manifest.pruningTable.compressed !== false })
|
|
89
|
+
]);
|
|
90
|
+
return {
|
|
91
|
+
moveTable: new Int32Array(moveTableBuffer),
|
|
92
|
+
pruning: new Uint8Array(pruningBuffer)
|
|
93
|
+
};
|
|
94
|
+
}
|
|
95
|
+
async function loadEdge3(baseUrl) {
|
|
96
|
+
const manifest = await fetchJson(baseUrl, "edge3-manifest.json");
|
|
97
|
+
const distancesBuffer = await (0, compressed_fetch_js_1.fetchTableBuffer)(baseUrl, GENERATED_DIRECTORY, manifest.distances.file, { cacheName: CACHE_NAME, compressed: manifest.distances.compressed !== false });
|
|
98
|
+
const distances = new Uint8Array(distancesBuffer);
|
|
99
|
+
return { distances, distanceOfEdge: (0, edge3_js_1.edge3DistanceLookup)(distances) };
|
|
100
|
+
}
|