@cubingcenter/scrambler 0.3.0 → 0.4.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +46 -3
- package/dist/core/api.d.ts.map +1 -1
- package/dist/core/api.js +13 -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/clock/scrambler.js +2 -2
- 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/megaminx/scrambler.js +2 -2
- 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 +26 -22
- 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/index.d.ts +1 -0
- package/dist/puzzles/skewb/index.d.ts.map +1 -1
- package/dist/puzzles/skewb/index.js +4 -0
- package/dist/puzzles/skewb/scrambler.js +2 -2
- package/dist-cjs/core/api.js +46 -6
- package/dist-cjs/puzzles/clock/index.js +13 -4
- package/dist-cjs/puzzles/clock/scrambler.js +2 -2
- 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/megaminx/scrambler.js +2 -2
- package/dist-cjs/puzzles/pyraminx/index.js +50 -6
- package/dist-cjs/puzzles/pyraminx/scrambler.js +25 -21
- 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/index.js +13 -4
- package/dist-cjs/puzzles/skewb/scrambler.js +2 -2
- package/package.json +17 -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-cjs/puzzles/pyraminx/solver.js +0 -170
|
@@ -0,0 +1,300 @@
|
|
|
1
|
+
import { loadGeneratedPyraminxSolverTables } from "./generated-assets.js";
|
|
2
|
+
import { applyPyraminxMove } from "../moves.js";
|
|
3
|
+
// ---------------------------------------------------------------------------
|
|
4
|
+
// Coordinate encoding / decoding (kept from original solver.ts)
|
|
5
|
+
// ---------------------------------------------------------------------------
|
|
6
|
+
const FACT = [1, 1, 2, 6, 24, 120, 720];
|
|
7
|
+
export function getPermutationIndex(perm) {
|
|
8
|
+
let index = 0;
|
|
9
|
+
const n = perm.length;
|
|
10
|
+
for (let i = 0; i < n; i++) {
|
|
11
|
+
let count = 0;
|
|
12
|
+
for (let j = i + 1; j < n; j++) {
|
|
13
|
+
if (perm[j] < perm[i])
|
|
14
|
+
count++;
|
|
15
|
+
}
|
|
16
|
+
index += count * FACT[n - 1 - i];
|
|
17
|
+
}
|
|
18
|
+
return index;
|
|
19
|
+
}
|
|
20
|
+
export function getPermutationFromIndex(index, n) {
|
|
21
|
+
const perm = Array(n).fill(0);
|
|
22
|
+
const temp = Array.from({ length: n }, (_, i) => i);
|
|
23
|
+
let val = index;
|
|
24
|
+
for (let i = 0; i < n; i++) {
|
|
25
|
+
const f = FACT[n - 1 - i];
|
|
26
|
+
const choice = Math.floor(val / f);
|
|
27
|
+
val %= f;
|
|
28
|
+
perm[i] = temp[choice];
|
|
29
|
+
temp.splice(choice, 1);
|
|
30
|
+
}
|
|
31
|
+
return perm;
|
|
32
|
+
}
|
|
33
|
+
export function getOrientationIndex(orient) {
|
|
34
|
+
let index = 0;
|
|
35
|
+
for (let i = 0; i < 5; i++) {
|
|
36
|
+
index = (index << 1) | orient[i];
|
|
37
|
+
}
|
|
38
|
+
return index;
|
|
39
|
+
}
|
|
40
|
+
export function getOrientationFromIndex(index) {
|
|
41
|
+
const orient = Array(6).fill(0);
|
|
42
|
+
let temp = index;
|
|
43
|
+
let sum = 0;
|
|
44
|
+
for (let i = 4; i >= 0; i--) {
|
|
45
|
+
const bit = temp & 1;
|
|
46
|
+
orient[i] = bit;
|
|
47
|
+
sum += bit;
|
|
48
|
+
temp >>= 1;
|
|
49
|
+
}
|
|
50
|
+
orient[5] = sum % 2 === 0 ? 0 : 1;
|
|
51
|
+
return orient;
|
|
52
|
+
}
|
|
53
|
+
export function getCentersIndex(centers) {
|
|
54
|
+
return centers[0] + 3 * centers[1] + 9 * centers[2] + 27 * centers[3];
|
|
55
|
+
}
|
|
56
|
+
export function getCentersFromIndex(index) {
|
|
57
|
+
let temp = index;
|
|
58
|
+
const centers = Array(4).fill(0);
|
|
59
|
+
for (let i = 0; i < 4; i++) {
|
|
60
|
+
centers[i] = temp % 3;
|
|
61
|
+
temp = Math.floor(temp / 3);
|
|
62
|
+
}
|
|
63
|
+
return centers;
|
|
64
|
+
}
|
|
65
|
+
export function permutationParity(perm) {
|
|
66
|
+
let inv = 0;
|
|
67
|
+
for (let i = 0; i < perm.length; i++)
|
|
68
|
+
for (let j = i + 1; j < perm.length; j++)
|
|
69
|
+
if (perm[i] > perm[j])
|
|
70
|
+
inv++;
|
|
71
|
+
return inv % 2;
|
|
72
|
+
}
|
|
73
|
+
// Compact mapping: only even permutations (360) are reachable
|
|
74
|
+
export const PERMUTATION_FULL_COUNT = 720;
|
|
75
|
+
export const PERMUTATION_COUNT = 360;
|
|
76
|
+
export const PERM_720_TO_360 = new Int16Array(PERMUTATION_FULL_COUNT).fill(-1);
|
|
77
|
+
export const PERM_360_TO_720 = new Uint16Array(PERMUTATION_COUNT);
|
|
78
|
+
(function initPermMapping() {
|
|
79
|
+
let compact = 0;
|
|
80
|
+
for (let full = 0; full < PERMUTATION_FULL_COUNT; full++) {
|
|
81
|
+
const perm = getPermutationFromIndex(full, 6);
|
|
82
|
+
if (permutationParity(perm) === 0) {
|
|
83
|
+
PERM_720_TO_360[full] = compact;
|
|
84
|
+
PERM_360_TO_720[compact] = full;
|
|
85
|
+
compact++;
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
})();
|
|
89
|
+
export function getPermutationCompactIndex(perm) {
|
|
90
|
+
const full = getPermutationIndex(perm);
|
|
91
|
+
const compact = PERM_720_TO_360[full];
|
|
92
|
+
if (compact === -1)
|
|
93
|
+
throw new Error("Unreachable pyraminx permutation (odd parity)");
|
|
94
|
+
return compact;
|
|
95
|
+
}
|
|
96
|
+
export function getPermutationCompactFromFull(full) {
|
|
97
|
+
const c = PERM_720_TO_360[full];
|
|
98
|
+
if (c === -1)
|
|
99
|
+
throw new Error(`Full perm index ${full} is odd parity`);
|
|
100
|
+
return c;
|
|
101
|
+
}
|
|
102
|
+
export function getPermutationFullFromCompact(compact) {
|
|
103
|
+
return PERM_360_TO_720[compact];
|
|
104
|
+
}
|
|
105
|
+
export function getStateIndex(state) {
|
|
106
|
+
const c = getCentersIndex(state.centers);
|
|
107
|
+
const p = getPermutationCompactIndex(state.edgesPerm);
|
|
108
|
+
const o = getOrientationIndex(state.edgesOrient);
|
|
109
|
+
return c + 81 * (p + PERMUTATION_COUNT * o);
|
|
110
|
+
}
|
|
111
|
+
export function getPyraminxStateFromIndex(index) {
|
|
112
|
+
let val = index;
|
|
113
|
+
const centersIdx = val % 81;
|
|
114
|
+
val = Math.floor(val / 81);
|
|
115
|
+
const permCompact = val % PERMUTATION_COUNT;
|
|
116
|
+
const orientIdx = Math.floor(val / PERMUTATION_COUNT);
|
|
117
|
+
const permFull = getPermutationFullFromCompact(permCompact);
|
|
118
|
+
return {
|
|
119
|
+
centers: getCentersFromIndex(centersIdx),
|
|
120
|
+
edgesPerm: getPermutationFromIndex(permFull, 6),
|
|
121
|
+
edgesOrient: getOrientationFromIndex(orientIdx),
|
|
122
|
+
tips: [0, 0, 0, 0]
|
|
123
|
+
};
|
|
124
|
+
}
|
|
125
|
+
// ---------------------------------------------------------------------------
|
|
126
|
+
// Table constants
|
|
127
|
+
// ---------------------------------------------------------------------------
|
|
128
|
+
export const CENTERS_COUNT = 81;
|
|
129
|
+
export const ORIENTATION_COUNT = 32;
|
|
130
|
+
export const MOVE_COUNT = 8;
|
|
131
|
+
export const STATE_COUNT = 81 * PERMUTATION_COUNT * ORIENTATION_COUNT; // 933_120
|
|
132
|
+
export const POLICY_PACKED_ENTRIES = Math.ceil((STATE_COUNT * 3) / 8); // 349_920
|
|
133
|
+
// 3-bit little-endian unpacking of the packed policy table.
|
|
134
|
+
export function getPolicyMoveFromPacked(packed, stateIndex) {
|
|
135
|
+
const bits = stateIndex * 3;
|
|
136
|
+
const byteIndex = bits >> 3;
|
|
137
|
+
const offset = bits & 7;
|
|
138
|
+
const word = (packed[byteIndex] | ((packed[byteIndex + 1] ?? 0) << 8)) >> offset;
|
|
139
|
+
return word & 0x07;
|
|
140
|
+
}
|
|
141
|
+
export const PYRAMINX_MOVES = [
|
|
142
|
+
"U", "U'", "L", "L'", "R", "R'", "B", "B'"
|
|
143
|
+
];
|
|
144
|
+
// ---------------------------------------------------------------------------
|
|
145
|
+
// Table generation (used by generate script)
|
|
146
|
+
// ---------------------------------------------------------------------------
|
|
147
|
+
export function generateCentersTable() {
|
|
148
|
+
const table = new Uint8Array(CENTERS_COUNT * MOVE_COUNT);
|
|
149
|
+
for (let c = 0; c < CENTERS_COUNT; c++) {
|
|
150
|
+
const centers = getCentersFromIndex(c);
|
|
151
|
+
for (let m = 0; m < MOVE_COUNT; m++) {
|
|
152
|
+
const state = {
|
|
153
|
+
centers: [...centers],
|
|
154
|
+
edgesPerm: [0, 1, 2, 3, 4, 5],
|
|
155
|
+
edgesOrient: [0, 0, 0, 0, 0, 0],
|
|
156
|
+
tips: [0, 0, 0, 0]
|
|
157
|
+
};
|
|
158
|
+
const next = applyPyraminxMove(state, PYRAMINX_MOVES[m]);
|
|
159
|
+
table[c * MOVE_COUNT + m] = getCentersIndex(next.centers);
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
return table;
|
|
163
|
+
}
|
|
164
|
+
export function generatePermutationTable() {
|
|
165
|
+
const table = new Uint16Array(PERMUTATION_COUNT * MOVE_COUNT);
|
|
166
|
+
for (let pCompact = 0; pCompact < PERMUTATION_COUNT; pCompact++) {
|
|
167
|
+
const full = getPermutationFullFromCompact(pCompact);
|
|
168
|
+
const perm = getPermutationFromIndex(full, 6);
|
|
169
|
+
for (let m = 0; m < MOVE_COUNT; m++) {
|
|
170
|
+
const state = {
|
|
171
|
+
centers: [0, 0, 0, 0],
|
|
172
|
+
edgesPerm: [...perm],
|
|
173
|
+
edgesOrient: [0, 0, 0, 0, 0, 0],
|
|
174
|
+
tips: [0, 0, 0, 0]
|
|
175
|
+
};
|
|
176
|
+
const next = applyPyraminxMove(state, PYRAMINX_MOVES[m]);
|
|
177
|
+
const nextFull = getPermutationIndex(next.edgesPerm);
|
|
178
|
+
table[pCompact * MOVE_COUNT + m] = getPermutationCompactFromFull(nextFull);
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
return table;
|
|
182
|
+
}
|
|
183
|
+
export function generateOrientationTable() {
|
|
184
|
+
const table = new Uint8Array(ORIENTATION_COUNT * MOVE_COUNT);
|
|
185
|
+
for (let o = 0; o < ORIENTATION_COUNT; o++) {
|
|
186
|
+
const orient = getOrientationFromIndex(o);
|
|
187
|
+
for (let m = 0; m < MOVE_COUNT; m++) {
|
|
188
|
+
const state = {
|
|
189
|
+
centers: [0, 0, 0, 0],
|
|
190
|
+
edgesPerm: [0, 1, 2, 3, 4, 5],
|
|
191
|
+
edgesOrient: [...orient],
|
|
192
|
+
tips: [0, 0, 0, 0]
|
|
193
|
+
};
|
|
194
|
+
const next = applyPyraminxMove(state, PYRAMINX_MOVES[m]);
|
|
195
|
+
table[o * MOVE_COUNT + m] = getOrientationIndex(next.edgesOrient);
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
return table;
|
|
199
|
+
}
|
|
200
|
+
// BFS from solved stores, for each state, the inverse of the move that first
|
|
201
|
+
// discovered it: an optimal move toward solved. Packed 3 bits per state
|
|
202
|
+
// (8 moves; the solved entry is never read, the solve loop exits first).
|
|
203
|
+
export function generatePolicyTable(centersTable, permTable, orientTable) {
|
|
204
|
+
const distances = new Uint8Array(STATE_COUNT).fill(255);
|
|
205
|
+
const policy = new Uint8Array(STATE_COUNT);
|
|
206
|
+
const solvedIdx = 0; // c=0,p=0,o=0 => 0
|
|
207
|
+
distances[solvedIdx] = 0;
|
|
208
|
+
const queue = new Uint32Array(STATE_COUNT);
|
|
209
|
+
let read = 0;
|
|
210
|
+
let write = 1;
|
|
211
|
+
queue[0] = solvedIdx;
|
|
212
|
+
let maxDepth = 0;
|
|
213
|
+
while (read < write) {
|
|
214
|
+
const curr = queue[read++];
|
|
215
|
+
const dist = distances[curr];
|
|
216
|
+
const c = curr % 81;
|
|
217
|
+
const rem = Math.floor(curr / 81);
|
|
218
|
+
const p = rem % PERMUTATION_COUNT;
|
|
219
|
+
const o = Math.floor(rem / PERMUTATION_COUNT);
|
|
220
|
+
const nextDist = dist + 1;
|
|
221
|
+
for (let m = 0; m < MOVE_COUNT; m++) {
|
|
222
|
+
const nc = centersTable[c * MOVE_COUNT + m];
|
|
223
|
+
const np = permTable[p * MOVE_COUNT + m];
|
|
224
|
+
const no = orientTable[o * MOVE_COUNT + m];
|
|
225
|
+
const next = nc + 81 * (np + PERMUTATION_COUNT * no);
|
|
226
|
+
if (distances[next] === 255) {
|
|
227
|
+
distances[next] = nextDist;
|
|
228
|
+
policy[next] = m ^ 1; // inverse move of the discovery edge
|
|
229
|
+
if (nextDist > maxDepth)
|
|
230
|
+
maxDepth = nextDist;
|
|
231
|
+
queue[write++] = next;
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
const packed = new Uint8Array(POLICY_PACKED_ENTRIES);
|
|
236
|
+
for (let i = 0; i < STATE_COUNT; i++) {
|
|
237
|
+
const bits = i * 3;
|
|
238
|
+
const byteIndex = bits >> 3;
|
|
239
|
+
const offset = bits & 7;
|
|
240
|
+
const value = policy[i] & 0x07;
|
|
241
|
+
packed[byteIndex] |= (value << offset) & 0xff;
|
|
242
|
+
if (offset > 5) {
|
|
243
|
+
packed[byteIndex + 1] |= value >> (8 - offset);
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
return { packed, maxDepth };
|
|
247
|
+
}
|
|
248
|
+
export function checksum(values) {
|
|
249
|
+
let hash = 0x811c9dc5;
|
|
250
|
+
for (let i = 0; i < values.length; i++) {
|
|
251
|
+
hash ^= values[i];
|
|
252
|
+
hash = Math.imul(hash, 0x01000193);
|
|
253
|
+
}
|
|
254
|
+
return hash >>> 0;
|
|
255
|
+
}
|
|
256
|
+
// ---------------------------------------------------------------------------
|
|
257
|
+
// Runtime table loading (mirrors cube2/cube3)
|
|
258
|
+
// ---------------------------------------------------------------------------
|
|
259
|
+
let tablesLoaded = false;
|
|
260
|
+
export let CENTERS_TABLE = null;
|
|
261
|
+
export let PERMUTATION_TABLE = null;
|
|
262
|
+
export let ORIENTATION_TABLE = null;
|
|
263
|
+
export let POLICY_TABLE = null;
|
|
264
|
+
export async function ensureTablesLoaded() {
|
|
265
|
+
if (tablesLoaded)
|
|
266
|
+
return;
|
|
267
|
+
const tables = await loadGeneratedPyraminxSolverTables();
|
|
268
|
+
CENTERS_TABLE = tables.centersTable;
|
|
269
|
+
PERMUTATION_TABLE = tables.permutationTable;
|
|
270
|
+
ORIENTATION_TABLE = tables.orientationTable;
|
|
271
|
+
POLICY_TABLE = tables.policyTable;
|
|
272
|
+
tablesLoaded = true;
|
|
273
|
+
}
|
|
274
|
+
export function getPolicyMove(stateIndex) {
|
|
275
|
+
if (!POLICY_TABLE)
|
|
276
|
+
throw new Error("Pyraminx solver tables not loaded. Call ensureTablesLoaded() first.");
|
|
277
|
+
return getPolicyMoveFromPacked(POLICY_TABLE, stateIndex);
|
|
278
|
+
}
|
|
279
|
+
export function getCentersTransition(centerIdx, move) {
|
|
280
|
+
if (!CENTERS_TABLE)
|
|
281
|
+
throw new Error("Pyraminx solver tables not loaded.");
|
|
282
|
+
return CENTERS_TABLE[centerIdx * MOVE_COUNT + move];
|
|
283
|
+
}
|
|
284
|
+
export function getPermutationTransition(permIdx, move) {
|
|
285
|
+
if (!PERMUTATION_TABLE)
|
|
286
|
+
throw new Error("Pyraminx solver tables not loaded.");
|
|
287
|
+
return PERMUTATION_TABLE[permIdx * MOVE_COUNT + move];
|
|
288
|
+
}
|
|
289
|
+
export function getOrientationTransition(orientIdx, move) {
|
|
290
|
+
if (!ORIENTATION_TABLE)
|
|
291
|
+
throw new Error("Pyraminx solver tables not loaded.");
|
|
292
|
+
return ORIENTATION_TABLE[orientIdx * MOVE_COUNT + move];
|
|
293
|
+
}
|
|
294
|
+
export function resetTablesForTests() {
|
|
295
|
+
tablesLoaded = false;
|
|
296
|
+
CENTERS_TABLE = null;
|
|
297
|
+
PERMUTATION_TABLE = null;
|
|
298
|
+
ORIENTATION_TABLE = null;
|
|
299
|
+
POLICY_TABLE = null;
|
|
300
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export interface FetchTableBufferOptions {
|
|
2
|
+
/** Cache API cache name to store responses in (used by cube3). */
|
|
3
|
+
cacheName?: string;
|
|
4
|
+
/**
|
|
5
|
+
* Whether the manifest advertises precompressed variants for this file.
|
|
6
|
+
* Defaults to true (old manifests without the flag keep the old behavior);
|
|
7
|
+
* set to false to skip .br/.gz attempts entirely.
|
|
8
|
+
*/
|
|
9
|
+
compressed?: boolean;
|
|
10
|
+
}
|
|
11
|
+
export declare function fetchTableBuffer(baseUrl: string, dir: string, file: string, options?: FetchTableBufferOptions): Promise<ArrayBuffer>;
|
|
12
|
+
//# sourceMappingURL=compressed-fetch.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"compressed-fetch.d.ts","sourceRoot":"","sources":["../../../src/puzzles/shared/compressed-fetch.ts"],"names":[],"mappings":"AAOA,MAAM,WAAW,uBAAuB;IACtC,kEAAkE;IAClE,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB;;;;OAIG;IACH,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB;AAkBD,wBAAsB,gBAAgB,CACpC,OAAO,EAAE,MAAM,EACf,GAAG,EAAE,MAAM,EACX,IAAI,EAAE,MAAM,EACZ,OAAO,GAAE,uBAA4B,GACpC,OAAO,CAAC,WAAW,CAAC,CAuBtB"}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
// Shared browser-only helper to fetch solver tables, preferring the
|
|
2
|
+
// precompressed .br/.gz variants (decompressed with DecompressionStream)
|
|
3
|
+
// and falling back to the raw .bin file.
|
|
4
|
+
//
|
|
5
|
+
// Node never uses this module: node-loader.ts reads the .bin files directly
|
|
6
|
+
// from the filesystem.
|
|
7
|
+
// DecompressionStream only guarantees "gzip"/"deflate"; "br" support varies,
|
|
8
|
+
// so probe once and never attempt formats the runtime cannot decompress.
|
|
9
|
+
const SUPPORTED_FORMATS = (() => {
|
|
10
|
+
if (typeof DecompressionStream === "undefined")
|
|
11
|
+
return [];
|
|
12
|
+
const supported = [];
|
|
13
|
+
for (const [suffix, format] of [["br", "br"], ["gz", "gzip"]]) {
|
|
14
|
+
try {
|
|
15
|
+
new DecompressionStream(format);
|
|
16
|
+
supported.push([suffix, format]);
|
|
17
|
+
}
|
|
18
|
+
catch {
|
|
19
|
+
// format not supported by this runtime
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
return supported;
|
|
23
|
+
})();
|
|
24
|
+
export async function fetchTableBuffer(baseUrl, dir, file, options = {}) {
|
|
25
|
+
const urlFor = (name) => `${baseUrl}/${dir}/${name}`;
|
|
26
|
+
const cachedFetch = options.cacheName === undefined ? undefined : makeCachedFetch(options.cacheName);
|
|
27
|
+
if (options.compressed !== false && SUPPORTED_FORMATS.length > 0) {
|
|
28
|
+
for (const [suffix, format] of SUPPORTED_FORMATS) {
|
|
29
|
+
try {
|
|
30
|
+
const response = await (cachedFetch ? cachedFetch(urlFor(`${file}.${suffix}`)) : fetch(urlFor(`${file}.${suffix}`)));
|
|
31
|
+
if (response.ok && response.body) {
|
|
32
|
+
const stream = response.body.pipeThrough(new DecompressionStream(format));
|
|
33
|
+
return await new Response(stream).arrayBuffer();
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
catch {
|
|
37
|
+
// try the next candidate
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
const response = await (cachedFetch ? cachedFetch(urlFor(file)) : fetch(urlFor(file)));
|
|
42
|
+
if (!response.ok) {
|
|
43
|
+
throw new Error(`Failed to load ${file}: ${response.status} ${response.statusText}`);
|
|
44
|
+
}
|
|
45
|
+
return response.arrayBuffer();
|
|
46
|
+
}
|
|
47
|
+
function makeCachedFetch(cacheName) {
|
|
48
|
+
return async (url) => {
|
|
49
|
+
if (typeof caches === "undefined") {
|
|
50
|
+
return fetch(url);
|
|
51
|
+
}
|
|
52
|
+
try {
|
|
53
|
+
const cache = await caches.open(cacheName);
|
|
54
|
+
const cached = await cache.match(url);
|
|
55
|
+
if (cached) {
|
|
56
|
+
return cached;
|
|
57
|
+
}
|
|
58
|
+
const response = await fetch(url);
|
|
59
|
+
if (response.ok) {
|
|
60
|
+
await cache.put(url, response.clone());
|
|
61
|
+
}
|
|
62
|
+
return response;
|
|
63
|
+
}
|
|
64
|
+
catch {
|
|
65
|
+
return fetch(url);
|
|
66
|
+
}
|
|
67
|
+
};
|
|
68
|
+
}
|
|
@@ -7,4 +7,5 @@ export { generateRandomSkewbState } from "./random-state.js";
|
|
|
7
7
|
export { createSolvedSkewbFacelets, formatSkewbFacelets, getSkewbFaceOrder, toSkewbFacelets } from "./facelets.js";
|
|
8
8
|
export { solveSkewb, getStateIndex, getStateFromIndex } from "./solver.js";
|
|
9
9
|
export { generateSkewbScramble, skewbScrambleGenerator } from "./scrambler.js";
|
|
10
|
+
export { generateScramble, generateScrambles, getEventInfo, getSupportedEvents, initializeScrambler } from "../../core/index.js";
|
|
10
11
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/puzzles/skewb/index.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/puzzles/skewb/index.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AACtD,YAAY,EAAE,SAAS,EAAE,UAAU,EAAE,aAAa,EAAE,uBAAuB,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAC/G,OAAO,EACL,mBAAmB,EACnB,cAAc,EACd,oBAAoB,EACpB,oBAAoB,EACpB,eAAe,EACf,mBAAmB,EACnB,cAAc,GACf,MAAM,YAAY,CAAC;AACpB,OAAO,EACL,eAAe,EACf,sBAAsB,EACtB,kBAAkB,EAClB,gBAAgB,GACjB,MAAM,YAAY,CAAC;AACpB,OAAO,EAAE,iBAAiB,EAAE,kBAAkB,EAAE,yBAAyB,EAAE,6BAA6B,EAAE,MAAM,iBAAiB,CAAC;AAClI,OAAO,EAAE,wBAAwB,EAAE,MAAM,mBAAmB,CAAC;AAC7D,OAAO,EAAE,yBAAyB,EAAE,mBAAmB,EAAE,iBAAiB,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AACnH,OAAO,EAAE,UAAU,EAAE,aAAa,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAC3E,OAAO,EAAE,qBAAqB,EAAE,sBAAsB,EAAE,MAAM,gBAAgB,CAAC;AAE/E,OAAO,EACL,gBAAgB,EAChB,iBAAiB,EACjB,YAAY,EACZ,kBAAkB,EAClB,mBAAmB,EACpB,MAAM,qBAAqB,CAAC"}
|
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
import { registerScrambleGenerator } from "../../core/index.js";
|
|
2
|
+
import { skewbScrambleGenerator } from "./scrambler.js";
|
|
3
|
+
registerScrambleGenerator(skewbScrambleGenerator);
|
|
1
4
|
export { SKEWB_MOVES, SKEWB_FACES } from "./types.js";
|
|
2
5
|
export { applySkewbAlgorithm, applySkewbMove, formatSkewbAlgorithm, invertSkewbAlgorithm, invertSkewbMove, parseSkewbAlgorithm, parseSkewbMove, } from "./moves.js";
|
|
3
6
|
export { cloneSkewbState, createSolvedSkewbState, isSolvedSkewbState, skewbStatesEqual, } from "./state.js";
|
|
@@ -6,3 +9,4 @@ export { generateRandomSkewbState } from "./random-state.js";
|
|
|
6
9
|
export { createSolvedSkewbFacelets, formatSkewbFacelets, getSkewbFaceOrder, toSkewbFacelets } from "./facelets.js";
|
|
7
10
|
export { solveSkewb, getStateIndex, getStateFromIndex } from "./solver.js";
|
|
8
11
|
export { generateSkewbScramble, skewbScrambleGenerator } from "./scrambler.js";
|
|
12
|
+
export { generateScramble, generateScrambles, getEventInfo, getSupportedEvents, initializeScrambler } from "../../core/index.js";
|
|
@@ -5,7 +5,7 @@ import { solveSkewb } from "./solver.js";
|
|
|
5
5
|
import { formatSkewbFacelets, toSkewbFacelets } from "./facelets.js";
|
|
6
6
|
export const skewbScrambleGenerator = {
|
|
7
7
|
info: {
|
|
8
|
-
eventId: "
|
|
8
|
+
eventId: "skwb",
|
|
9
9
|
name: "Skewb",
|
|
10
10
|
puzzle: "skewb",
|
|
11
11
|
quality: "random-state",
|
|
@@ -33,7 +33,7 @@ export async function generateSkewbScramble(options = {}) {
|
|
|
33
33
|
}
|
|
34
34
|
const facelets = toSkewbFacelets(state);
|
|
35
35
|
const result = {
|
|
36
|
-
eventId: "
|
|
36
|
+
eventId: "skwb",
|
|
37
37
|
scramble: formatSkewbAlgorithm(scrambleMoves),
|
|
38
38
|
moves: scrambleMoves,
|
|
39
39
|
quality: "random-state",
|
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,25 @@ 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);
|
|
34
73
|
}
|
|
35
74
|
else if (!eventId) {
|
|
36
75
|
await Promise.all([
|
|
37
|
-
(
|
|
38
|
-
(
|
|
76
|
+
Promise.resolve().then(() => __importStar(require("../puzzles/cube2/solver/browser-loader.js"))).then((m) => m.loadBrowserTables(baseUrl)),
|
|
77
|
+
Promise.resolve().then(() => __importStar(require("../puzzles/cube3/solver/browser-loader.js"))).then((m) => m.loadBrowserTables(baseUrl)),
|
|
78
|
+
Promise.resolve().then(() => __importStar(require("../puzzles/pyraminx/solver/browser-loader.js"))).then((m) => m.loadBrowserTables(baseUrl))
|
|
39
79
|
]);
|
|
40
80
|
}
|
|
41
81
|
}
|
|
@@ -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; } });
|
|
@@ -4,7 +4,7 @@ exports.clockScrambleGenerator = void 0;
|
|
|
4
4
|
exports.generateClockScramble = generateClockScramble;
|
|
5
5
|
exports.clockScrambleGenerator = {
|
|
6
6
|
info: {
|
|
7
|
-
eventId: "
|
|
7
|
+
eventId: "clck",
|
|
8
8
|
name: "Clock",
|
|
9
9
|
puzzle: "clock",
|
|
10
10
|
quality: "random-state",
|
|
@@ -42,7 +42,7 @@ async function generateClockScramble(options = {}) {
|
|
|
42
42
|
const finalPinsStr = finalPins.join(" ");
|
|
43
43
|
const scramble = [...moves, finalPinsStr].filter(Boolean).join(" ");
|
|
44
44
|
return {
|
|
45
|
-
eventId: "
|
|
45
|
+
eventId: "clck",
|
|
46
46
|
scramble,
|
|
47
47
|
moves, // For moves we return the steps without final pins as parsed moves, or just string array
|
|
48
48
|
quality: "random-state",
|
|
@@ -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; } });
|
|
@@ -4,7 +4,6 @@ exports.cube2ScrambleGenerator = void 0;
|
|
|
4
4
|
exports.generateCube2Scramble = generateCube2Scramble;
|
|
5
5
|
const moves_js_1 = require("./moves.js");
|
|
6
6
|
const random_state_js_1 = require("./random-state.js");
|
|
7
|
-
const state_js_1 = require("./state.js");
|
|
8
7
|
const facelets_js_1 = require("./facelets.js");
|
|
9
8
|
const index_js_1 = require("./solver/index.js");
|
|
10
9
|
exports.cube2ScrambleGenerator = {
|
|
@@ -25,11 +24,10 @@ async function generateCube2Scramble(options = {}) {
|
|
|
25
24
|
const solution = await (0, index_js_1.solveCube2State)(state);
|
|
26
25
|
const scrambleMoves = (0, moves_js_1.invertCube2Algorithm)(solution.moves);
|
|
27
26
|
if (!options.skipValidation) {
|
|
28
|
-
|
|
29
|
-
if (!(0, state_js_1.cube2StatesEqual)(scrambledState, state)) {
|
|
27
|
+
if (!(0, index_js_1.verifyCube2Scramble)(state, scrambleMoves)) {
|
|
30
28
|
throw new Error("Generated 2x2 scramble does not reproduce the target random state.");
|
|
31
29
|
}
|
|
32
|
-
if (!(0,
|
|
30
|
+
if (!(0, index_js_1.verifyCube2Solution)(state, solution.moves)) {
|
|
33
31
|
throw new Error("Generated 2x2 solution does not solve the target random state.");
|
|
34
32
|
}
|
|
35
33
|
if (scrambleMoves.length < 2) {
|
|
@@ -4,6 +4,8 @@ exports.getCachedBrowserTables = getCachedBrowserTables;
|
|
|
4
4
|
exports.clearCachedBrowserTables = clearCachedBrowserTables;
|
|
5
5
|
exports.loadBrowserTables = loadBrowserTables;
|
|
6
6
|
const table_metadata_js_1 = require("./table-metadata.js");
|
|
7
|
+
const compressed_fetch_js_1 = require("../../shared/compressed-fetch.js");
|
|
8
|
+
const TABLES_DIR = "puzzles/cube2/solver/generated";
|
|
7
9
|
let cachedBrowserTables;
|
|
8
10
|
function getCachedBrowserTables() {
|
|
9
11
|
return cachedBrowserTables;
|
|
@@ -55,12 +57,7 @@ async function fetchManifest(baseUrl) {
|
|
|
55
57
|
return manifest;
|
|
56
58
|
}
|
|
57
59
|
async function fetchUint16Table(baseUrl, entry, expectedEntries) {
|
|
58
|
-
const
|
|
59
|
-
const response = await fetch(url);
|
|
60
|
-
if (!response.ok) {
|
|
61
|
-
throw new Error(`Failed to load ${entry.file}: ${response.status} ${response.statusText}`);
|
|
62
|
-
}
|
|
63
|
-
const buffer = await response.arrayBuffer();
|
|
60
|
+
const buffer = await (0, compressed_fetch_js_1.fetchTableBuffer)(baseUrl, TABLES_DIR, entry.file, { compressed: entry.compressed !== false });
|
|
64
61
|
if (buffer.byteLength !== expectedEntries * 2) {
|
|
65
62
|
throw new Error(`Invalid byte size for ${entry.file}`);
|
|
66
63
|
}
|
|
@@ -72,12 +69,7 @@ async function fetchUint16Table(baseUrl, entry, expectedEntries) {
|
|
|
72
69
|
return values;
|
|
73
70
|
}
|
|
74
71
|
async function fetchUint8Table(baseUrl, entry, expectedEntries) {
|
|
75
|
-
const
|
|
76
|
-
const response = await fetch(url);
|
|
77
|
-
if (!response.ok) {
|
|
78
|
-
throw new Error(`Failed to load ${entry.file}: ${response.status} ${response.statusText}`);
|
|
79
|
-
}
|
|
80
|
-
const buffer = await response.arrayBuffer();
|
|
72
|
+
const buffer = await (0, compressed_fetch_js_1.fetchTableBuffer)(baseUrl, TABLES_DIR, entry.file, { compressed: entry.compressed !== false });
|
|
81
73
|
if (buffer.byteLength !== expectedEntries) {
|
|
82
74
|
throw new Error(`Invalid byte size for ${entry.file}`);
|
|
83
75
|
}
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.solveCube2State = void 0;
|
|
3
|
+
exports.verifyCube2Solution = exports.verifyCube2Scramble = exports.solveCube2State = void 0;
|
|
4
4
|
var search_js_1 = require("./search.js");
|
|
5
5
|
Object.defineProperty(exports, "solveCube2State", { enumerable: true, get: function () { return search_js_1.solveCube2State; } });
|
|
6
|
+
Object.defineProperty(exports, "verifyCube2Scramble", { enumerable: true, get: function () { return search_js_1.verifyCube2Scramble; } });
|
|
7
|
+
Object.defineProperty(exports, "verifyCube2Solution", { enumerable: true, get: function () { return search_js_1.verifyCube2Solution; } });
|