@cubingcenter/scrambler 0.4.0 → 0.5.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 +67 -3
- package/dist/core/api.d.ts.map +1 -1
- package/dist/core/api.js +18 -6
- package/dist/core/index.d.ts +1 -1
- package/dist/core/index.d.ts.map +1 -1
- package/dist/core/types.d.ts +7 -0
- package/dist/core/types.d.ts.map +1 -1
- package/dist/puzzles/clock/index.d.ts +1 -0
- package/dist/puzzles/clock/index.d.ts.map +1 -1
- package/dist/puzzles/clock/index.js +4 -0
- package/dist/puzzles/cube2/index.d.ts +1 -0
- package/dist/puzzles/cube2/index.d.ts.map +1 -1
- package/dist/puzzles/cube2/index.js +4 -0
- package/dist/puzzles/cube2/scrambler.d.ts.map +1 -1
- package/dist/puzzles/cube2/scrambler.js +4 -6
- package/dist/puzzles/cube2/solver/browser-loader.d.ts.map +1 -1
- package/dist/puzzles/cube2/solver/browser-loader.js +4 -12
- package/dist/puzzles/cube2/solver/index.d.ts +1 -1
- package/dist/puzzles/cube2/solver/index.d.ts.map +1 -1
- package/dist/puzzles/cube2/solver/index.js +1 -1
- package/dist/puzzles/cube2/solver/search.d.ts +2 -0
- package/dist/puzzles/cube2/solver/search.d.ts.map +1 -1
- package/dist/puzzles/cube2/solver/search.js +26 -0
- package/dist/puzzles/cube2/validation.d.ts.map +1 -1
- package/dist/puzzles/cube2/validation.js +15 -3
- package/dist/puzzles/cube3/index.d.ts +1 -0
- package/dist/puzzles/cube3/index.d.ts.map +1 -1
- package/dist/puzzles/cube3/index.js +4 -0
- package/dist/puzzles/cube3/solver/browser-loader.d.ts.map +1 -1
- package/dist/puzzles/cube3/solver/browser-loader.js +5 -29
- package/dist/puzzles/cube4/index.d.ts +1 -0
- package/dist/puzzles/cube4/index.d.ts.map +1 -1
- package/dist/puzzles/cube4/index.js +4 -0
- package/dist/puzzles/cube5x5/index.d.ts +1 -0
- package/dist/puzzles/cube5x5/index.d.ts.map +1 -1
- package/dist/puzzles/cube5x5/index.js +4 -0
- package/dist/puzzles/cube6x6/index.d.ts +1 -0
- package/dist/puzzles/cube6x6/index.d.ts.map +1 -1
- package/dist/puzzles/cube6x6/index.js +4 -0
- package/dist/puzzles/cube7x7/index.d.ts +1 -0
- package/dist/puzzles/cube7x7/index.d.ts.map +1 -1
- package/dist/puzzles/cube7x7/index.js +4 -0
- package/dist/puzzles/megaminx/index.d.ts +1 -0
- package/dist/puzzles/megaminx/index.d.ts.map +1 -1
- package/dist/puzzles/megaminx/index.js +4 -0
- package/dist/puzzles/pyraminx/index.d.ts +3 -1
- package/dist/puzzles/pyraminx/index.d.ts.map +1 -1
- package/dist/puzzles/pyraminx/index.js +6 -1
- package/dist/puzzles/pyraminx/scrambler.d.ts.map +1 -1
- package/dist/puzzles/pyraminx/scrambler.js +24 -20
- package/dist/puzzles/pyraminx/solver/browser-loader.d.ts +14 -0
- package/dist/puzzles/pyraminx/solver/browser-loader.d.ts.map +1 -0
- package/dist/puzzles/pyraminx/solver/browser-loader.js +63 -0
- package/dist/puzzles/pyraminx/solver/generated/centers-table.bin +0 -0
- package/dist/puzzles/pyraminx/solver/generated/manifest.json +26 -0
- package/dist/puzzles/pyraminx/solver/generated/orientation-table.bin +0 -0
- package/dist/puzzles/pyraminx/solver/generated/permutation-table.bin +0 -0
- package/dist/puzzles/pyraminx/solver/generated/policy.bin +0 -0
- package/dist/puzzles/pyraminx/solver/generated-assets.d.ts +7 -0
- package/dist/puzzles/pyraminx/solver/generated-assets.d.ts.map +1 -0
- package/dist/puzzles/pyraminx/solver/generated-assets.js +24 -0
- package/dist/puzzles/pyraminx/solver/index.d.ts +5 -0
- package/dist/puzzles/pyraminx/solver/index.d.ts.map +1 -0
- package/dist/puzzles/pyraminx/solver/index.js +4 -0
- package/dist/puzzles/pyraminx/solver/node-loader.d.ts +7 -0
- package/dist/puzzles/pyraminx/solver/node-loader.d.ts.map +1 -0
- package/dist/puzzles/pyraminx/solver/node-loader.js +73 -0
- package/dist/puzzles/pyraminx/solver/search.d.ts +10 -0
- package/dist/puzzles/pyraminx/solver/search.d.ts.map +1 -0
- package/dist/puzzles/pyraminx/solver/search.js +82 -0
- package/dist/puzzles/pyraminx/solver/table-metadata.d.ts +20 -0
- package/dist/puzzles/pyraminx/solver/table-metadata.d.ts.map +1 -0
- package/dist/puzzles/pyraminx/solver/table-metadata.js +19 -0
- package/dist/puzzles/pyraminx/solver/tables.d.ts +43 -0
- package/dist/puzzles/pyraminx/solver/tables.d.ts.map +1 -0
- package/dist/puzzles/pyraminx/solver/tables.js +300 -0
- package/dist/puzzles/shared/compressed-fetch.d.ts +12 -0
- package/dist/puzzles/shared/compressed-fetch.d.ts.map +1 -0
- package/dist/puzzles/shared/compressed-fetch.js +68 -0
- package/dist/puzzles/skewb/facelets.d.ts.map +1 -1
- package/dist/puzzles/skewb/facelets.js +46 -23
- package/dist/puzzles/skewb/index.d.ts +3 -1
- package/dist/puzzles/skewb/index.d.ts.map +1 -1
- package/dist/puzzles/skewb/index.js +6 -1
- package/dist/puzzles/skewb/random-state.d.ts +1 -1
- package/dist/puzzles/skewb/random-state.d.ts.map +1 -1
- package/dist/puzzles/skewb/random-state.js +25 -18
- package/dist/puzzles/skewb/scrambler.d.ts.map +1 -1
- package/dist/puzzles/skewb/scrambler.js +10 -13
- package/dist/puzzles/skewb/solver/browser-loader.d.ts +20 -0
- package/dist/puzzles/skewb/solver/browser-loader.d.ts.map +1 -0
- package/dist/puzzles/skewb/solver/browser-loader.js +86 -0
- package/dist/puzzles/skewb/solver/generated/centers-table.bin +0 -0
- package/dist/puzzles/skewb/solver/generated/helpers.bin +0 -0
- package/dist/puzzles/skewb/solver/generated/manifest.json +31 -0
- package/dist/puzzles/skewb/solver/generated/orientation-table.bin +0 -0
- package/dist/puzzles/skewb/solver/generated/permutation-table.bin +0 -0
- package/dist/puzzles/skewb/solver/generated/policy.bin +0 -0
- package/dist/puzzles/skewb/solver/generated-assets.d.ts +10 -0
- package/dist/puzzles/skewb/solver/generated-assets.d.ts.map +1 -0
- package/dist/puzzles/skewb/solver/generated-assets.js +24 -0
- package/dist/puzzles/skewb/solver/index.d.ts +5 -0
- package/dist/puzzles/skewb/solver/index.d.ts.map +1 -0
- package/dist/puzzles/skewb/solver/index.js +4 -0
- package/dist/puzzles/skewb/solver/node-loader.d.ts +10 -0
- package/dist/puzzles/skewb/solver/node-loader.d.ts.map +1 -0
- package/dist/puzzles/skewb/solver/node-loader.js +91 -0
- package/dist/puzzles/skewb/solver/search.d.ts +11 -0
- package/dist/puzzles/skewb/solver/search.d.ts.map +1 -0
- package/dist/puzzles/skewb/solver/search.js +80 -0
- package/dist/puzzles/skewb/solver/table-metadata.d.ts +27 -0
- package/dist/puzzles/skewb/solver/table-metadata.d.ts.map +1 -0
- package/dist/puzzles/skewb/solver/table-metadata.js +26 -0
- package/dist/puzzles/skewb/solver/tables.d.ts +68 -0
- package/dist/puzzles/skewb/solver/tables.d.ts.map +1 -0
- package/dist/puzzles/skewb/solver/tables.js +508 -0
- package/dist/random/prng.js +10 -1
- package/dist-cjs/core/api.js +51 -6
- package/dist-cjs/puzzles/clock/index.js +13 -4
- package/dist-cjs/puzzles/cube2/index.js +13 -4
- package/dist-cjs/puzzles/cube2/scrambler.js +2 -4
- package/dist-cjs/puzzles/cube2/solver/browser-loader.js +4 -12
- package/dist-cjs/puzzles/cube2/solver/index.js +3 -1
- package/dist-cjs/puzzles/cube2/solver/search.js +28 -0
- package/dist-cjs/puzzles/cube2/validation.js +14 -2
- package/dist-cjs/puzzles/cube3/index.js +13 -4
- package/dist-cjs/puzzles/cube3/solver/browser-loader.js +5 -29
- package/dist-cjs/puzzles/cube4/index.js +13 -4
- package/dist-cjs/puzzles/cube5x5/index.js +13 -4
- package/dist-cjs/puzzles/cube6x6/index.js +13 -4
- package/dist-cjs/puzzles/cube7x7/index.js +13 -4
- package/dist-cjs/puzzles/megaminx/index.js +13 -4
- package/dist-cjs/puzzles/pyraminx/index.js +50 -6
- package/dist-cjs/puzzles/pyraminx/scrambler.js +23 -19
- package/dist-cjs/puzzles/pyraminx/solver/browser-loader.js +68 -0
- package/dist-cjs/puzzles/pyraminx/solver/generated/centers-table.bin +0 -0
- package/dist-cjs/puzzles/pyraminx/solver/generated/manifest.json +26 -0
- package/dist-cjs/puzzles/pyraminx/solver/generated/orientation-table.bin +0 -0
- package/dist-cjs/puzzles/pyraminx/solver/generated/permutation-table.bin +0 -0
- package/dist-cjs/puzzles/pyraminx/solver/generated/policy.bin +0 -0
- package/dist-cjs/puzzles/pyraminx/solver/generated-assets.js +60 -0
- package/dist-cjs/puzzles/pyraminx/solver/index.js +23 -0
- package/dist-cjs/puzzles/pyraminx/solver/node-loader.js +79 -0
- package/dist-cjs/puzzles/pyraminx/solver/search.js +88 -0
- package/dist-cjs/puzzles/pyraminx/solver/table-metadata.js +22 -0
- package/dist-cjs/puzzles/pyraminx/solver/tables.js +327 -0
- package/dist-cjs/puzzles/shared/compressed-fetch.js +71 -0
- package/dist-cjs/puzzles/skewb/facelets.js +46 -23
- package/dist-cjs/puzzles/skewb/index.js +55 -8
- package/dist-cjs/puzzles/skewb/random-state.js +25 -18
- package/dist-cjs/puzzles/skewb/scrambler.js +9 -12
- package/dist-cjs/puzzles/skewb/solver/browser-loader.js +91 -0
- package/dist-cjs/puzzles/skewb/solver/generated/centers-table.bin +0 -0
- package/dist-cjs/puzzles/skewb/solver/generated/helpers.bin +0 -0
- package/dist-cjs/puzzles/skewb/solver/generated/manifest.json +31 -0
- package/dist-cjs/puzzles/skewb/solver/generated/orientation-table.bin +0 -0
- package/dist-cjs/puzzles/skewb/solver/generated/permutation-table.bin +0 -0
- package/dist-cjs/puzzles/skewb/solver/generated/policy.bin +0 -0
- package/dist-cjs/puzzles/skewb/solver/generated-assets.js +60 -0
- package/dist-cjs/puzzles/skewb/solver/index.js +23 -0
- package/dist-cjs/puzzles/skewb/solver/node-loader.js +97 -0
- package/dist-cjs/puzzles/skewb/solver/search.js +87 -0
- package/dist-cjs/puzzles/skewb/solver/table-metadata.js +29 -0
- package/dist-cjs/puzzles/skewb/solver/tables.js +539 -0
- package/dist-cjs/random/prng.js +10 -1
- package/package.json +20 -6
- package/dist/puzzles/pyraminx/solver.d.ts +0 -10
- package/dist/puzzles/pyraminx/solver.d.ts.map +0 -1
- package/dist/puzzles/pyraminx/solver.js +0 -160
- package/dist/puzzles/skewb/solver.d.ts +0 -11
- package/dist/puzzles/skewb/solver.d.ts.map +0 -1
- package/dist/puzzles/skewb/solver.js +0 -149
- package/dist-cjs/puzzles/pyraminx/solver.js +0 -170
- package/dist-cjs/puzzles/skewb/solver.js +0 -160
|
@@ -0,0 +1,508 @@
|
|
|
1
|
+
import { applySkewbMove } from "../moves.js";
|
|
2
|
+
import { loadGeneratedSkewbSolverTables } from "./generated-assets.js";
|
|
3
|
+
// ---------------------------------------------------------------------------
|
|
4
|
+
// Coordinate encoding / decoding (kept from the original solver.ts)
|
|
5
|
+
// ---------------------------------------------------------------------------
|
|
6
|
+
const FACT = [1, 1, 2, 6, 24, 120, 720, 5040, 40320];
|
|
7
|
+
// Popcount lookup (0..255) for the allocation-free Lehmer encoders below.
|
|
8
|
+
const POPCOUNT = new Uint8Array(256);
|
|
9
|
+
for (let i = 1; i < 256; i++)
|
|
10
|
+
POPCOUNT[i] = POPCOUNT[i >> 1] + (i & 1);
|
|
11
|
+
export function getPermutationIndex(perm) {
|
|
12
|
+
// perm length 8, but pos0 is always 0 for WCA reachable states.
|
|
13
|
+
// We encode full 8-perm via Lehmer code (0..40319), but for fixed corner it will be in subset.
|
|
14
|
+
let index = 0;
|
|
15
|
+
let used = 0;
|
|
16
|
+
const n = perm.length;
|
|
17
|
+
for (let i = 0; i < n; i++) {
|
|
18
|
+
const v = perm[i];
|
|
19
|
+
const digit = v - POPCOUNT[used & ((1 << v) - 1)];
|
|
20
|
+
used |= 1 << v;
|
|
21
|
+
index += digit * FACT[n - 1 - i];
|
|
22
|
+
}
|
|
23
|
+
return index;
|
|
24
|
+
}
|
|
25
|
+
export function getPermutationFromIndex(index, n) {
|
|
26
|
+
const perm = Array(n).fill(0);
|
|
27
|
+
const temp = Array.from({ length: n }, (_, i) => i);
|
|
28
|
+
let val = index;
|
|
29
|
+
for (let i = 0; i < n; i++) {
|
|
30
|
+
const f = FACT[n - 1 - i];
|
|
31
|
+
const choice = Math.floor(val / f);
|
|
32
|
+
val %= f;
|
|
33
|
+
perm[i] = temp[choice];
|
|
34
|
+
temp.splice(choice, 1);
|
|
35
|
+
}
|
|
36
|
+
return perm;
|
|
37
|
+
}
|
|
38
|
+
export function getOrientationIndex(orient) {
|
|
39
|
+
// orient length 8, index 0 is fixed 0, encode remaining 7 base3
|
|
40
|
+
let index = 0;
|
|
41
|
+
for (let i = 7; i >= 1; i--) {
|
|
42
|
+
index = index * 3 + orient[i];
|
|
43
|
+
}
|
|
44
|
+
return index;
|
|
45
|
+
}
|
|
46
|
+
export function getOrientationFromIndex(index) {
|
|
47
|
+
const orient = Array(8).fill(0);
|
|
48
|
+
orient[0] = 0;
|
|
49
|
+
let val = index;
|
|
50
|
+
for (let i = 1; i < 8; i++) {
|
|
51
|
+
orient[i] = val % 3;
|
|
52
|
+
val = Math.floor(val / 3);
|
|
53
|
+
}
|
|
54
|
+
return orient;
|
|
55
|
+
}
|
|
56
|
+
export function getCenterIndex(centers) {
|
|
57
|
+
let index = 0;
|
|
58
|
+
let used = 0;
|
|
59
|
+
const n = centers.length;
|
|
60
|
+
for (let i = 0; i < n; i++) {
|
|
61
|
+
const v = centers[i];
|
|
62
|
+
const digit = v - POPCOUNT[used & ((1 << v) - 1)];
|
|
63
|
+
used |= 1 << v;
|
|
64
|
+
index += digit * FACT[n - 1 - i];
|
|
65
|
+
}
|
|
66
|
+
return index;
|
|
67
|
+
}
|
|
68
|
+
export function getCenterFromIndex(index) {
|
|
69
|
+
return getPermutationFromIndex(index, 6);
|
|
70
|
+
}
|
|
71
|
+
export function getStateIndex(state) {
|
|
72
|
+
const p = getPermutationIndex(state.corners.permutation);
|
|
73
|
+
const c = getCenterIndex(state.centers);
|
|
74
|
+
const o = getOrientationIndex(state.corners.orientation);
|
|
75
|
+
// p in 0..40319, c in 0..719, o in 0..2186
|
|
76
|
+
// Combine: ((p * 720 + c) * 2187 + o) -> up to 63B fits in JS number (53-bit)
|
|
77
|
+
return ((p * 720 + c) * 2187 + o);
|
|
78
|
+
}
|
|
79
|
+
export function getStateFromIndex(index) {
|
|
80
|
+
const o = index % 2187;
|
|
81
|
+
let val = Math.floor(index / 2187);
|
|
82
|
+
const c = val % 720;
|
|
83
|
+
const p = Math.floor(val / 720);
|
|
84
|
+
return {
|
|
85
|
+
corners: {
|
|
86
|
+
permutation: getPermutationFromIndex(p, 8),
|
|
87
|
+
orientation: getOrientationFromIndex(o),
|
|
88
|
+
},
|
|
89
|
+
centers: getCenterFromIndex(c),
|
|
90
|
+
};
|
|
91
|
+
}
|
|
92
|
+
// ---------------------------------------------------------------------------
|
|
93
|
+
// Compact encoding over the WCA-reachable group (3,149,280 states)
|
|
94
|
+
// ---------------------------------------------------------------------------
|
|
95
|
+
// With the UFR corner fixed (position 0, orientation 0), the reachable group
|
|
96
|
+
// factors as:
|
|
97
|
+
// rC: even center permutations only -> 360
|
|
98
|
+
// rO: orientations of corners 1..7 -> 2187, partitioned into 9 classes
|
|
99
|
+
// r7: corner permutations of 1..7 -> exactly 4 values per (rC, rO-class)
|
|
100
|
+
// so rank = (rC_even * 2187 + rO) * 4 + k is a bijection over the reachable set.
|
|
101
|
+
export const PERMUTATION_COUNT = 5040; // r7: corners 1..7 Lehmer
|
|
102
|
+
export const ORIENTATION_COUNT = 2187; // rO: corners 1..7 base-3
|
|
103
|
+
export const CENTER_COUNT = 720; // rC: centers Lehmer
|
|
104
|
+
export const EVEN_CENTER_COUNT = 360; // reachable center arrangements
|
|
105
|
+
export const ORIENT_CLASS_COUNT = 9; // orientation classes
|
|
106
|
+
export const PER_SET_SIZE = 4; // corner permutations per (rC, rO-class)
|
|
107
|
+
export const MOVE_COUNT = 8;
|
|
108
|
+
export const STATE_COUNT = EVEN_CENTER_COUNT * ORIENTATION_COUNT * PER_SET_SIZE; // 3_149_280
|
|
109
|
+
export const POLICY_PACKED_ENTRIES = Math.ceil((STATE_COUNT * 3) / 8);
|
|
110
|
+
export const SKEWB_MOVES = ["R", "R'", "U", "U'", "L", "L'", "B", "B'"];
|
|
111
|
+
export function getPerm7Index(perm) {
|
|
112
|
+
// Lehmer rank of the positions 1..7 (values 1..7, offset by -1).
|
|
113
|
+
// Allocation-free: digit = count of unused values below the current one,
|
|
114
|
+
// computed with a used-bitmask and a popcount lookup.
|
|
115
|
+
let index = 0;
|
|
116
|
+
let used = 0;
|
|
117
|
+
for (let i = 1; i < 8; i++) {
|
|
118
|
+
const v = perm[i] - 1;
|
|
119
|
+
const digit = v - POPCOUNT[used & ((1 << v) - 1)];
|
|
120
|
+
used |= 1 << v;
|
|
121
|
+
index += digit * FACT[7 - i];
|
|
122
|
+
}
|
|
123
|
+
return index;
|
|
124
|
+
}
|
|
125
|
+
export function getPerm7FromIndex(index) {
|
|
126
|
+
const perm = Array(8).fill(0);
|
|
127
|
+
const available = [1, 2, 3, 4, 5, 6, 7];
|
|
128
|
+
let val = index;
|
|
129
|
+
for (let i = 1; i < 8; i++) {
|
|
130
|
+
const f = FACT[7 - i];
|
|
131
|
+
const choice = Math.floor(val / f);
|
|
132
|
+
val %= f;
|
|
133
|
+
perm[i] = available[choice];
|
|
134
|
+
available.splice(choice, 1);
|
|
135
|
+
}
|
|
136
|
+
return perm;
|
|
137
|
+
}
|
|
138
|
+
// ---------------------------------------------------------------------------
|
|
139
|
+
// Table loading / runtime state
|
|
140
|
+
// ---------------------------------------------------------------------------
|
|
141
|
+
let tablesLoaded = false;
|
|
142
|
+
export let PERMUTATION_TABLE = null; // r7 * MOVE_COUNT + m
|
|
143
|
+
export let ORIENTATION_TABLE = null; // rO * MOVE_COUNT + m
|
|
144
|
+
export let CENTERS_TABLE = null; // rC * MOVE_COUNT + m
|
|
145
|
+
export let POLICY_TABLE = null; // optimal move per rank, 3-bit packed
|
|
146
|
+
export let EVEN_CENTER_RANK = null; // rC -> compact 0..359 (65535 = odd)
|
|
147
|
+
export let EVEN_CENTER_FULL = null; // compact 0..359 -> rC (derived at load)
|
|
148
|
+
export let ORIENT_CLASS = null; // rO -> class 0..8
|
|
149
|
+
export let R7_SETS = null; // (rC_even * 9 + class) * 4 + i
|
|
150
|
+
export let PERM7_UNRANK = null; // r7 * 7 + i -> piece at corner i+1 (derived at load)
|
|
151
|
+
export let CENTER_UNRANK = null; // rC * 6 + i -> center piece (derived at load)
|
|
152
|
+
export let SOLVED_RANK = 0;
|
|
153
|
+
export async function ensureTablesLoaded() {
|
|
154
|
+
if (tablesLoaded)
|
|
155
|
+
return;
|
|
156
|
+
const tables = await loadGeneratedSkewbSolverTables();
|
|
157
|
+
assignTables(tables);
|
|
158
|
+
}
|
|
159
|
+
export function assignTables(tables) {
|
|
160
|
+
PERMUTATION_TABLE = tables.permutationTable;
|
|
161
|
+
ORIENTATION_TABLE = tables.orientationTable;
|
|
162
|
+
CENTERS_TABLE = tables.centersTable;
|
|
163
|
+
POLICY_TABLE = tables.policyTable;
|
|
164
|
+
EVEN_CENTER_RANK = tables.evenCenterRank;
|
|
165
|
+
ORIENT_CLASS = tables.orientClass;
|
|
166
|
+
R7_SETS = tables.r7Sets;
|
|
167
|
+
EVEN_CENTER_FULL = new Uint16Array(EVEN_CENTER_COUNT);
|
|
168
|
+
for (let rC = 0; rC < CENTER_COUNT; rC++) {
|
|
169
|
+
const compactIdx = tables.evenCenterRank[rC];
|
|
170
|
+
if (compactIdx !== 65535)
|
|
171
|
+
EVEN_CENTER_FULL[compactIdx] = rC;
|
|
172
|
+
}
|
|
173
|
+
PERM7_UNRANK = new Uint8Array(PERMUTATION_COUNT * 7);
|
|
174
|
+
for (let r7 = 0; r7 < PERMUTATION_COUNT; r7++) {
|
|
175
|
+
const perm = getPerm7FromIndex(r7);
|
|
176
|
+
for (let i = 0; i < 7; i++)
|
|
177
|
+
PERM7_UNRANK[r7 * 7 + i] = perm[i + 1];
|
|
178
|
+
}
|
|
179
|
+
CENTER_UNRANK = new Uint8Array(CENTER_COUNT * 6);
|
|
180
|
+
for (let rC = 0; rC < CENTER_COUNT; rC++) {
|
|
181
|
+
const centers = getCenterFromIndex(rC);
|
|
182
|
+
for (let i = 0; i < 6; i++)
|
|
183
|
+
CENTER_UNRANK[rC * 6 + i] = centers[i];
|
|
184
|
+
}
|
|
185
|
+
SOLVED_RANK = rankFromComponents(0, 0, 0);
|
|
186
|
+
tablesLoaded = true;
|
|
187
|
+
}
|
|
188
|
+
export function resetTablesForTests() {
|
|
189
|
+
tablesLoaded = false;
|
|
190
|
+
PERMUTATION_TABLE = null;
|
|
191
|
+
ORIENTATION_TABLE = null;
|
|
192
|
+
CENTERS_TABLE = null;
|
|
193
|
+
POLICY_TABLE = null;
|
|
194
|
+
EVEN_CENTER_RANK = null;
|
|
195
|
+
EVEN_CENTER_FULL = null;
|
|
196
|
+
ORIENT_CLASS = null;
|
|
197
|
+
R7_SETS = null;
|
|
198
|
+
PERM7_UNRANK = null;
|
|
199
|
+
CENTER_UNRANK = null;
|
|
200
|
+
}
|
|
201
|
+
// ---------------------------------------------------------------------------
|
|
202
|
+
// Compact rank helpers
|
|
203
|
+
// ---------------------------------------------------------------------------
|
|
204
|
+
export function rankFromComponents(r7, rO, rC) {
|
|
205
|
+
const evenRank = EVEN_CENTER_RANK[rC];
|
|
206
|
+
if (evenRank === 65535) {
|
|
207
|
+
throw new Error("Unreachable Skewb state: odd center permutation parity.");
|
|
208
|
+
}
|
|
209
|
+
const cls = ORIENT_CLASS[rO];
|
|
210
|
+
const set = R7_SETS;
|
|
211
|
+
const base = (evenRank * ORIENT_CLASS_COUNT + cls) * PER_SET_SIZE;
|
|
212
|
+
for (let i = 0; i < PER_SET_SIZE; i++) {
|
|
213
|
+
if (set[base + i] === r7) {
|
|
214
|
+
return (evenRank * ORIENTATION_COUNT + rO) * PER_SET_SIZE + i;
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
throw new Error("Unreachable Skewb state: corner permutation not in reachable set.");
|
|
218
|
+
}
|
|
219
|
+
export function getStateRank(state) {
|
|
220
|
+
if (state.corners.permutation[0] !== 0) {
|
|
221
|
+
throw new Error("The Skewb solver requires the UFR corner (index 0) to be fixed " +
|
|
222
|
+
"as the frame of reference. Please normalize the state before solving.");
|
|
223
|
+
}
|
|
224
|
+
const r7 = getPerm7Index(state.corners.permutation);
|
|
225
|
+
const rO = getOrientationIndex(state.corners.orientation);
|
|
226
|
+
const rC = getCenterIndex(state.centers);
|
|
227
|
+
return rankFromComponents(r7, rO, rC);
|
|
228
|
+
}
|
|
229
|
+
// Inverse of getStateRank: decodes a reachable rank (0..3_149_279) back into
|
|
230
|
+
// a full state. Used for exact uniform random-state sampling.
|
|
231
|
+
export function getStateFromRank(rank) {
|
|
232
|
+
const even = Math.floor(rank / (ORIENTATION_COUNT * PER_SET_SIZE));
|
|
233
|
+
const rest = rank % (ORIENTATION_COUNT * PER_SET_SIZE);
|
|
234
|
+
const rO = Math.floor(rest / PER_SET_SIZE);
|
|
235
|
+
const k = rest % PER_SET_SIZE;
|
|
236
|
+
const cls = ORIENT_CLASS[rO];
|
|
237
|
+
const r7 = R7_SETS[(even * ORIENT_CLASS_COUNT + cls) * PER_SET_SIZE + k];
|
|
238
|
+
const perm = new Array(8);
|
|
239
|
+
perm[0] = 0;
|
|
240
|
+
const permBase = r7 * 7;
|
|
241
|
+
for (let i = 0; i < 7; i++)
|
|
242
|
+
perm[i + 1] = PERM7_UNRANK[permBase + i];
|
|
243
|
+
const orient = new Array(8);
|
|
244
|
+
orient[0] = 0;
|
|
245
|
+
let val = rO;
|
|
246
|
+
for (let i = 1; i < 8; i++) {
|
|
247
|
+
orient[i] = val % 3;
|
|
248
|
+
val = Math.floor(val / 3);
|
|
249
|
+
}
|
|
250
|
+
const centers = new Array(6);
|
|
251
|
+
const centerBase = EVEN_CENTER_FULL[even] * 6;
|
|
252
|
+
for (let i = 0; i < 6; i++)
|
|
253
|
+
centers[i] = CENTER_UNRANK[centerBase + i];
|
|
254
|
+
return { corners: { permutation: perm, orientation: orient }, centers };
|
|
255
|
+
}
|
|
256
|
+
// 3-bit little-endian unpacking of the packed policy table.
|
|
257
|
+
export function getPolicyMoveFromPacked(packed, stateRank) {
|
|
258
|
+
const bits = stateRank * 3;
|
|
259
|
+
const byteIndex = bits >> 3;
|
|
260
|
+
const offset = bits & 7;
|
|
261
|
+
const word = (packed[byteIndex] | ((packed[byteIndex + 1] ?? 0) << 8)) >> offset;
|
|
262
|
+
return word & 0x07;
|
|
263
|
+
}
|
|
264
|
+
export function getPolicyMove(stateRank) {
|
|
265
|
+
if (!POLICY_TABLE) {
|
|
266
|
+
throw new Error("Skewb solver tables not loaded. Call ensureTablesLoaded() first.");
|
|
267
|
+
}
|
|
268
|
+
return getPolicyMoveFromPacked(POLICY_TABLE, stateRank);
|
|
269
|
+
}
|
|
270
|
+
export function getPermutationTransition(permIdx, move) {
|
|
271
|
+
if (!PERMUTATION_TABLE) {
|
|
272
|
+
throw new Error("Skewb solver tables not loaded. Call ensureTablesLoaded() first.");
|
|
273
|
+
}
|
|
274
|
+
return PERMUTATION_TABLE[permIdx * MOVE_COUNT + move];
|
|
275
|
+
}
|
|
276
|
+
export function getOrientationTransition(orientIdx, move) {
|
|
277
|
+
if (!ORIENTATION_TABLE) {
|
|
278
|
+
throw new Error("Skewb solver tables not loaded. Call ensureTablesLoaded() first.");
|
|
279
|
+
}
|
|
280
|
+
return ORIENTATION_TABLE[orientIdx * MOVE_COUNT + move];
|
|
281
|
+
}
|
|
282
|
+
export function getCentersTransition(centerIdx, move) {
|
|
283
|
+
if (!CENTERS_TABLE) {
|
|
284
|
+
throw new Error("Skewb solver tables not loaded. Call ensureTablesLoaded() first.");
|
|
285
|
+
}
|
|
286
|
+
return CENTERS_TABLE[centerIdx * MOVE_COUNT + move];
|
|
287
|
+
}
|
|
288
|
+
// ---------------------------------------------------------------------------
|
|
289
|
+
// Table generation (used by the generate script)
|
|
290
|
+
// ---------------------------------------------------------------------------
|
|
291
|
+
export function generatePermutationTable() {
|
|
292
|
+
const table = new Uint16Array(PERMUTATION_COUNT * MOVE_COUNT);
|
|
293
|
+
for (let r7 = 0; r7 < PERMUTATION_COUNT; r7++) {
|
|
294
|
+
const perm = getPerm7FromIndex(r7);
|
|
295
|
+
for (let m = 0; m < MOVE_COUNT; m++) {
|
|
296
|
+
const state = {
|
|
297
|
+
corners: { permutation: [...perm], orientation: [0, 0, 0, 0, 0, 0, 0, 0] },
|
|
298
|
+
centers: [0, 1, 2, 3, 4, 5],
|
|
299
|
+
};
|
|
300
|
+
const next = applySkewbMove(state, SKEWB_MOVES[m]);
|
|
301
|
+
table[r7 * MOVE_COUNT + m] = getPerm7Index(next.corners.permutation);
|
|
302
|
+
}
|
|
303
|
+
}
|
|
304
|
+
return table;
|
|
305
|
+
}
|
|
306
|
+
export function generateOrientationTable() {
|
|
307
|
+
const table = new Uint16Array(ORIENTATION_COUNT * MOVE_COUNT);
|
|
308
|
+
for (let rO = 0; rO < ORIENTATION_COUNT; rO++) {
|
|
309
|
+
const orient = getOrientationFromIndex(rO);
|
|
310
|
+
for (let m = 0; m < MOVE_COUNT; m++) {
|
|
311
|
+
const state = {
|
|
312
|
+
corners: { permutation: [0, 1, 2, 3, 4, 5, 6, 7], orientation: [...orient] },
|
|
313
|
+
centers: [0, 1, 2, 3, 4, 5],
|
|
314
|
+
};
|
|
315
|
+
const next = applySkewbMove(state, SKEWB_MOVES[m]);
|
|
316
|
+
table[rO * MOVE_COUNT + m] = getOrientationIndex(next.corners.orientation);
|
|
317
|
+
}
|
|
318
|
+
}
|
|
319
|
+
return table;
|
|
320
|
+
}
|
|
321
|
+
export function generateCentersTable() {
|
|
322
|
+
const table = new Uint16Array(CENTER_COUNT * MOVE_COUNT);
|
|
323
|
+
for (let rC = 0; rC < CENTER_COUNT; rC++) {
|
|
324
|
+
const centers = getCenterFromIndex(rC);
|
|
325
|
+
for (let m = 0; m < MOVE_COUNT; m++) {
|
|
326
|
+
const state = {
|
|
327
|
+
corners: { permutation: [0, 1, 2, 3, 4, 5, 6, 7], orientation: [0, 0, 0, 0, 0, 0, 0, 0] },
|
|
328
|
+
centers: [...centers],
|
|
329
|
+
};
|
|
330
|
+
const next = applySkewbMove(state, SKEWB_MOVES[m]);
|
|
331
|
+
table[rC * MOVE_COUNT + m] = getCenterIndex(next.centers);
|
|
332
|
+
}
|
|
333
|
+
}
|
|
334
|
+
return table;
|
|
335
|
+
}
|
|
336
|
+
export function permutationParity(perm) {
|
|
337
|
+
let inversions = 0;
|
|
338
|
+
for (let i = 0; i < perm.length; i++) {
|
|
339
|
+
for (let j = i + 1; j < perm.length; j++) {
|
|
340
|
+
if (perm[i] > perm[j])
|
|
341
|
+
inversions++;
|
|
342
|
+
}
|
|
343
|
+
}
|
|
344
|
+
return inversions % 2;
|
|
345
|
+
}
|
|
346
|
+
// Discovers the reachable-state structure with a BFS over the full product
|
|
347
|
+
// coordinate (r7, rO, rC) and derives the compact-rank helper tables:
|
|
348
|
+
// - even center permutations only (360 of 720)
|
|
349
|
+
// - rO partitioned into 9 classes by the 4-corner-permutation sets
|
|
350
|
+
export function generateHelperTables(permTable, orientTable, centersTable) {
|
|
351
|
+
const evenCenterRank = new Uint16Array(CENTER_COUNT).fill(65535);
|
|
352
|
+
const evenCenterFull = new Uint16Array(EVEN_CENTER_COUNT);
|
|
353
|
+
let compact = 0;
|
|
354
|
+
for (let rC = 0; rC < CENTER_COUNT; rC++) {
|
|
355
|
+
if (permutationParity(getCenterFromIndex(rC)) === 0) {
|
|
356
|
+
evenCenterRank[rC] = compact;
|
|
357
|
+
evenCenterFull[compact] = rC;
|
|
358
|
+
compact++;
|
|
359
|
+
}
|
|
360
|
+
}
|
|
361
|
+
if (compact !== EVEN_CENTER_COUNT) {
|
|
362
|
+
throw new Error(`Expected ${EVEN_CENTER_COUNT} even center permutations, found ${compact}.`);
|
|
363
|
+
}
|
|
364
|
+
const pack = (r7, rO, rC) => (r7 * ORIENTATION_COUNT + rO) * CENTER_COUNT + rC;
|
|
365
|
+
const pairSets = new Map();
|
|
366
|
+
const seen = new Set([0]);
|
|
367
|
+
const queue = [0];
|
|
368
|
+
let head = 0;
|
|
369
|
+
while (head < queue.length) {
|
|
370
|
+
const cur = queue[head++];
|
|
371
|
+
const rC = cur % CENTER_COUNT;
|
|
372
|
+
const rest = Math.floor(cur / CENTER_COUNT);
|
|
373
|
+
const rO = rest % ORIENTATION_COUNT;
|
|
374
|
+
const r7 = Math.floor(rest / ORIENTATION_COUNT);
|
|
375
|
+
const pairKey = rC * ORIENTATION_COUNT + rO;
|
|
376
|
+
let set = pairSets.get(pairKey);
|
|
377
|
+
if (!set) {
|
|
378
|
+
set = new Set();
|
|
379
|
+
pairSets.set(pairKey, set);
|
|
380
|
+
}
|
|
381
|
+
set.add(r7);
|
|
382
|
+
for (let m = 0; m < MOVE_COUNT; m++) {
|
|
383
|
+
const n7 = permTable[r7 * MOVE_COUNT + m];
|
|
384
|
+
const nO = orientTable[rO * MOVE_COUNT + m];
|
|
385
|
+
const nC = centersTable[rC * MOVE_COUNT + m];
|
|
386
|
+
const next = pack(n7, nO, nC);
|
|
387
|
+
if (!seen.has(next)) {
|
|
388
|
+
seen.add(next);
|
|
389
|
+
queue.push(next);
|
|
390
|
+
}
|
|
391
|
+
}
|
|
392
|
+
}
|
|
393
|
+
if (seen.size !== STATE_COUNT) {
|
|
394
|
+
throw new Error(`Reachability BFS covered ${seen.size} states, expected ${STATE_COUNT}.`);
|
|
395
|
+
}
|
|
396
|
+
const setKey = (values) => [...values].sort((a, b) => a - b).join(",");
|
|
397
|
+
// Reference partition from rC = 0 (verified identical for all even rC).
|
|
398
|
+
const orientClass = new Uint8Array(ORIENTATION_COUNT);
|
|
399
|
+
const classOfSet = new Map();
|
|
400
|
+
for (let rO = 0; rO < ORIENTATION_COUNT; rO++) {
|
|
401
|
+
const set = pairSets.get(rO);
|
|
402
|
+
const key = setKey(set);
|
|
403
|
+
if (!classOfSet.has(key)) {
|
|
404
|
+
classOfSet.set(key, classOfSet.size);
|
|
405
|
+
}
|
|
406
|
+
orientClass[rO] = classOfSet.get(key);
|
|
407
|
+
}
|
|
408
|
+
if (classOfSet.size !== ORIENT_CLASS_COUNT) {
|
|
409
|
+
throw new Error(`Expected ${ORIENT_CLASS_COUNT} orientation classes, found ${classOfSet.size}.`);
|
|
410
|
+
}
|
|
411
|
+
// Verify the partition is identical for every even rC and that each
|
|
412
|
+
// (rC, class) has exactly PER_SET_SIZE corner permutations.
|
|
413
|
+
const r7Sets = new Uint16Array(EVEN_CENTER_COUNT * ORIENT_CLASS_COUNT * PER_SET_SIZE);
|
|
414
|
+
for (let rC = 0; rC < CENTER_COUNT; rC++) {
|
|
415
|
+
const rCCompact = evenCenterRank[rC];
|
|
416
|
+
if (rCCompact === 65535)
|
|
417
|
+
continue;
|
|
418
|
+
for (let rO = 0; rO < ORIENTATION_COUNT; rO++) {
|
|
419
|
+
const set = pairSets.get(rC * ORIENTATION_COUNT + rO);
|
|
420
|
+
if (set.size !== PER_SET_SIZE) {
|
|
421
|
+
throw new Error(`Expected ${PER_SET_SIZE} permutations for (rC=${rC}, rO=${rO}), found ${set.size}.`);
|
|
422
|
+
}
|
|
423
|
+
const cls = orientClass[rO];
|
|
424
|
+
if (classOfSet.get(setKey(set)) !== cls) {
|
|
425
|
+
throw new Error(`Orientation class partition differs at rC=${rC}, rO=${rO}.`);
|
|
426
|
+
}
|
|
427
|
+
const stored = [...set].sort((a, b) => a - b);
|
|
428
|
+
const base = (rCCompact * ORIENT_CLASS_COUNT + cls) * PER_SET_SIZE;
|
|
429
|
+
for (let i = 0; i < PER_SET_SIZE; i++)
|
|
430
|
+
r7Sets[base + i] = stored[i];
|
|
431
|
+
}
|
|
432
|
+
}
|
|
433
|
+
return { evenCenterRank, orientClass, r7Sets, evenCenterFull };
|
|
434
|
+
}
|
|
435
|
+
// BFS from solved stores, for each state, the inverse of the move that first
|
|
436
|
+
// discovered it: an optimal move toward solved. Packed 3 bits per state
|
|
437
|
+
// (8 moves; the solved entry is never read, the solve loop exits first).
|
|
438
|
+
export function generatePolicyTable(permTable, orientTable, centersTable, helpers) {
|
|
439
|
+
// Install the compact-rank tables for the duration of the build.
|
|
440
|
+
const saved = { evenCenterRank: EVEN_CENTER_RANK, orientClass: ORIENT_CLASS, r7Sets: R7_SETS };
|
|
441
|
+
EVEN_CENTER_RANK = helpers.evenCenterRank;
|
|
442
|
+
ORIENT_CLASS = helpers.orientClass;
|
|
443
|
+
R7_SETS = helpers.r7Sets;
|
|
444
|
+
try {
|
|
445
|
+
const solvedRank = rankFromComponents(0, 0, 0);
|
|
446
|
+
const distances = new Uint8Array(STATE_COUNT).fill(255);
|
|
447
|
+
const policy = new Uint8Array(STATE_COUNT);
|
|
448
|
+
distances[solvedRank] = 0;
|
|
449
|
+
const queue = new Uint32Array(STATE_COUNT);
|
|
450
|
+
let read = 0;
|
|
451
|
+
let write = 1;
|
|
452
|
+
queue[0] = solvedRank;
|
|
453
|
+
let maxDepth = 0;
|
|
454
|
+
while (read < write) {
|
|
455
|
+
const curr = queue[read++];
|
|
456
|
+
const dist = distances[curr];
|
|
457
|
+
const even = Math.floor(curr / (ORIENTATION_COUNT * PER_SET_SIZE));
|
|
458
|
+
const rest = curr % (ORIENTATION_COUNT * PER_SET_SIZE);
|
|
459
|
+
const rO = Math.floor(rest / PER_SET_SIZE);
|
|
460
|
+
const k = rest % PER_SET_SIZE;
|
|
461
|
+
const cls = ORIENT_CLASS[rO];
|
|
462
|
+
const r7 = R7_SETS[(even * ORIENT_CLASS_COUNT + cls) * PER_SET_SIZE + k];
|
|
463
|
+
const rC = helpers.evenCenterFull[even];
|
|
464
|
+
const nextDist = dist + 1;
|
|
465
|
+
for (let m = 0; m < MOVE_COUNT; m++) {
|
|
466
|
+
const n7 = permTable[r7 * MOVE_COUNT + m];
|
|
467
|
+
const nO = orientTable[rO * MOVE_COUNT + m];
|
|
468
|
+
const nC = centersTable[rC * MOVE_COUNT + m];
|
|
469
|
+
const next = rankFromComponents(n7, nO, nC);
|
|
470
|
+
if (distances[next] === 255) {
|
|
471
|
+
distances[next] = nextDist;
|
|
472
|
+
policy[next] = m ^ 1; // inverse move of the discovery edge
|
|
473
|
+
if (nextDist > maxDepth)
|
|
474
|
+
maxDepth = nextDist;
|
|
475
|
+
queue[write++] = next;
|
|
476
|
+
}
|
|
477
|
+
}
|
|
478
|
+
}
|
|
479
|
+
if (write !== STATE_COUNT) {
|
|
480
|
+
throw new Error(`Policy BFS covered ${write} states, expected ${STATE_COUNT}.`);
|
|
481
|
+
}
|
|
482
|
+
const packed = new Uint8Array(POLICY_PACKED_ENTRIES);
|
|
483
|
+
for (let i = 0; i < STATE_COUNT; i++) {
|
|
484
|
+
const bits = i * 3;
|
|
485
|
+
const byteIndex = bits >> 3;
|
|
486
|
+
const offset = bits & 7;
|
|
487
|
+
const value = policy[i] & 0x07;
|
|
488
|
+
packed[byteIndex] |= (value << offset) & 0xff;
|
|
489
|
+
if (offset > 5) {
|
|
490
|
+
packed[byteIndex + 1] |= value >> (8 - offset);
|
|
491
|
+
}
|
|
492
|
+
}
|
|
493
|
+
return { packed, maxDepth };
|
|
494
|
+
}
|
|
495
|
+
finally {
|
|
496
|
+
EVEN_CENTER_RANK = saved.evenCenterRank;
|
|
497
|
+
ORIENT_CLASS = saved.orientClass;
|
|
498
|
+
R7_SETS = saved.r7Sets;
|
|
499
|
+
}
|
|
500
|
+
}
|
|
501
|
+
export function checksum(values) {
|
|
502
|
+
let hash = 0x811c9dc5;
|
|
503
|
+
for (let i = 0; i < values.length; i++) {
|
|
504
|
+
hash ^= values[i];
|
|
505
|
+
hash = Math.imul(hash, 0x01000193);
|
|
506
|
+
}
|
|
507
|
+
return hash >>> 0;
|
|
508
|
+
}
|
package/dist/random/prng.js
CHANGED
|
@@ -6,8 +6,17 @@ export function createRandomSource(seed) {
|
|
|
6
6
|
return new SeededRandomSource(hashSeed(seed));
|
|
7
7
|
}
|
|
8
8
|
class CryptoRandomSource {
|
|
9
|
+
buffer = null;
|
|
10
|
+
offset = 0;
|
|
9
11
|
next() {
|
|
10
|
-
|
|
12
|
+
// Batch the crypto calls: one randomBytes per move is ~2 orders of
|
|
13
|
+
// magnitude slower in Node (syscall per call). Refill lazily.
|
|
14
|
+
if (this.buffer === null || this.offset + 6 > 256) {
|
|
15
|
+
this.buffer = randomBytes(256);
|
|
16
|
+
this.offset = 0;
|
|
17
|
+
}
|
|
18
|
+
const value = this.buffer.readUIntBE(this.offset, 6);
|
|
19
|
+
this.offset += 6;
|
|
11
20
|
return value / 0x1000000000000;
|
|
12
21
|
}
|
|
13
22
|
nextInt(maxExclusive) {
|
package/dist-cjs/core/api.js
CHANGED
|
@@ -1,4 +1,37 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
2
35
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
36
|
exports.initializeScrambler = initializeScrambler;
|
|
4
37
|
exports.registerScrambleGenerator = registerScrambleGenerator;
|
|
@@ -8,8 +41,6 @@ exports.generateScramble = generateScramble;
|
|
|
8
41
|
exports.generateScrambles = generateScrambles;
|
|
9
42
|
const errors_js_1 = require("./errors.js");
|
|
10
43
|
const registry_js_1 = require("./registry.js");
|
|
11
|
-
const browser_loader_js_1 = require("../puzzles/cube2/solver/browser-loader.js");
|
|
12
|
-
const browser_loader_js_2 = require("../puzzles/cube3/solver/browser-loader.js");
|
|
13
44
|
/**
|
|
14
45
|
* Pre-load solver tables in browser environments.
|
|
15
46
|
* In Node.js this is a no-op (tables are read lazily from the filesystem).
|
|
@@ -26,16 +57,30 @@ async function initializeScrambler(baseUrl, eventId) {
|
|
|
26
57
|
// Node.js — tables are loaded on-demand from the filesystem
|
|
27
58
|
return;
|
|
28
59
|
}
|
|
60
|
+
// Lazy imports keep per-puzzle subpath bundles from pulling in the
|
|
61
|
+
// loaders of every other puzzle.
|
|
29
62
|
if (eventId === "222" || eventId === "222so") {
|
|
30
|
-
await (
|
|
63
|
+
const { loadBrowserTables } = await Promise.resolve().then(() => __importStar(require("../puzzles/cube2/solver/browser-loader.js")));
|
|
64
|
+
await loadBrowserTables(baseUrl);
|
|
31
65
|
}
|
|
32
66
|
else if (eventId === "333") {
|
|
33
|
-
await (
|
|
67
|
+
const { loadBrowserTables } = await Promise.resolve().then(() => __importStar(require("../puzzles/cube3/solver/browser-loader.js")));
|
|
68
|
+
await loadBrowserTables(baseUrl);
|
|
69
|
+
}
|
|
70
|
+
else if (eventId === "pymx") {
|
|
71
|
+
const { loadBrowserTables } = await Promise.resolve().then(() => __importStar(require("../puzzles/pyraminx/solver/browser-loader.js")));
|
|
72
|
+
await loadBrowserTables(baseUrl);
|
|
73
|
+
}
|
|
74
|
+
else if (eventId === "skwb") {
|
|
75
|
+
const { loadBrowserTables } = await Promise.resolve().then(() => __importStar(require("../puzzles/skewb/solver/browser-loader.js")));
|
|
76
|
+
await loadBrowserTables(baseUrl);
|
|
34
77
|
}
|
|
35
78
|
else if (!eventId) {
|
|
36
79
|
await Promise.all([
|
|
37
|
-
(
|
|
38
|
-
(
|
|
80
|
+
Promise.resolve().then(() => __importStar(require("../puzzles/cube2/solver/browser-loader.js"))).then((m) => m.loadBrowserTables(baseUrl)),
|
|
81
|
+
Promise.resolve().then(() => __importStar(require("../puzzles/cube3/solver/browser-loader.js"))).then((m) => m.loadBrowserTables(baseUrl)),
|
|
82
|
+
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))
|
|
39
84
|
]);
|
|
40
85
|
}
|
|
41
86
|
}
|
|
@@ -1,6 +1,15 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.generateClockScramble = exports.clockScrambleGenerator = void 0;
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
3
|
+
exports.initializeScrambler = exports.getSupportedEvents = exports.getEventInfo = exports.generateScrambles = exports.generateScramble = exports.generateClockScramble = exports.clockScrambleGenerator = void 0;
|
|
4
|
+
const index_js_1 = require("../../core/index.js");
|
|
5
|
+
const scrambler_js_1 = require("./scrambler.js");
|
|
6
|
+
(0, index_js_1.registerScrambleGenerator)(scrambler_js_1.clockScrambleGenerator);
|
|
7
|
+
var scrambler_js_2 = require("./scrambler.js");
|
|
8
|
+
Object.defineProperty(exports, "clockScrambleGenerator", { enumerable: true, get: function () { return scrambler_js_2.clockScrambleGenerator; } });
|
|
9
|
+
Object.defineProperty(exports, "generateClockScramble", { enumerable: true, get: function () { return scrambler_js_2.generateClockScramble; } });
|
|
10
|
+
var index_js_2 = require("../../core/index.js");
|
|
11
|
+
Object.defineProperty(exports, "generateScramble", { enumerable: true, get: function () { return index_js_2.generateScramble; } });
|
|
12
|
+
Object.defineProperty(exports, "generateScrambles", { enumerable: true, get: function () { return index_js_2.generateScrambles; } });
|
|
13
|
+
Object.defineProperty(exports, "getEventInfo", { enumerable: true, get: function () { return index_js_2.getEventInfo; } });
|
|
14
|
+
Object.defineProperty(exports, "getSupportedEvents", { enumerable: true, get: function () { return index_js_2.getSupportedEvents; } });
|
|
15
|
+
Object.defineProperty(exports, "initializeScrambler", { enumerable: true, get: function () { return index_js_2.initializeScrambler; } });
|
|
@@ -33,7 +33,10 @@ var __importStar = (this && this.__importStar) || (function () {
|
|
|
33
33
|
};
|
|
34
34
|
})();
|
|
35
35
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
-
exports.solver = exports.toCube2Facelets = exports.getCube2FaceOrder = exports.formatCube2Facelets = exports.generateCube2Scramble = exports.cube2ScrambleGenerator = exports.generateRandomCube2State = exports.validateCube2State = exports.permutationParity = exports.isOneMoveFromSolvedCube2State = exports.isAllowedRandomCube2State = exports.isSolvedCube2State = exports.cube2StatesEqual = exports.createSolvedCube2State = exports.cloneCube2State = exports.parseCube2Move = exports.parseCube2Algorithm = exports.invertCube2Move = exports.invertCube2Algorithm = exports.formatCube2Algorithm = exports.applyCube2Move = exports.applyCube2Algorithm = exports.CORNER_COUNT = exports.CUBE2_MOVES = void 0;
|
|
36
|
+
exports.initializeScrambler = exports.getSupportedEvents = exports.getEventInfo = exports.generateScrambles = exports.generateScramble = exports.solver = exports.toCube2Facelets = exports.getCube2FaceOrder = exports.formatCube2Facelets = exports.generateCube2Scramble = exports.cube2ScrambleGenerator = exports.generateRandomCube2State = exports.validateCube2State = exports.permutationParity = exports.isOneMoveFromSolvedCube2State = exports.isAllowedRandomCube2State = exports.isSolvedCube2State = exports.cube2StatesEqual = exports.createSolvedCube2State = exports.cloneCube2State = exports.parseCube2Move = exports.parseCube2Algorithm = exports.invertCube2Move = exports.invertCube2Algorithm = exports.formatCube2Algorithm = exports.applyCube2Move = exports.applyCube2Algorithm = exports.CORNER_COUNT = exports.CUBE2_MOVES = void 0;
|
|
37
|
+
const index_js_1 = require("../../core/index.js");
|
|
38
|
+
const scrambler_js_1 = require("./scrambler.js");
|
|
39
|
+
(0, index_js_1.registerScrambleGenerator)(scrambler_js_1.cube2ScrambleGenerator);
|
|
37
40
|
var types_js_1 = require("./types.js");
|
|
38
41
|
Object.defineProperty(exports, "CUBE2_MOVES", { enumerable: true, get: function () { return types_js_1.CUBE2_MOVES; } });
|
|
39
42
|
Object.defineProperty(exports, "CORNER_COUNT", { enumerable: true, get: function () { return types_js_1.CORNER_COUNT; } });
|
|
@@ -57,11 +60,17 @@ Object.defineProperty(exports, "permutationParity", { enumerable: true, get: fun
|
|
|
57
60
|
Object.defineProperty(exports, "validateCube2State", { enumerable: true, get: function () { return validation_js_1.validateCube2State; } });
|
|
58
61
|
var random_state_js_1 = require("./random-state.js");
|
|
59
62
|
Object.defineProperty(exports, "generateRandomCube2State", { enumerable: true, get: function () { return random_state_js_1.generateRandomCube2State; } });
|
|
60
|
-
var
|
|
61
|
-
Object.defineProperty(exports, "cube2ScrambleGenerator", { enumerable: true, get: function () { return
|
|
62
|
-
Object.defineProperty(exports, "generateCube2Scramble", { enumerable: true, get: function () { return
|
|
63
|
+
var scrambler_js_2 = require("./scrambler.js");
|
|
64
|
+
Object.defineProperty(exports, "cube2ScrambleGenerator", { enumerable: true, get: function () { return scrambler_js_2.cube2ScrambleGenerator; } });
|
|
65
|
+
Object.defineProperty(exports, "generateCube2Scramble", { enumerable: true, get: function () { return scrambler_js_2.generateCube2Scramble; } });
|
|
63
66
|
var facelets_js_1 = require("./facelets.js");
|
|
64
67
|
Object.defineProperty(exports, "formatCube2Facelets", { enumerable: true, get: function () { return facelets_js_1.formatCube2Facelets; } });
|
|
65
68
|
Object.defineProperty(exports, "getCube2FaceOrder", { enumerable: true, get: function () { return facelets_js_1.getCube2FaceOrder; } });
|
|
66
69
|
Object.defineProperty(exports, "toCube2Facelets", { enumerable: true, get: function () { return facelets_js_1.toCube2Facelets; } });
|
|
67
70
|
exports.solver = __importStar(require("./solver/index.js"));
|
|
71
|
+
var index_js_2 = require("../../core/index.js");
|
|
72
|
+
Object.defineProperty(exports, "generateScramble", { enumerable: true, get: function () { return index_js_2.generateScramble; } });
|
|
73
|
+
Object.defineProperty(exports, "generateScrambles", { enumerable: true, get: function () { return index_js_2.generateScrambles; } });
|
|
74
|
+
Object.defineProperty(exports, "getEventInfo", { enumerable: true, get: function () { return index_js_2.getEventInfo; } });
|
|
75
|
+
Object.defineProperty(exports, "getSupportedEvents", { enumerable: true, get: function () { return index_js_2.getSupportedEvents; } });
|
|
76
|
+
Object.defineProperty(exports, "initializeScrambler", { enumerable: true, get: function () { return index_js_2.initializeScrambler; } });
|