cube-state-engine 1.3.0 → 1.5.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/.claude/settings.local.json +9 -0
- package/.idea/AICommit.xml +6 -0
- package/.idea/awsToolkit.xml +11 -0
- package/.idea/cube-state-engine.iml +1 -5
- package/.idea/inspectionProfiles/Project_Default.xml +6 -0
- package/dist/index.d.mts +1217 -672
- package/dist/index.d.ts +1217 -672
- package/dist/index.js +862 -496
- package/dist/index.mjs +855 -495
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
var __defProp = Object.defineProperty;
|
|
3
|
+
var __defProps = Object.defineProperties;
|
|
3
4
|
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
+
var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
|
|
4
6
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
7
|
var __getOwnPropSymbols = Object.getOwnPropertySymbols;
|
|
6
8
|
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
@@ -20,6 +22,7 @@ var __spreadValues = (a, b) => {
|
|
|
20
22
|
}
|
|
21
23
|
return a;
|
|
22
24
|
};
|
|
25
|
+
var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
|
|
23
26
|
var __export = (target, all) => {
|
|
24
27
|
for (var name in all)
|
|
25
28
|
__defProp(target, name, { get: all[name], enumerable: true });
|
|
@@ -35,60 +38,755 @@ var __copyProps = (to, from, except, desc) => {
|
|
|
35
38
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
36
39
|
var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
37
40
|
var __accessCheck = (obj, member, msg) => member.has(obj) || __typeError("Cannot " + msg);
|
|
41
|
+
var __privateGet = (obj, member, getter) => (__accessCheck(obj, member, "read from private field"), getter ? getter.call(obj) : member.get(obj));
|
|
38
42
|
var __privateAdd = (obj, member, value) => member.has(obj) ? __typeError("Cannot add the same private member more than once") : member instanceof WeakSet ? member.add(obj) : member.set(obj, value);
|
|
43
|
+
var __privateSet = (obj, member, value, setter) => (__accessCheck(obj, member, "write to private field"), setter ? setter.call(obj, value) : member.set(obj, value), value);
|
|
39
44
|
var __privateMethod = (obj, member, method) => (__accessCheck(obj, member, "access private method"), method);
|
|
40
45
|
|
|
41
46
|
// src/index.js
|
|
42
47
|
var src_exports = {};
|
|
43
48
|
__export(src_exports, {
|
|
44
49
|
COLOR: () => COLOR,
|
|
45
|
-
CubeEngine: () => CubeEngine
|
|
50
|
+
CubeEngine: () => CubeEngine,
|
|
51
|
+
analyzeSolution: () => analyzeSolution,
|
|
52
|
+
getMovePermutations: () => getMovePermutations,
|
|
53
|
+
invertSequence: () => invertSequence,
|
|
54
|
+
simplifyMoves: () => simplifyMoves
|
|
46
55
|
});
|
|
47
56
|
module.exports = __toCommonJS(src_exports);
|
|
48
|
-
|
|
57
|
+
|
|
58
|
+
// src/simplify.js
|
|
59
|
+
function canMerge(a, b) {
|
|
60
|
+
return typeof a === "string" && a === b && !a.includes("2");
|
|
61
|
+
}
|
|
62
|
+
function doubled(tok) {
|
|
63
|
+
return tok.replace("'", "") + "2";
|
|
64
|
+
}
|
|
65
|
+
function simplifyTokens(tokens) {
|
|
66
|
+
const out = [];
|
|
67
|
+
for (let i = 0; i < tokens.length; ) {
|
|
68
|
+
const a = tokens[i];
|
|
69
|
+
const b = tokens[i + 1];
|
|
70
|
+
if (i + 1 < tokens.length && canMerge(a, b)) {
|
|
71
|
+
out.push(doubled(a));
|
|
72
|
+
i += 2;
|
|
73
|
+
} else {
|
|
74
|
+
out.push(a);
|
|
75
|
+
i += 1;
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
return out;
|
|
79
|
+
}
|
|
80
|
+
function simplifyTimed(moves) {
|
|
81
|
+
const out = [];
|
|
82
|
+
for (let i = 0; i < moves.length; ) {
|
|
83
|
+
const a = moves[i];
|
|
84
|
+
const b = moves[i + 1];
|
|
85
|
+
if (i + 1 < moves.length && canMerge(a == null ? void 0 : a.m, b == null ? void 0 : b.m)) {
|
|
86
|
+
out.push({ m: doubled(a.m), t: b.t });
|
|
87
|
+
i += 2;
|
|
88
|
+
} else {
|
|
89
|
+
out.push(a);
|
|
90
|
+
i += 1;
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
return out;
|
|
94
|
+
}
|
|
95
|
+
function simplifyMoves(moves) {
|
|
96
|
+
if (typeof moves === "string") {
|
|
97
|
+
const tokens = moves.split(/\s+/).filter((t) => t.length > 0);
|
|
98
|
+
return simplifyTokens(tokens).join(" ");
|
|
99
|
+
}
|
|
100
|
+
if (Array.isArray(moves)) {
|
|
101
|
+
if (moves.length === 0) return [];
|
|
102
|
+
if (typeof moves[0] === "string") return simplifyTokens(moves);
|
|
103
|
+
return simplifyTimed(moves);
|
|
104
|
+
}
|
|
105
|
+
return moves;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
// src/analyzer.js
|
|
109
|
+
var FACE_NAMES = ["UPPER", "LEFT", "FRONT", "RIGHT", "BACK", "DOWN"];
|
|
110
|
+
var FACE_MOVE_TO_INDEX = { U: 0, L: 1, F: 2, R: 3, B: 4, D: 5 };
|
|
111
|
+
var SUPPORTED_BASES = /* @__PURE__ */ new Set([
|
|
112
|
+
"U",
|
|
113
|
+
"D",
|
|
114
|
+
"L",
|
|
115
|
+
"R",
|
|
116
|
+
"F",
|
|
117
|
+
"B",
|
|
118
|
+
"x",
|
|
119
|
+
"y",
|
|
120
|
+
"z",
|
|
121
|
+
"M",
|
|
122
|
+
"E",
|
|
123
|
+
"S",
|
|
124
|
+
"Uw",
|
|
125
|
+
"Dw",
|
|
126
|
+
"Rw",
|
|
127
|
+
"Lw",
|
|
128
|
+
"Fw"
|
|
129
|
+
]);
|
|
130
|
+
var WIDE_LOWER = { r: "Rw", u: "Uw", f: "Fw", l: "Lw", d: "Dw", b: "Bw" };
|
|
131
|
+
function normalizeToken(raw) {
|
|
132
|
+
const m = String(raw).trim().match(/^([A-Za-z]w?)('?2?|2?'?)$/);
|
|
133
|
+
if (!m) return { token: raw, base: null };
|
|
134
|
+
let base = m[1];
|
|
135
|
+
if (base.length === 1 && WIDE_LOWER[base]) base = WIDE_LOWER[base];
|
|
136
|
+
return { token: base + m[2], base };
|
|
137
|
+
}
|
|
138
|
+
var GEOMETRY_CACHE = /* @__PURE__ */ new Map();
|
|
139
|
+
function buildGeometry(size) {
|
|
140
|
+
if (GEOMETRY_CACHE.has(size)) return GEOMETRY_CACHE.get(size);
|
|
141
|
+
const perms = getMovePermutations(size);
|
|
142
|
+
const per = size * size;
|
|
143
|
+
const total = per * 6;
|
|
144
|
+
const faceMoves = Object.keys(FACE_MOVE_TO_INDEX);
|
|
145
|
+
const edgeMap = /* @__PURE__ */ new Map();
|
|
146
|
+
const cornerMap = /* @__PURE__ */ new Map();
|
|
147
|
+
for (let i = 0; i < total; i++) {
|
|
148
|
+
const faces = [];
|
|
149
|
+
for (const mv of faceMoves) {
|
|
150
|
+
if (perms[mv].cw[i] !== i) faces.push(FACE_MOVE_TO_INDEX[mv]);
|
|
151
|
+
}
|
|
152
|
+
faces.sort((a, b) => a - b);
|
|
153
|
+
const key = faces.join(",");
|
|
154
|
+
if (faces.length === 2) {
|
|
155
|
+
if (!edgeMap.has(key)) edgeMap.set(key, []);
|
|
156
|
+
edgeMap.get(key).push(i);
|
|
157
|
+
} else if (faces.length === 3) {
|
|
158
|
+
if (!cornerMap.has(key)) cornerMap.set(key, []);
|
|
159
|
+
cornerMap.get(key).push(i);
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
const edges = [...edgeMap.entries()].map(([key, indices]) => ({
|
|
163
|
+
faces: key.split(",").map(Number),
|
|
164
|
+
indices
|
|
165
|
+
}));
|
|
166
|
+
const corners = [...cornerMap.entries()].map(([key, indices]) => ({
|
|
167
|
+
faces: key.split(",").map(Number),
|
|
168
|
+
indices
|
|
169
|
+
}));
|
|
170
|
+
const neighbors = Array.from({ length: 6 }, () => /* @__PURE__ */ new Set());
|
|
171
|
+
for (const e of edges) {
|
|
172
|
+
const [a, b] = e.faces;
|
|
173
|
+
neighbors[a].add(b);
|
|
174
|
+
neighbors[b].add(a);
|
|
175
|
+
}
|
|
176
|
+
const opposite = new Array(6).fill(-1);
|
|
177
|
+
for (let f = 0; f < 6; f++) {
|
|
178
|
+
for (let g = 0; g < 6; g++) {
|
|
179
|
+
if (g !== f && !neighbors[f].has(g)) {
|
|
180
|
+
opposite[f] = g;
|
|
181
|
+
break;
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
const geo = {
|
|
186
|
+
size,
|
|
187
|
+
per,
|
|
188
|
+
centerIndex: (f) => f * per + Math.floor(per / 2),
|
|
189
|
+
edges,
|
|
190
|
+
corners,
|
|
191
|
+
neighbors,
|
|
192
|
+
opposite,
|
|
193
|
+
edgesByFace: (f) => edges.filter((e) => e.faces.includes(f)),
|
|
194
|
+
cornersByFace: (f) => corners.filter((c) => c.faces.includes(f)),
|
|
195
|
+
edgeByPair: (a, b) => edges.find(
|
|
196
|
+
(e) => e.faces[0] === a && e.faces[1] === b || e.faces[0] === b && e.faces[1] === a
|
|
197
|
+
)
|
|
198
|
+
};
|
|
199
|
+
GEOMETRY_CACHE.set(size, geo);
|
|
200
|
+
return geo;
|
|
201
|
+
}
|
|
202
|
+
function invertToken(tok) {
|
|
203
|
+
if (tok.endsWith("2")) return tok;
|
|
204
|
+
if (tok.endsWith("'")) return tok.slice(0, -1);
|
|
205
|
+
return tok + "'";
|
|
206
|
+
}
|
|
207
|
+
function invertSequence(tokens) {
|
|
208
|
+
return tokens.slice().reverse().map(invertToken);
|
|
209
|
+
}
|
|
210
|
+
function flattenState(state) {
|
|
211
|
+
const out = [];
|
|
212
|
+
for (const name of FACE_NAMES) {
|
|
213
|
+
const matrix = state[name];
|
|
214
|
+
for (const row of matrix) {
|
|
215
|
+
for (const v of row) out.push(v);
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
return out;
|
|
219
|
+
}
|
|
220
|
+
function centersOf(st, geo) {
|
|
221
|
+
const centers = new Array(6);
|
|
222
|
+
for (let f = 0; f < 6; f++) centers[f] = st[geo.centerIndex(f)];
|
|
223
|
+
return centers;
|
|
224
|
+
}
|
|
225
|
+
function slotCorrect(st, centers, indices, per) {
|
|
226
|
+
for (const x of indices) {
|
|
227
|
+
if (st[x] !== centers[Math.floor(x / per)]) return false;
|
|
228
|
+
}
|
|
229
|
+
return true;
|
|
230
|
+
}
|
|
231
|
+
function isSolvedFlat(st, per) {
|
|
232
|
+
for (let f = 0; f < 6; f++) {
|
|
233
|
+
const base = f * per;
|
|
234
|
+
const c = st[base];
|
|
235
|
+
for (let i = 1; i < per; i++) if (st[base + i] !== c) return false;
|
|
236
|
+
}
|
|
237
|
+
return true;
|
|
238
|
+
}
|
|
239
|
+
function crossDone(st, geo, color) {
|
|
240
|
+
const centers = centersOf(st, geo);
|
|
241
|
+
const C = centers.indexOf(color);
|
|
242
|
+
if (C < 0) return false;
|
|
243
|
+
return geo.edgesByFace(C).every((e) => slotCorrect(st, centers, e.indices, geo.per));
|
|
244
|
+
}
|
|
245
|
+
function f2lSlotStates(st, geo, color) {
|
|
246
|
+
const centers = centersOf(st, geo);
|
|
247
|
+
const C = centers.indexOf(color);
|
|
248
|
+
const result = {};
|
|
249
|
+
if (C < 0) return result;
|
|
250
|
+
for (const corner of geo.cornersByFace(C)) {
|
|
251
|
+
const sides = corner.faces.filter((f) => f !== C);
|
|
252
|
+
if (sides.length !== 2) continue;
|
|
253
|
+
const [a, b] = sides;
|
|
254
|
+
const edge = geo.edgeByPair(a, b);
|
|
255
|
+
const cornerOk = slotCorrect(st, centers, corner.indices, geo.per);
|
|
256
|
+
const edgeOk = edge ? slotCorrect(st, centers, edge.indices, geo.per) : false;
|
|
257
|
+
const key = [centers[a], centers[b]].sort().join("-");
|
|
258
|
+
result[key] = cornerOk && edgeOk;
|
|
259
|
+
}
|
|
260
|
+
return result;
|
|
261
|
+
}
|
|
262
|
+
function ollDone(st, geo, color) {
|
|
263
|
+
const centers = centersOf(st, geo);
|
|
264
|
+
const C = centers.indexOf(color);
|
|
265
|
+
if (C < 0) return false;
|
|
266
|
+
const O = geo.opposite[C];
|
|
267
|
+
const base = O * geo.per;
|
|
268
|
+
for (let i = 0; i < geo.per; i++) {
|
|
269
|
+
if (st[base + i] !== centers[O]) return false;
|
|
270
|
+
}
|
|
271
|
+
return true;
|
|
272
|
+
}
|
|
273
|
+
function completionIndex(bools) {
|
|
274
|
+
const n = bools.length;
|
|
275
|
+
if (n === 0 || !bools[n - 1]) return null;
|
|
276
|
+
for (let i = 0; i < n; i++) if (bools[i]) return i;
|
|
277
|
+
return null;
|
|
278
|
+
}
|
|
279
|
+
function buildForCross(snapshots, geo, color) {
|
|
280
|
+
const n = snapshots.length;
|
|
281
|
+
const crossBools = snapshots.map((st) => crossDone(st, geo, color));
|
|
282
|
+
const crossIdx = completionIndex(crossBools);
|
|
283
|
+
const slotSeries = /* @__PURE__ */ new Map();
|
|
284
|
+
for (let i = 0; i < n; i++) {
|
|
285
|
+
const states = f2lSlotStates(snapshots[i], geo, color);
|
|
286
|
+
for (const [key, val] of Object.entries(states)) {
|
|
287
|
+
if (!slotSeries.has(key)) slotSeries.set(key, new Array(n).fill(false));
|
|
288
|
+
slotSeries.get(key)[i] = crossBools[i] && val;
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
const f2lSlots = [...slotSeries.entries()].map(([slot, bools]) => ({ slot, idx: completionIndex(bools) })).filter((s) => s.idx != null).sort((a, b) => a.idx - b.idx);
|
|
292
|
+
const f2lComplete = new Array(n).fill(false);
|
|
293
|
+
for (let i = 0; i < n; i++) {
|
|
294
|
+
if (!crossBools[i] || slotSeries.size < 4) continue;
|
|
295
|
+
let all = true;
|
|
296
|
+
for (const bools of slotSeries.values()) {
|
|
297
|
+
if (!bools[i]) {
|
|
298
|
+
all = false;
|
|
299
|
+
break;
|
|
300
|
+
}
|
|
301
|
+
}
|
|
302
|
+
f2lComplete[i] = all;
|
|
303
|
+
}
|
|
304
|
+
const ollIdx = completionIndex(
|
|
305
|
+
snapshots.map((st, i) => f2lComplete[i] && ollDone(st, geo, color))
|
|
306
|
+
);
|
|
307
|
+
const pllIdx = completionIndex(snapshots.map((st) => isSolvedFlat(st, geo.per)));
|
|
308
|
+
return { crossIdx, f2lSlots, ollIdx, pllIdx };
|
|
309
|
+
}
|
|
310
|
+
function isCFOP(build) {
|
|
311
|
+
const { crossIdx, f2lSlots, ollIdx, pllIdx } = build;
|
|
312
|
+
if (crossIdx == null || pllIdx == null || ollIdx == null) return false;
|
|
313
|
+
if (f2lSlots.length !== 4) return false;
|
|
314
|
+
if (!f2lSlots.every((s) => s.idx >= crossIdx)) return false;
|
|
315
|
+
const lastF2L = f2lSlots[3].idx;
|
|
316
|
+
return ollIdx >= lastF2L && pllIdx >= ollIdx;
|
|
317
|
+
}
|
|
318
|
+
function analyzeSolution(moves, options = {}) {
|
|
319
|
+
var _a;
|
|
320
|
+
const size = options.size === 2 ? 2 : 3;
|
|
321
|
+
const unsupported = [];
|
|
322
|
+
const seq = (Array.isArray(moves) ? moves : []).map((x) => {
|
|
323
|
+
var _a2;
|
|
324
|
+
const m = String((_a2 = x == null ? void 0 : x.m) != null ? _a2 : "").trim();
|
|
325
|
+
const { token, base } = normalizeToken(m);
|
|
326
|
+
const supported = base != null && SUPPORTED_BASES.has(base);
|
|
327
|
+
if (m.length > 0 && !supported) unsupported.push(m);
|
|
328
|
+
return { m, mm: supported ? token : "", t: Number(x == null ? void 0 : x.t) };
|
|
329
|
+
}).filter((x) => x.m.length > 0);
|
|
330
|
+
const n = seq.length;
|
|
331
|
+
const simplifiedMoves = simplifyMoves(
|
|
332
|
+
(Array.isArray(moves) ? moves : []).filter((x) => x == null ? void 0 : x.m)
|
|
333
|
+
);
|
|
334
|
+
const simplifiedCount = simplifiedMoves.length;
|
|
335
|
+
const empty = {
|
|
336
|
+
size,
|
|
337
|
+
method: "unknown",
|
|
338
|
+
solved: false,
|
|
339
|
+
total: n > 0 ? seq[n - 1].t : 0,
|
|
340
|
+
tps: 0,
|
|
341
|
+
moves: simplifiedMoves,
|
|
342
|
+
cross: null,
|
|
343
|
+
f2l: [],
|
|
344
|
+
oll: null,
|
|
345
|
+
pll: null,
|
|
346
|
+
allCrosses: {},
|
|
347
|
+
unsupported
|
|
348
|
+
};
|
|
349
|
+
if (n === 0) return empty;
|
|
350
|
+
const engine = new CubeEngine("", { size });
|
|
351
|
+
const scramble = invertSequence(seq.map((x) => x.mm).filter(Boolean)).join(" ");
|
|
352
|
+
engine.applyMoves(scramble, { record: false });
|
|
353
|
+
const geo = buildGeometry(size);
|
|
354
|
+
const snapshots = new Array(n);
|
|
355
|
+
for (let i = 0; i < n; i++) {
|
|
356
|
+
if (seq[i].mm) engine.applyMoves(seq[i].mm, { record: false });
|
|
357
|
+
snapshots[i] = flattenState(engine.state());
|
|
358
|
+
}
|
|
359
|
+
const solved = isSolvedFlat(snapshots[n - 1], geo.per);
|
|
360
|
+
const pllIdxOnly = completionIndex(
|
|
361
|
+
snapshots.map((st) => isSolvedFlat(st, geo.per))
|
|
362
|
+
);
|
|
363
|
+
const milestone = (idx, prevAt2) => {
|
|
364
|
+
if (idx == null) return { record: null, at: prevAt2 };
|
|
365
|
+
const at = seq[idx].t;
|
|
366
|
+
return {
|
|
367
|
+
record: { at, duration: at - prevAt2, moveIndex: idx, move: seq[idx].m },
|
|
368
|
+
at
|
|
369
|
+
};
|
|
370
|
+
};
|
|
371
|
+
if (size !== 3) {
|
|
372
|
+
const pll2 = milestone(pllIdxOnly, 0);
|
|
373
|
+
const total2 = seq[n - 1].t;
|
|
374
|
+
return __spreadProps(__spreadValues({}, empty), {
|
|
375
|
+
solved,
|
|
376
|
+
total: total2,
|
|
377
|
+
tps: total2 > 0 ? simplifiedCount / (total2 / 1e3) : 0,
|
|
378
|
+
pll: pll2.record
|
|
379
|
+
});
|
|
380
|
+
}
|
|
381
|
+
const finalCenters = centersOf(snapshots[n - 1], geo);
|
|
382
|
+
const colors = [...new Set(finalCenters)];
|
|
383
|
+
const allCrosses = {};
|
|
384
|
+
for (const color of colors) {
|
|
385
|
+
const idx = completionIndex(
|
|
386
|
+
snapshots.map((st) => crossDone(st, geo, color))
|
|
387
|
+
);
|
|
388
|
+
allCrosses[color] = idx == null ? null : { at: seq[idx].t, moveIndex: idx, move: seq[idx].m };
|
|
389
|
+
}
|
|
390
|
+
const ordered = colors.map((color) => ({ color, build: buildForCross(snapshots, geo, color) })).sort((a, b) => {
|
|
391
|
+
var _a2, _b;
|
|
392
|
+
const ai = (_a2 = a.build.crossIdx) != null ? _a2 : Infinity;
|
|
393
|
+
const bi = (_b = b.build.crossIdx) != null ? _b : Infinity;
|
|
394
|
+
return ai - bi;
|
|
395
|
+
});
|
|
396
|
+
let chosen = (_a = ordered.find((c) => isCFOP(c.build))) != null ? _a : ordered[0];
|
|
397
|
+
const method = chosen && isCFOP(chosen.build) ? "CFOP" : "unknown";
|
|
398
|
+
const { color: crossColor, build } = chosen;
|
|
399
|
+
const crossM = milestone(build.crossIdx, 0);
|
|
400
|
+
const cross = crossM.record ? __spreadValues({ color: crossColor }, crossM.record) : null;
|
|
401
|
+
let prevAt = crossM.at;
|
|
402
|
+
const f2l = [];
|
|
403
|
+
for (const slot of build.f2lSlots) {
|
|
404
|
+
const m = milestone(slot.idx, prevAt);
|
|
405
|
+
if (m.record) {
|
|
406
|
+
f2l.push(__spreadValues({ slot: slot.slot }, m.record));
|
|
407
|
+
prevAt = m.at;
|
|
408
|
+
}
|
|
409
|
+
}
|
|
410
|
+
const ollM = milestone(build.ollIdx, prevAt);
|
|
411
|
+
const oll = ollM.record;
|
|
412
|
+
prevAt = ollM.at;
|
|
413
|
+
const pllM = milestone(build.pllIdx, prevAt);
|
|
414
|
+
const pll = pllM.record;
|
|
415
|
+
const total = seq[n - 1].t;
|
|
416
|
+
return {
|
|
417
|
+
size,
|
|
418
|
+
method,
|
|
419
|
+
solved,
|
|
420
|
+
total,
|
|
421
|
+
tps: total > 0 ? simplifiedCount / (total / 1e3) : 0,
|
|
422
|
+
moves: simplifiedMoves,
|
|
423
|
+
cross,
|
|
424
|
+
f2l,
|
|
425
|
+
oll,
|
|
426
|
+
pll,
|
|
427
|
+
allCrosses,
|
|
428
|
+
unsupported
|
|
429
|
+
};
|
|
430
|
+
}
|
|
431
|
+
|
|
432
|
+
// src/index.js
|
|
433
|
+
var FACE_NAMES2 = ["UPPER", "LEFT", "FRONT", "RIGHT", "BACK", "DOWN"];
|
|
434
|
+
var FACE_COLORS = ["W", "O", "G", "R", "B", "Y"];
|
|
435
|
+
var NOOP_SIZE2 = /* @__PURE__ */ new Set(["Uw", "Dw", "Rw", "Lw", "Fw", "M", "E", "S"]);
|
|
436
|
+
var MOVE_FNS = {
|
|
437
|
+
U: "rotateU",
|
|
438
|
+
D: "rotateD",
|
|
439
|
+
L: "rotateL",
|
|
440
|
+
R: "rotateR",
|
|
441
|
+
F: "rotateF",
|
|
442
|
+
B: "rotateB",
|
|
443
|
+
x: "rotateX",
|
|
444
|
+
y: "rotateY",
|
|
445
|
+
z: "rotateZ",
|
|
446
|
+
M: "rotateM",
|
|
447
|
+
E: "rotateE",
|
|
448
|
+
S: "rotateS",
|
|
449
|
+
Uw: "rotateUw",
|
|
450
|
+
Dw: "rotateDw",
|
|
451
|
+
Rw: "rotateRw",
|
|
452
|
+
Lw: "rotateLw",
|
|
453
|
+
Fw: "rotateFw"
|
|
454
|
+
};
|
|
455
|
+
var PERM_CACHE = /* @__PURE__ */ new Map();
|
|
456
|
+
var _OracleCube = class {
|
|
457
|
+
constructor(size) {
|
|
458
|
+
this.size = size;
|
|
459
|
+
this.STATES = {};
|
|
460
|
+
for (let f = 0; f < FACE_NAMES2.length; f++) {
|
|
461
|
+
const face = [];
|
|
462
|
+
for (let r = 0; r < size; r++) {
|
|
463
|
+
const row = [];
|
|
464
|
+
for (let c = 0; c < size; c++) {
|
|
465
|
+
row.push(f * size * size + r * size + c);
|
|
466
|
+
}
|
|
467
|
+
face.push(row);
|
|
468
|
+
}
|
|
469
|
+
this.STATES[FACE_NAMES2[f]] = face;
|
|
470
|
+
}
|
|
471
|
+
}
|
|
472
|
+
// Concatenate every face row-major into a single flat array of tags.
|
|
473
|
+
flatten() {
|
|
474
|
+
const out = [];
|
|
475
|
+
for (const name of FACE_NAMES2) {
|
|
476
|
+
const face = this.STATES[name];
|
|
477
|
+
for (let r = 0; r < this.size; r++) {
|
|
478
|
+
for (let c = 0; c < this.size; c++) {
|
|
479
|
+
out.push(face[r][c]);
|
|
480
|
+
}
|
|
481
|
+
}
|
|
482
|
+
}
|
|
483
|
+
return out;
|
|
484
|
+
}
|
|
485
|
+
switchMatrix(matrix, clockwise = true) {
|
|
486
|
+
const clone = structuredClone(matrix);
|
|
487
|
+
const size = this.size;
|
|
488
|
+
let tempMatrix = [];
|
|
489
|
+
for (let i = 0; i < size; i++) {
|
|
490
|
+
tempMatrix = [...tempMatrix, ...clone[i]];
|
|
491
|
+
}
|
|
492
|
+
if (size === 2) {
|
|
493
|
+
if (clockwise) {
|
|
494
|
+
return [
|
|
495
|
+
[tempMatrix[2], tempMatrix[0]],
|
|
496
|
+
[tempMatrix[3], tempMatrix[1]]
|
|
497
|
+
];
|
|
498
|
+
} else {
|
|
499
|
+
return [
|
|
500
|
+
[tempMatrix[1], tempMatrix[3]],
|
|
501
|
+
[tempMatrix[0], tempMatrix[2]]
|
|
502
|
+
];
|
|
503
|
+
}
|
|
504
|
+
} else {
|
|
505
|
+
if (clockwise) {
|
|
506
|
+
return [
|
|
507
|
+
[tempMatrix[6], tempMatrix[3], tempMatrix[0]],
|
|
508
|
+
[tempMatrix[7], tempMatrix[4], tempMatrix[1]],
|
|
509
|
+
[tempMatrix[8], tempMatrix[5], tempMatrix[2]]
|
|
510
|
+
];
|
|
511
|
+
} else {
|
|
512
|
+
return [
|
|
513
|
+
[tempMatrix[2], tempMatrix[5], tempMatrix[8]],
|
|
514
|
+
[tempMatrix[1], tempMatrix[4], tempMatrix[7]],
|
|
515
|
+
[tempMatrix[0], tempMatrix[3], tempMatrix[6]]
|
|
516
|
+
];
|
|
517
|
+
}
|
|
518
|
+
}
|
|
519
|
+
}
|
|
520
|
+
specialFlip(matrix) {
|
|
521
|
+
return structuredClone(matrix).reverse().map((row) => [...row].reverse());
|
|
522
|
+
}
|
|
523
|
+
rotateU(clockwise = true) {
|
|
524
|
+
if (clockwise) {
|
|
525
|
+
this.STATES.UPPER = this.switchMatrix(this.STATES.UPPER, true);
|
|
526
|
+
const tempFront = [...this.STATES.FRONT[0]];
|
|
527
|
+
const tempRight = [...this.STATES.RIGHT[0]];
|
|
528
|
+
const tempLeft = [...this.STATES.LEFT[0]];
|
|
529
|
+
const tempBack = [...this.STATES.BACK[0]];
|
|
530
|
+
this.STATES.FRONT[0] = [...tempRight];
|
|
531
|
+
this.STATES.LEFT[0] = [...tempFront];
|
|
532
|
+
this.STATES.BACK[0] = [...tempLeft];
|
|
533
|
+
this.STATES.RIGHT[0] = [...tempBack];
|
|
534
|
+
} else {
|
|
535
|
+
this.STATES.UPPER = this.switchMatrix(this.STATES.UPPER, false);
|
|
536
|
+
const tempFront = [...this.STATES.FRONT[0]];
|
|
537
|
+
const tempRight = [...this.STATES.RIGHT[0]];
|
|
538
|
+
const tempLeft = [...this.STATES.LEFT[0]];
|
|
539
|
+
const tempBack = [...this.STATES.BACK[0]];
|
|
540
|
+
this.STATES.FRONT[0] = [...tempLeft];
|
|
541
|
+
this.STATES.LEFT[0] = [...tempBack];
|
|
542
|
+
this.STATES.BACK[0] = [...tempRight];
|
|
543
|
+
this.STATES.RIGHT[0] = [...tempFront];
|
|
544
|
+
}
|
|
545
|
+
}
|
|
546
|
+
rotateF(clockwise = true) {
|
|
547
|
+
if (clockwise) {
|
|
548
|
+
this.rotateX(true);
|
|
549
|
+
this.rotateU(true);
|
|
550
|
+
this.rotateX(false);
|
|
551
|
+
} else {
|
|
552
|
+
this.rotateX(true);
|
|
553
|
+
this.rotateU(false);
|
|
554
|
+
this.rotateX(false);
|
|
555
|
+
}
|
|
556
|
+
}
|
|
557
|
+
rotateB(clockwise = true) {
|
|
558
|
+
this.rotateY(true);
|
|
559
|
+
this.rotateY(true);
|
|
560
|
+
if (clockwise) {
|
|
561
|
+
this.rotateF(true);
|
|
562
|
+
} else {
|
|
563
|
+
this.rotateF(false);
|
|
564
|
+
}
|
|
565
|
+
this.rotateY(false);
|
|
566
|
+
this.rotateY(false);
|
|
567
|
+
}
|
|
568
|
+
rotateR(clockwise = true) {
|
|
569
|
+
if (clockwise) {
|
|
570
|
+
this.rotateY(true);
|
|
571
|
+
this.rotateX(true);
|
|
572
|
+
this.rotateU(true);
|
|
573
|
+
this.rotateX(false);
|
|
574
|
+
this.rotateY(false);
|
|
575
|
+
} else {
|
|
576
|
+
this.rotateY(true);
|
|
577
|
+
this.rotateX(true);
|
|
578
|
+
this.rotateU(false);
|
|
579
|
+
this.rotateX(false);
|
|
580
|
+
this.rotateY(false);
|
|
581
|
+
}
|
|
582
|
+
}
|
|
583
|
+
rotateL(clockwise = true) {
|
|
584
|
+
if (clockwise) {
|
|
585
|
+
this.rotateY(false);
|
|
586
|
+
this.rotateX(true);
|
|
587
|
+
this.rotateU(true);
|
|
588
|
+
this.rotateX(false);
|
|
589
|
+
this.rotateY(true);
|
|
590
|
+
} else {
|
|
591
|
+
this.rotateY(false);
|
|
592
|
+
this.rotateX(true);
|
|
593
|
+
this.rotateU(false);
|
|
594
|
+
this.rotateX(false);
|
|
595
|
+
this.rotateY(true);
|
|
596
|
+
}
|
|
597
|
+
}
|
|
598
|
+
rotateD(clockwise = true) {
|
|
599
|
+
if (clockwise) {
|
|
600
|
+
this.rotateX(true);
|
|
601
|
+
this.rotateF(true);
|
|
602
|
+
this.rotateX(false);
|
|
603
|
+
} else {
|
|
604
|
+
this.rotateX(true);
|
|
605
|
+
this.rotateF(false);
|
|
606
|
+
this.rotateX(false);
|
|
607
|
+
}
|
|
608
|
+
}
|
|
609
|
+
rotateDw(clockwise = true) {
|
|
610
|
+
if (this.size === 2) return;
|
|
611
|
+
if (clockwise) {
|
|
612
|
+
this.rotateY(false);
|
|
613
|
+
this.rotateU(true);
|
|
614
|
+
} else {
|
|
615
|
+
this.rotateY(true);
|
|
616
|
+
this.rotateU(false);
|
|
617
|
+
}
|
|
618
|
+
}
|
|
619
|
+
rotateUw(clockwise = true) {
|
|
620
|
+
if (this.size === 2) return;
|
|
621
|
+
if (clockwise) {
|
|
622
|
+
this.rotateY(true);
|
|
623
|
+
this.rotateD(true);
|
|
624
|
+
} else {
|
|
625
|
+
this.rotateY(false);
|
|
626
|
+
this.rotateD(false);
|
|
627
|
+
}
|
|
628
|
+
}
|
|
629
|
+
rotateRw(clockwise = true) {
|
|
630
|
+
if (this.size === 2) return;
|
|
631
|
+
if (clockwise) {
|
|
632
|
+
this.rotateX(true);
|
|
633
|
+
this.rotateL(true);
|
|
634
|
+
} else {
|
|
635
|
+
this.rotateX(false);
|
|
636
|
+
this.rotateL(false);
|
|
637
|
+
}
|
|
638
|
+
}
|
|
639
|
+
rotateLw(clockwise = true) {
|
|
640
|
+
if (this.size === 2) return;
|
|
641
|
+
if (clockwise) {
|
|
642
|
+
this.rotateX(false);
|
|
643
|
+
this.rotateR(true);
|
|
644
|
+
} else {
|
|
645
|
+
this.rotateX(true);
|
|
646
|
+
this.rotateR(false);
|
|
647
|
+
}
|
|
648
|
+
}
|
|
649
|
+
rotateM(clockwise = true) {
|
|
650
|
+
if (this.size === 2) return;
|
|
651
|
+
if (clockwise) {
|
|
652
|
+
this.rotateLw(true);
|
|
653
|
+
this.rotateL(false);
|
|
654
|
+
} else {
|
|
655
|
+
this.rotateLw(false);
|
|
656
|
+
this.rotateL(true);
|
|
657
|
+
}
|
|
658
|
+
}
|
|
659
|
+
rotateE(clockwise = true) {
|
|
660
|
+
if (this.size === 2) return;
|
|
661
|
+
if (clockwise) {
|
|
662
|
+
this.rotateDw(true);
|
|
663
|
+
this.rotateD(false);
|
|
664
|
+
} else {
|
|
665
|
+
this.rotateDw(false);
|
|
666
|
+
this.rotateD(true);
|
|
667
|
+
}
|
|
668
|
+
}
|
|
669
|
+
rotateFw(clockwise = true) {
|
|
670
|
+
if (this.size === 2) return;
|
|
671
|
+
if (clockwise) {
|
|
672
|
+
this.rotateZ(true);
|
|
673
|
+
this.rotateB(true);
|
|
674
|
+
} else {
|
|
675
|
+
this.rotateZ(false);
|
|
676
|
+
this.rotateB(false);
|
|
677
|
+
}
|
|
678
|
+
}
|
|
679
|
+
rotateS(clockwise = true) {
|
|
680
|
+
if (this.size === 2) return;
|
|
681
|
+
if (clockwise) {
|
|
682
|
+
this.rotateFw(true);
|
|
683
|
+
this.rotateF(false);
|
|
684
|
+
} else {
|
|
685
|
+
this.rotateFw(false);
|
|
686
|
+
this.rotateF(true);
|
|
687
|
+
}
|
|
688
|
+
}
|
|
689
|
+
rotateX(clockwise = true) {
|
|
690
|
+
const tempFront = structuredClone(this.STATES.FRONT);
|
|
691
|
+
const tempDown = structuredClone(this.STATES.DOWN);
|
|
692
|
+
const tempUpper = structuredClone(this.STATES.UPPER);
|
|
693
|
+
const tempBack = structuredClone(this.STATES.BACK);
|
|
694
|
+
const tempLeft = structuredClone(this.STATES.LEFT);
|
|
695
|
+
const tempRight = structuredClone(this.STATES.RIGHT);
|
|
696
|
+
if (clockwise) {
|
|
697
|
+
this.STATES.LEFT = this.switchMatrix(tempLeft, false);
|
|
698
|
+
this.STATES.RIGHT = this.switchMatrix(tempRight, true);
|
|
699
|
+
this.STATES.FRONT = [...tempDown];
|
|
700
|
+
this.STATES.UPPER = [...tempFront];
|
|
701
|
+
this.STATES.BACK = this.specialFlip(tempUpper);
|
|
702
|
+
this.STATES.DOWN = this.specialFlip(tempBack);
|
|
703
|
+
} else {
|
|
704
|
+
this.STATES.LEFT = this.switchMatrix(tempLeft, true);
|
|
705
|
+
this.STATES.RIGHT = this.switchMatrix(tempRight, false);
|
|
706
|
+
this.STATES.FRONT = [...tempUpper];
|
|
707
|
+
this.STATES.DOWN = [...tempFront];
|
|
708
|
+
this.STATES.BACK = this.specialFlip(tempDown);
|
|
709
|
+
this.STATES.UPPER = this.specialFlip(tempBack);
|
|
710
|
+
}
|
|
711
|
+
}
|
|
712
|
+
rotateZ(clockwise = true) {
|
|
713
|
+
const tempUpper = structuredClone(this.STATES.UPPER);
|
|
714
|
+
const tempRight = structuredClone(this.STATES.RIGHT);
|
|
715
|
+
const tempDown = structuredClone(this.STATES.DOWN);
|
|
716
|
+
const tempLeft = structuredClone(this.STATES.LEFT);
|
|
717
|
+
const tempFront = structuredClone(this.STATES.FRONT);
|
|
718
|
+
const tempBack = structuredClone(this.STATES.BACK);
|
|
719
|
+
if (clockwise) {
|
|
720
|
+
this.STATES.FRONT = this.switchMatrix(tempFront, true);
|
|
721
|
+
this.STATES.BACK = this.switchMatrix(tempBack, false);
|
|
722
|
+
this.STATES.RIGHT = this.switchMatrix(tempUpper, true);
|
|
723
|
+
this.STATES.DOWN = this.switchMatrix(tempRight, true);
|
|
724
|
+
this.STATES.LEFT = this.switchMatrix(tempDown, true);
|
|
725
|
+
this.STATES.UPPER = this.switchMatrix(tempLeft, true);
|
|
726
|
+
} else {
|
|
727
|
+
this.STATES.FRONT = this.switchMatrix(tempFront, false);
|
|
728
|
+
this.STATES.BACK = this.switchMatrix(tempBack, true);
|
|
729
|
+
this.STATES.RIGHT = this.switchMatrix(tempDown, false);
|
|
730
|
+
this.STATES.DOWN = this.switchMatrix(tempLeft, false);
|
|
731
|
+
this.STATES.LEFT = this.switchMatrix(tempUpper, false);
|
|
732
|
+
this.STATES.UPPER = this.switchMatrix(tempRight, false);
|
|
733
|
+
}
|
|
734
|
+
}
|
|
735
|
+
rotateY(clockwise = true) {
|
|
736
|
+
const tempFront = structuredClone(this.STATES.FRONT);
|
|
737
|
+
const tempRight = structuredClone(this.STATES.RIGHT);
|
|
738
|
+
const tempBack = structuredClone(this.STATES.BACK);
|
|
739
|
+
const tempLeft = structuredClone(this.STATES.LEFT);
|
|
740
|
+
if (clockwise) {
|
|
741
|
+
this.STATES.UPPER = this.switchMatrix(this.STATES.UPPER, true);
|
|
742
|
+
this.STATES.DOWN = this.switchMatrix(this.STATES.DOWN, false);
|
|
743
|
+
this.STATES.FRONT = [...tempRight];
|
|
744
|
+
this.STATES.RIGHT = [...tempBack];
|
|
745
|
+
this.STATES.LEFT = [...tempFront];
|
|
746
|
+
this.STATES.BACK = [...tempLeft];
|
|
747
|
+
} else {
|
|
748
|
+
this.STATES.UPPER = this.switchMatrix(this.STATES.UPPER, false);
|
|
749
|
+
this.STATES.DOWN = this.switchMatrix(this.STATES.DOWN, true);
|
|
750
|
+
this.STATES.FRONT = [...tempLeft];
|
|
751
|
+
this.STATES.RIGHT = [...tempFront];
|
|
752
|
+
this.STATES.LEFT = [...tempBack];
|
|
753
|
+
this.STATES.BACK = [...tempRight];
|
|
754
|
+
}
|
|
755
|
+
}
|
|
756
|
+
};
|
|
757
|
+
function buildPerm(size, fnName, clockwise) {
|
|
758
|
+
const oracle = new _OracleCube(size);
|
|
759
|
+
oracle[fnName](clockwise);
|
|
760
|
+
return oracle.flatten();
|
|
761
|
+
}
|
|
762
|
+
function getPerms(size) {
|
|
763
|
+
if (PERM_CACHE.has(size)) return PERM_CACHE.get(size);
|
|
764
|
+
const perms = {};
|
|
765
|
+
for (const key of Object.keys(MOVE_FNS)) {
|
|
766
|
+
perms[key] = {
|
|
767
|
+
cw: buildPerm(size, MOVE_FNS[key], true),
|
|
768
|
+
ccw: buildPerm(size, MOVE_FNS[key], false)
|
|
769
|
+
};
|
|
770
|
+
}
|
|
771
|
+
PERM_CACHE.set(size, perms);
|
|
772
|
+
return perms;
|
|
773
|
+
}
|
|
774
|
+
function getMovePermutations(size = 3) {
|
|
775
|
+
const allowedSizes = [2, 3];
|
|
776
|
+
return getPerms(allowedSizes.includes(size) ? size : 3);
|
|
777
|
+
}
|
|
778
|
+
var _stickers, _perms, _CubeEngine_instances, initializeState_fn, applyPerm_fn, apply_fn, faceMatrix_fn, applyMovesFromString_fn;
|
|
49
779
|
var CubeEngine = class {
|
|
50
|
-
constructor(initialScramble = "") {
|
|
780
|
+
constructor(initialScramble = "", options = { size: 3 }) {
|
|
51
781
|
__privateAdd(this, _CubeEngine_instances);
|
|
52
782
|
__publicField(this, "MOVES", []);
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
],
|
|
61
|
-
LEFT: [
|
|
62
|
-
// (Orange)
|
|
63
|
-
[COLOR.O[0], COLOR.O[1], COLOR.O[2]],
|
|
64
|
-
[COLOR.O[3], COLOR.O[4], COLOR.O[5]],
|
|
65
|
-
[COLOR.O[6], COLOR.O[7], COLOR.O[8]]
|
|
66
|
-
],
|
|
67
|
-
FRONT: [
|
|
68
|
-
// (Green)
|
|
69
|
-
[COLOR.G[0], COLOR.G[1], COLOR.G[2]],
|
|
70
|
-
[COLOR.G[3], COLOR.G[4], COLOR.G[5]],
|
|
71
|
-
[COLOR.G[6], COLOR.G[7], COLOR.G[8]]
|
|
72
|
-
],
|
|
73
|
-
RIGHT: [
|
|
74
|
-
// (Red)
|
|
75
|
-
[COLOR.R[0], COLOR.R[1], COLOR.R[2]],
|
|
76
|
-
[COLOR.R[3], COLOR.R[4], COLOR.R[5]],
|
|
77
|
-
[COLOR.R[6], COLOR.R[7], COLOR.R[8]]
|
|
78
|
-
],
|
|
79
|
-
BACK: [
|
|
80
|
-
// (Blue)
|
|
81
|
-
[COLOR.B[0], COLOR.B[1], COLOR.B[2]],
|
|
82
|
-
[COLOR.B[3], COLOR.B[4], COLOR.B[5]],
|
|
83
|
-
[COLOR.B[6], COLOR.B[7], COLOR.B[8]]
|
|
84
|
-
],
|
|
85
|
-
DOWN: [
|
|
86
|
-
// (Yellow)
|
|
87
|
-
[COLOR.Y[0], COLOR.Y[1], COLOR.Y[2]],
|
|
88
|
-
[COLOR.Y[3], COLOR.Y[4], COLOR.Y[5]],
|
|
89
|
-
[COLOR.Y[6], COLOR.Y[7], COLOR.Y[8]]
|
|
90
|
-
]
|
|
91
|
-
});
|
|
783
|
+
__publicField(this, "size", 3);
|
|
784
|
+
__privateAdd(this, _stickers, []);
|
|
785
|
+
__privateAdd(this, _perms, null);
|
|
786
|
+
const allowedSizes = [2, 3];
|
|
787
|
+
this.size = allowedSizes.includes(options.size) ? options.size : 3;
|
|
788
|
+
__privateSet(this, _perms, getPerms(this.size));
|
|
789
|
+
__privateMethod(this, _CubeEngine_instances, initializeState_fn).call(this);
|
|
92
790
|
if (typeof initialScramble === "string" && initialScramble.trim().length > 0) {
|
|
93
791
|
__privateMethod(this, _CubeEngine_instances, applyMovesFromString_fn).call(this, initialScramble, false);
|
|
94
792
|
this.MOVES = [];
|
|
@@ -98,191 +796,131 @@ var CubeEngine = class {
|
|
|
98
796
|
* Rotates the (UPPER) layer clockwise or counterclockwise.
|
|
99
797
|
*/
|
|
100
798
|
rotateU(clockwise = true) {
|
|
101
|
-
|
|
102
|
-
__privateMethod(this, _CubeEngine_instances, rotateU_fn).call(this, true);
|
|
103
|
-
this.MOVES.push("U");
|
|
104
|
-
} else {
|
|
105
|
-
__privateMethod(this, _CubeEngine_instances, rotateU_fn).call(this, false);
|
|
106
|
-
this.MOVES.push("U'");
|
|
107
|
-
}
|
|
799
|
+
__privateMethod(this, _CubeEngine_instances, apply_fn).call(this, "U", clockwise ? "cw" : "ccw", true);
|
|
108
800
|
}
|
|
109
801
|
/**
|
|
110
802
|
* Rotates the (FRONT) layer clockwise or counterclockwise.
|
|
111
803
|
*/
|
|
112
804
|
rotateF(clockwise = true) {
|
|
113
|
-
|
|
114
|
-
__privateMethod(this, _CubeEngine_instances, rotateF_fn).call(this, true);
|
|
115
|
-
this.MOVES.push("F");
|
|
116
|
-
} else {
|
|
117
|
-
__privateMethod(this, _CubeEngine_instances, rotateF_fn).call(this, false);
|
|
118
|
-
this.MOVES.push("F'");
|
|
119
|
-
}
|
|
805
|
+
__privateMethod(this, _CubeEngine_instances, apply_fn).call(this, "F", clockwise ? "cw" : "ccw", true);
|
|
120
806
|
}
|
|
121
807
|
/**
|
|
122
808
|
* Rotates the (BACK) layer clockwise or counterclockwise.
|
|
123
809
|
*/
|
|
124
810
|
rotateB(clockwise = true) {
|
|
125
|
-
|
|
126
|
-
__privateMethod(this, _CubeEngine_instances, rotateB_fn).call(this, true);
|
|
127
|
-
this.MOVES.push("B");
|
|
128
|
-
} else {
|
|
129
|
-
__privateMethod(this, _CubeEngine_instances, rotateB_fn).call(this, false);
|
|
130
|
-
this.MOVES.push("B'");
|
|
131
|
-
}
|
|
811
|
+
__privateMethod(this, _CubeEngine_instances, apply_fn).call(this, "B", clockwise ? "cw" : "ccw", true);
|
|
132
812
|
}
|
|
133
813
|
/**
|
|
134
814
|
* Rotates the (RIGHT) layer clockwise or counterclockwise.
|
|
135
815
|
*/
|
|
136
816
|
rotateR(clockwise = true) {
|
|
137
|
-
|
|
138
|
-
__privateMethod(this, _CubeEngine_instances, rotateR_fn).call(this, true);
|
|
139
|
-
this.MOVES.push("R");
|
|
140
|
-
} else {
|
|
141
|
-
__privateMethod(this, _CubeEngine_instances, rotateR_fn).call(this, false);
|
|
142
|
-
this.MOVES.push("R'");
|
|
143
|
-
}
|
|
817
|
+
__privateMethod(this, _CubeEngine_instances, apply_fn).call(this, "R", clockwise ? "cw" : "ccw", true);
|
|
144
818
|
}
|
|
145
819
|
/**
|
|
146
820
|
* Rotates the (LEFT) layer clockwise or counterclockwise.
|
|
147
821
|
*/
|
|
148
822
|
rotateL(clockwise = true) {
|
|
149
|
-
|
|
150
|
-
__privateMethod(this, _CubeEngine_instances, rotateL_fn).call(this, true);
|
|
151
|
-
this.MOVES.push("L");
|
|
152
|
-
} else {
|
|
153
|
-
__privateMethod(this, _CubeEngine_instances, rotateL_fn).call(this, false);
|
|
154
|
-
this.MOVES.push("L'");
|
|
155
|
-
}
|
|
823
|
+
__privateMethod(this, _CubeEngine_instances, apply_fn).call(this, "L", clockwise ? "cw" : "ccw", true);
|
|
156
824
|
}
|
|
157
825
|
/**
|
|
158
826
|
* Rotates the (DOWN) layer clockwise or counterclockwise.
|
|
159
827
|
*/
|
|
160
828
|
rotateD(clockwise = true) {
|
|
161
|
-
|
|
162
|
-
__privateMethod(this, _CubeEngine_instances, rotateD_fn).call(this, true);
|
|
163
|
-
this.MOVES.push("D");
|
|
164
|
-
} else {
|
|
165
|
-
__privateMethod(this, _CubeEngine_instances, rotateD_fn).call(this, false);
|
|
166
|
-
this.MOVES.push("D'");
|
|
167
|
-
}
|
|
829
|
+
__privateMethod(this, _CubeEngine_instances, apply_fn).call(this, "D", clockwise ? "cw" : "ccw", true);
|
|
168
830
|
}
|
|
169
831
|
/**
|
|
170
832
|
* Rotates the wide (DOWN two layers) clockwise or counterclockwise.
|
|
171
833
|
*/
|
|
172
834
|
rotateDw(clockwise = true) {
|
|
173
|
-
|
|
174
|
-
__privateMethod(this, _CubeEngine_instances, rotateDw_fn).call(this, true);
|
|
175
|
-
this.MOVES.push("Dw");
|
|
176
|
-
} else {
|
|
177
|
-
__privateMethod(this, _CubeEngine_instances, rotateDw_fn).call(this, false);
|
|
178
|
-
this.MOVES.push("Dw'");
|
|
179
|
-
}
|
|
835
|
+
__privateMethod(this, _CubeEngine_instances, apply_fn).call(this, "Dw", clockwise ? "cw" : "ccw", true);
|
|
180
836
|
}
|
|
181
837
|
/**
|
|
182
838
|
* Rotates the wide (UPPER two layers) clockwise or counterclockwise.
|
|
183
839
|
*/
|
|
184
840
|
rotateUw(clockwise = true) {
|
|
185
|
-
|
|
186
|
-
__privateMethod(this, _CubeEngine_instances, rotateUw_fn).call(this, true);
|
|
187
|
-
this.MOVES.push("Uw");
|
|
188
|
-
} else {
|
|
189
|
-
__privateMethod(this, _CubeEngine_instances, rotateUw_fn).call(this, false);
|
|
190
|
-
this.MOVES.push("Uw'");
|
|
191
|
-
}
|
|
841
|
+
__privateMethod(this, _CubeEngine_instances, apply_fn).call(this, "Uw", clockwise ? "cw" : "ccw", true);
|
|
192
842
|
}
|
|
193
843
|
/**
|
|
194
844
|
* Rotates the wide (RIGHT two layers) clockwise or counterclockwise.
|
|
195
845
|
*/
|
|
196
846
|
rotateRw(clockwise = true) {
|
|
197
|
-
|
|
198
|
-
__privateMethod(this, _CubeEngine_instances, rotateRw_fn).call(this, true);
|
|
199
|
-
this.MOVES.push("Rw");
|
|
200
|
-
} else {
|
|
201
|
-
__privateMethod(this, _CubeEngine_instances, rotateRw_fn).call(this, false);
|
|
202
|
-
this.MOVES.push("Rw'");
|
|
203
|
-
}
|
|
847
|
+
__privateMethod(this, _CubeEngine_instances, apply_fn).call(this, "Rw", clockwise ? "cw" : "ccw", true);
|
|
204
848
|
}
|
|
205
849
|
/**
|
|
206
850
|
* Rotates the wide (LEFT two layers) clockwise or counterclockwise.
|
|
207
851
|
*/
|
|
208
852
|
rotateLw(clockwise = true) {
|
|
209
|
-
|
|
210
|
-
__privateMethod(this, _CubeEngine_instances, rotateLw_fn).call(this, true);
|
|
211
|
-
this.MOVES.push("Lw");
|
|
212
|
-
} else {
|
|
213
|
-
__privateMethod(this, _CubeEngine_instances, rotateLw_fn).call(this, false);
|
|
214
|
-
this.MOVES.push("Lw'");
|
|
215
|
-
}
|
|
853
|
+
__privateMethod(this, _CubeEngine_instances, apply_fn).call(this, "Lw", clockwise ? "cw" : "ccw", true);
|
|
216
854
|
}
|
|
217
855
|
/**
|
|
218
856
|
* Rotates the middle slice (M) parallel to L/R. Clockwise corresponds to Lw followed by L'.
|
|
219
857
|
*/
|
|
220
858
|
rotateM(clockwise = true) {
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
859
|
+
__privateMethod(this, _CubeEngine_instances, apply_fn).call(this, "M", clockwise ? "cw" : "ccw", true);
|
|
860
|
+
}
|
|
861
|
+
/**
|
|
862
|
+
* Rotates the equatorial slice (E) parallel to U/D. Clockwise follows the D direction (E = Dw D').
|
|
863
|
+
*/
|
|
864
|
+
rotateE(clockwise = true) {
|
|
865
|
+
__privateMethod(this, _CubeEngine_instances, apply_fn).call(this, "E", clockwise ? "cw" : "ccw", true);
|
|
866
|
+
}
|
|
867
|
+
/**
|
|
868
|
+
* Rotates the wide (FRONT two layers) clockwise or counterclockwise. Equivalent to z B.
|
|
869
|
+
*/
|
|
870
|
+
rotateFw(clockwise = true) {
|
|
871
|
+
__privateMethod(this, _CubeEngine_instances, apply_fn).call(this, "Fw", clockwise ? "cw" : "ccw", true);
|
|
872
|
+
}
|
|
873
|
+
/**
|
|
874
|
+
* Rotates the standing slice (S) parallel to F/B. Clockwise follows the F direction (S = Fw F').
|
|
875
|
+
*/
|
|
876
|
+
rotateS(clockwise = true) {
|
|
877
|
+
__privateMethod(this, _CubeEngine_instances, apply_fn).call(this, "S", clockwise ? "cw" : "ccw", true);
|
|
228
878
|
}
|
|
229
879
|
/**
|
|
230
880
|
* Rotates the (x) axis clockwise or counterclockwise.
|
|
231
881
|
*/
|
|
232
882
|
rotateX(clockwise = true) {
|
|
233
|
-
|
|
234
|
-
__privateMethod(this, _CubeEngine_instances, rotateX_fn).call(this, true);
|
|
235
|
-
this.MOVES.push("x");
|
|
236
|
-
} else {
|
|
237
|
-
__privateMethod(this, _CubeEngine_instances, rotateX_fn).call(this, false);
|
|
238
|
-
this.MOVES.push("x'");
|
|
239
|
-
}
|
|
883
|
+
__privateMethod(this, _CubeEngine_instances, apply_fn).call(this, "x", clockwise ? "cw" : "ccw", true);
|
|
240
884
|
}
|
|
241
885
|
/**
|
|
242
886
|
* Rotates the (z) axis clockwise or counterclockwise.
|
|
243
887
|
*/
|
|
244
888
|
rotateZ(clockwise = true) {
|
|
245
|
-
|
|
246
|
-
__privateMethod(this, _CubeEngine_instances, rotateZ_fn).call(this, true);
|
|
247
|
-
this.MOVES.push("z");
|
|
248
|
-
} else {
|
|
249
|
-
__privateMethod(this, _CubeEngine_instances, rotateZ_fn).call(this, false);
|
|
250
|
-
this.MOVES.push("z'");
|
|
251
|
-
}
|
|
889
|
+
__privateMethod(this, _CubeEngine_instances, apply_fn).call(this, "z", clockwise ? "cw" : "ccw", true);
|
|
252
890
|
}
|
|
253
891
|
/**
|
|
254
892
|
* Rotates the (y) axis clockwise or counterclockwise.
|
|
255
893
|
*/
|
|
256
894
|
rotateY(clockwise = true) {
|
|
257
|
-
|
|
258
|
-
__privateMethod(this, _CubeEngine_instances, rotateY_fn).call(this, true);
|
|
259
|
-
this.MOVES.push("y");
|
|
260
|
-
} else {
|
|
261
|
-
__privateMethod(this, _CubeEngine_instances, rotateY_fn).call(this, false);
|
|
262
|
-
this.MOVES.push("y'");
|
|
263
|
-
}
|
|
895
|
+
__privateMethod(this, _CubeEngine_instances, apply_fn).call(this, "y", clockwise ? "cw" : "ccw", true);
|
|
264
896
|
}
|
|
265
897
|
/**
|
|
266
898
|
* Logs the current state of the cube.
|
|
267
899
|
*/
|
|
268
900
|
state() {
|
|
269
|
-
return
|
|
901
|
+
return {
|
|
902
|
+
UPPER: __privateMethod(this, _CubeEngine_instances, faceMatrix_fn).call(this, 0),
|
|
903
|
+
LEFT: __privateMethod(this, _CubeEngine_instances, faceMatrix_fn).call(this, 1),
|
|
904
|
+
FRONT: __privateMethod(this, _CubeEngine_instances, faceMatrix_fn).call(this, 2),
|
|
905
|
+
RIGHT: __privateMethod(this, _CubeEngine_instances, faceMatrix_fn).call(this, 3),
|
|
906
|
+
BACK: __privateMethod(this, _CubeEngine_instances, faceMatrix_fn).call(this, 4),
|
|
907
|
+
DOWN: __privateMethod(this, _CubeEngine_instances, faceMatrix_fn).call(this, 5)
|
|
908
|
+
};
|
|
270
909
|
}
|
|
271
910
|
/**
|
|
272
911
|
* Indicates if the cube is solve or not in all layers.
|
|
273
912
|
*/
|
|
274
913
|
isSolved() {
|
|
275
|
-
const
|
|
276
|
-
const
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
return layersSolved.every((isLayerSolved) => isLayerSolved);
|
|
914
|
+
const per = this.size * this.size;
|
|
915
|
+
const centerOffset = this.size === 2 ? 0 : 4;
|
|
916
|
+
for (let f = 0; f < FACE_COLORS.length; f++) {
|
|
917
|
+
const base = f * per;
|
|
918
|
+
const centerColor = __privateGet(this, _stickers)[base + centerOffset];
|
|
919
|
+
for (let i = 0; i < per; i++) {
|
|
920
|
+
if (__privateGet(this, _stickers)[base + i] !== centerColor) return false;
|
|
921
|
+
}
|
|
922
|
+
}
|
|
923
|
+
return true;
|
|
286
924
|
}
|
|
287
925
|
/**
|
|
288
926
|
* Returns the history of all movements made.
|
|
@@ -297,44 +935,13 @@ var CubeEngine = class {
|
|
|
297
935
|
* Resets the cube to the solved state and clears the move history.
|
|
298
936
|
*/
|
|
299
937
|
reset() {
|
|
300
|
-
this
|
|
301
|
-
UPPER: [
|
|
302
|
-
[COLOR.W[0], COLOR.W[1], COLOR.W[2]],
|
|
303
|
-
[COLOR.W[3], COLOR.W[4], COLOR.W[5]],
|
|
304
|
-
[COLOR.W[6], COLOR.W[7], COLOR.W[8]]
|
|
305
|
-
],
|
|
306
|
-
LEFT: [
|
|
307
|
-
[COLOR.O[0], COLOR.O[1], COLOR.O[2]],
|
|
308
|
-
[COLOR.O[3], COLOR.O[4], COLOR.O[5]],
|
|
309
|
-
[COLOR.O[6], COLOR.O[7], COLOR.O[8]]
|
|
310
|
-
],
|
|
311
|
-
FRONT: [
|
|
312
|
-
[COLOR.G[0], COLOR.G[1], COLOR.G[2]],
|
|
313
|
-
[COLOR.G[3], COLOR.G[4], COLOR.G[5]],
|
|
314
|
-
[COLOR.G[6], COLOR.G[7], COLOR.G[8]]
|
|
315
|
-
],
|
|
316
|
-
RIGHT: [
|
|
317
|
-
[COLOR.R[0], COLOR.R[1], COLOR.R[2]],
|
|
318
|
-
[COLOR.R[3], COLOR.R[4], COLOR.R[5]],
|
|
319
|
-
[COLOR.R[6], COLOR.R[7], COLOR.R[8]]
|
|
320
|
-
],
|
|
321
|
-
BACK: [
|
|
322
|
-
[COLOR.B[0], COLOR.B[1], COLOR.B[2]],
|
|
323
|
-
[COLOR.B[3], COLOR.B[4], COLOR.B[5]],
|
|
324
|
-
[COLOR.B[6], COLOR.B[7], COLOR.B[8]]
|
|
325
|
-
],
|
|
326
|
-
DOWN: [
|
|
327
|
-
[COLOR.Y[0], COLOR.Y[1], COLOR.Y[2]],
|
|
328
|
-
[COLOR.Y[3], COLOR.Y[4], COLOR.Y[5]],
|
|
329
|
-
[COLOR.Y[6], COLOR.Y[7], COLOR.Y[8]]
|
|
330
|
-
]
|
|
331
|
-
};
|
|
938
|
+
__privateMethod(this, _CubeEngine_instances, initializeState_fn).call(this);
|
|
332
939
|
this.MOVES = [];
|
|
333
940
|
}
|
|
334
941
|
/**
|
|
335
942
|
* Applies a sequence of moves provided as a string.
|
|
336
|
-
* Supports: U, D, L, R, F, x, y, z; slice moves: M; and wide moves: Dw, Uw, Rw, Lw with optional ' for counterclockwise and 2 for double turns.
|
|
337
|
-
* @param {string} sequence - e.g. "R U' F R2 D Dw Uw Rw Rw' Lw Lw2 M M' M2"
|
|
943
|
+
* Supports: U, D, L, R, F, B, x, y, z; slice moves: M, E, S; and wide moves: Dw, Uw, Rw, Lw, Fw with optional ' for counterclockwise and 2 for double turns.
|
|
944
|
+
* @param {string} sequence - e.g. "R U' F R2 D Dw Uw Rw Rw' Lw Lw2 M M' M2 E E' S S2 Fw"
|
|
338
945
|
* @param {object} options - { record: boolean } whether to record moves in history (default true)
|
|
339
946
|
*/
|
|
340
947
|
applyMoves(sequence, options = { record: false }) {
|
|
@@ -342,229 +949,51 @@ var CubeEngine = class {
|
|
|
342
949
|
__privateMethod(this, _CubeEngine_instances, applyMovesFromString_fn).call(this, sequence, record);
|
|
343
950
|
}
|
|
344
951
|
};
|
|
952
|
+
_stickers = new WeakMap();
|
|
953
|
+
_perms = new WeakMap();
|
|
345
954
|
_CubeEngine_instances = new WeakSet();
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
const
|
|
351
|
-
const
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
this.STATES.BACK[0] = [...tempLeft];
|
|
356
|
-
this.STATES.RIGHT[0] = [...tempBack];
|
|
357
|
-
} else {
|
|
358
|
-
this.STATES.UPPER = __privateMethod(this, _CubeEngine_instances, switchMatrix_fn).call(this, this.STATES.UPPER, false);
|
|
359
|
-
const tempFront = [...this.STATES.FRONT[0]];
|
|
360
|
-
const tempRight = [...this.STATES.RIGHT[0]];
|
|
361
|
-
const tempLeft = [...this.STATES.LEFT[0]];
|
|
362
|
-
const tempBack = [...this.STATES.BACK[0]];
|
|
363
|
-
this.STATES.FRONT[0] = [...tempLeft];
|
|
364
|
-
this.STATES.LEFT[0] = [...tempBack];
|
|
365
|
-
this.STATES.BACK[0] = [...tempRight];
|
|
366
|
-
this.STATES.RIGHT[0] = [...tempFront];
|
|
367
|
-
}
|
|
368
|
-
};
|
|
369
|
-
rotateF_fn = function(clockwise = true) {
|
|
370
|
-
if (clockwise) {
|
|
371
|
-
__privateMethod(this, _CubeEngine_instances, rotateX_fn).call(this, true);
|
|
372
|
-
__privateMethod(this, _CubeEngine_instances, rotateU_fn).call(this, true);
|
|
373
|
-
__privateMethod(this, _CubeEngine_instances, rotateX_fn).call(this, false);
|
|
374
|
-
} else {
|
|
375
|
-
__privateMethod(this, _CubeEngine_instances, rotateX_fn).call(this, true);
|
|
376
|
-
__privateMethod(this, _CubeEngine_instances, rotateU_fn).call(this, false);
|
|
377
|
-
__privateMethod(this, _CubeEngine_instances, rotateX_fn).call(this, false);
|
|
378
|
-
}
|
|
379
|
-
};
|
|
380
|
-
rotateB_fn = function(clockwise = true) {
|
|
381
|
-
__privateMethod(this, _CubeEngine_instances, rotateY_fn).call(this, true);
|
|
382
|
-
__privateMethod(this, _CubeEngine_instances, rotateY_fn).call(this, true);
|
|
383
|
-
if (clockwise) {
|
|
384
|
-
__privateMethod(this, _CubeEngine_instances, rotateF_fn).call(this, true);
|
|
385
|
-
} else {
|
|
386
|
-
__privateMethod(this, _CubeEngine_instances, rotateF_fn).call(this, false);
|
|
387
|
-
}
|
|
388
|
-
__privateMethod(this, _CubeEngine_instances, rotateY_fn).call(this, false);
|
|
389
|
-
__privateMethod(this, _CubeEngine_instances, rotateY_fn).call(this, false);
|
|
390
|
-
};
|
|
391
|
-
rotateR_fn = function(clockwise = true) {
|
|
392
|
-
if (clockwise) {
|
|
393
|
-
__privateMethod(this, _CubeEngine_instances, rotateY_fn).call(this, true);
|
|
394
|
-
__privateMethod(this, _CubeEngine_instances, rotateX_fn).call(this, true);
|
|
395
|
-
__privateMethod(this, _CubeEngine_instances, rotateU_fn).call(this, true);
|
|
396
|
-
__privateMethod(this, _CubeEngine_instances, rotateX_fn).call(this, false);
|
|
397
|
-
__privateMethod(this, _CubeEngine_instances, rotateY_fn).call(this, false);
|
|
398
|
-
} else {
|
|
399
|
-
__privateMethod(this, _CubeEngine_instances, rotateY_fn).call(this, true);
|
|
400
|
-
__privateMethod(this, _CubeEngine_instances, rotateX_fn).call(this, true);
|
|
401
|
-
__privateMethod(this, _CubeEngine_instances, rotateU_fn).call(this, false);
|
|
402
|
-
__privateMethod(this, _CubeEngine_instances, rotateX_fn).call(this, false);
|
|
403
|
-
__privateMethod(this, _CubeEngine_instances, rotateY_fn).call(this, false);
|
|
404
|
-
}
|
|
405
|
-
};
|
|
406
|
-
rotateL_fn = function(clockwise = true) {
|
|
407
|
-
if (clockwise) {
|
|
408
|
-
__privateMethod(this, _CubeEngine_instances, rotateY_fn).call(this, false);
|
|
409
|
-
__privateMethod(this, _CubeEngine_instances, rotateX_fn).call(this, true);
|
|
410
|
-
__privateMethod(this, _CubeEngine_instances, rotateU_fn).call(this, true);
|
|
411
|
-
__privateMethod(this, _CubeEngine_instances, rotateX_fn).call(this, false);
|
|
412
|
-
__privateMethod(this, _CubeEngine_instances, rotateY_fn).call(this, true);
|
|
413
|
-
} else {
|
|
414
|
-
__privateMethod(this, _CubeEngine_instances, rotateY_fn).call(this, false);
|
|
415
|
-
__privateMethod(this, _CubeEngine_instances, rotateX_fn).call(this, true);
|
|
416
|
-
__privateMethod(this, _CubeEngine_instances, rotateU_fn).call(this, false);
|
|
417
|
-
__privateMethod(this, _CubeEngine_instances, rotateX_fn).call(this, false);
|
|
418
|
-
__privateMethod(this, _CubeEngine_instances, rotateY_fn).call(this, true);
|
|
419
|
-
}
|
|
420
|
-
};
|
|
421
|
-
rotateD_fn = function(clockwise = true) {
|
|
422
|
-
if (clockwise) {
|
|
423
|
-
__privateMethod(this, _CubeEngine_instances, rotateX_fn).call(this, true);
|
|
424
|
-
__privateMethod(this, _CubeEngine_instances, rotateF_fn).call(this, true);
|
|
425
|
-
__privateMethod(this, _CubeEngine_instances, rotateX_fn).call(this, false);
|
|
426
|
-
} else {
|
|
427
|
-
__privateMethod(this, _CubeEngine_instances, rotateX_fn).call(this, true);
|
|
428
|
-
__privateMethod(this, _CubeEngine_instances, rotateF_fn).call(this, false);
|
|
429
|
-
__privateMethod(this, _CubeEngine_instances, rotateX_fn).call(this, false);
|
|
430
|
-
}
|
|
431
|
-
};
|
|
432
|
-
rotateDw_fn = function(clockwise = true) {
|
|
433
|
-
if (clockwise) {
|
|
434
|
-
__privateMethod(this, _CubeEngine_instances, rotateY_fn).call(this, false);
|
|
435
|
-
__privateMethod(this, _CubeEngine_instances, rotateU_fn).call(this, true);
|
|
436
|
-
} else {
|
|
437
|
-
__privateMethod(this, _CubeEngine_instances, rotateY_fn).call(this, true);
|
|
438
|
-
__privateMethod(this, _CubeEngine_instances, rotateU_fn).call(this, false);
|
|
439
|
-
}
|
|
440
|
-
};
|
|
441
|
-
rotateUw_fn = function(clockwise = true) {
|
|
442
|
-
if (clockwise) {
|
|
443
|
-
__privateMethod(this, _CubeEngine_instances, rotateY_fn).call(this, true);
|
|
444
|
-
__privateMethod(this, _CubeEngine_instances, rotateD_fn).call(this, true);
|
|
445
|
-
} else {
|
|
446
|
-
__privateMethod(this, _CubeEngine_instances, rotateY_fn).call(this, false);
|
|
447
|
-
__privateMethod(this, _CubeEngine_instances, rotateD_fn).call(this, false);
|
|
448
|
-
}
|
|
449
|
-
};
|
|
450
|
-
rotateRw_fn = function(clockwise = true) {
|
|
451
|
-
if (clockwise) {
|
|
452
|
-
__privateMethod(this, _CubeEngine_instances, rotateX_fn).call(this, true);
|
|
453
|
-
__privateMethod(this, _CubeEngine_instances, rotateL_fn).call(this, true);
|
|
454
|
-
} else {
|
|
455
|
-
__privateMethod(this, _CubeEngine_instances, rotateX_fn).call(this, false);
|
|
456
|
-
__privateMethod(this, _CubeEngine_instances, rotateL_fn).call(this, false);
|
|
457
|
-
}
|
|
458
|
-
};
|
|
459
|
-
rotateLw_fn = function(clockwise = true) {
|
|
460
|
-
if (clockwise) {
|
|
461
|
-
__privateMethod(this, _CubeEngine_instances, rotateX_fn).call(this, false);
|
|
462
|
-
__privateMethod(this, _CubeEngine_instances, rotateR_fn).call(this, true);
|
|
463
|
-
} else {
|
|
464
|
-
__privateMethod(this, _CubeEngine_instances, rotateX_fn).call(this, true);
|
|
465
|
-
__privateMethod(this, _CubeEngine_instances, rotateR_fn).call(this, false);
|
|
466
|
-
}
|
|
467
|
-
};
|
|
468
|
-
rotateM_fn = function(clockwise = true) {
|
|
469
|
-
if (clockwise) {
|
|
470
|
-
__privateMethod(this, _CubeEngine_instances, rotateLw_fn).call(this, true);
|
|
471
|
-
__privateMethod(this, _CubeEngine_instances, rotateL_fn).call(this, false);
|
|
472
|
-
} else {
|
|
473
|
-
__privateMethod(this, _CubeEngine_instances, rotateLw_fn).call(this, false);
|
|
474
|
-
__privateMethod(this, _CubeEngine_instances, rotateL_fn).call(this, true);
|
|
475
|
-
}
|
|
476
|
-
};
|
|
477
|
-
rotateX_fn = function(clockwise = true) {
|
|
478
|
-
const tempFront = structuredClone(this.STATES.FRONT);
|
|
479
|
-
const tempDown = structuredClone(this.STATES.DOWN);
|
|
480
|
-
const tempUpper = structuredClone(this.STATES.UPPER);
|
|
481
|
-
const tempBack = structuredClone(this.STATES.BACK);
|
|
482
|
-
const tempLeft = structuredClone(this.STATES.LEFT);
|
|
483
|
-
const tempRight = structuredClone(this.STATES.RIGHT);
|
|
484
|
-
if (clockwise) {
|
|
485
|
-
this.STATES.LEFT = __privateMethod(this, _CubeEngine_instances, switchMatrix_fn).call(this, tempLeft, false);
|
|
486
|
-
this.STATES.RIGHT = __privateMethod(this, _CubeEngine_instances, switchMatrix_fn).call(this, tempRight, true);
|
|
487
|
-
this.STATES.FRONT = [...tempDown];
|
|
488
|
-
this.STATES.UPPER = [...tempFront];
|
|
489
|
-
this.STATES.BACK = __privateMethod(this, _CubeEngine_instances, specialFlip_fn).call(this, tempUpper);
|
|
490
|
-
this.STATES.DOWN = __privateMethod(this, _CubeEngine_instances, specialFlip_fn).call(this, tempBack);
|
|
491
|
-
} else {
|
|
492
|
-
this.STATES.LEFT = __privateMethod(this, _CubeEngine_instances, switchMatrix_fn).call(this, tempLeft, true);
|
|
493
|
-
this.STATES.RIGHT = __privateMethod(this, _CubeEngine_instances, switchMatrix_fn).call(this, tempRight, false);
|
|
494
|
-
this.STATES.FRONT = [...tempUpper];
|
|
495
|
-
this.STATES.DOWN = [...tempFront];
|
|
496
|
-
this.STATES.BACK = __privateMethod(this, _CubeEngine_instances, specialFlip_fn).call(this, tempDown);
|
|
497
|
-
this.STATES.UPPER = __privateMethod(this, _CubeEngine_instances, specialFlip_fn).call(this, tempBack);
|
|
955
|
+
initializeState_fn = function() {
|
|
956
|
+
const per = this.size * this.size;
|
|
957
|
+
const stickers = new Array(FACE_COLORS.length * per);
|
|
958
|
+
for (let f = 0; f < FACE_COLORS.length; f++) {
|
|
959
|
+
const color = FACE_COLORS[f];
|
|
960
|
+
const base = f * per;
|
|
961
|
+
for (let i = 0; i < per; i++) {
|
|
962
|
+
stickers[base + i] = color;
|
|
963
|
+
}
|
|
498
964
|
}
|
|
965
|
+
__privateSet(this, _stickers, stickers);
|
|
499
966
|
};
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
const
|
|
503
|
-
const
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
const tempBack = structuredClone(this.STATES.BACK);
|
|
507
|
-
if (clockwise) {
|
|
508
|
-
this.STATES.FRONT = __privateMethod(this, _CubeEngine_instances, switchMatrix_fn).call(this, tempFront, true);
|
|
509
|
-
this.STATES.BACK = __privateMethod(this, _CubeEngine_instances, switchMatrix_fn).call(this, tempBack, false);
|
|
510
|
-
this.STATES.RIGHT = __privateMethod(this, _CubeEngine_instances, switchMatrix_fn).call(this, tempUpper, true);
|
|
511
|
-
this.STATES.DOWN = __privateMethod(this, _CubeEngine_instances, switchMatrix_fn).call(this, tempRight, true);
|
|
512
|
-
this.STATES.LEFT = __privateMethod(this, _CubeEngine_instances, switchMatrix_fn).call(this, tempDown, true);
|
|
513
|
-
this.STATES.UPPER = __privateMethod(this, _CubeEngine_instances, switchMatrix_fn).call(this, tempLeft, true);
|
|
514
|
-
} else {
|
|
515
|
-
this.STATES.FRONT = __privateMethod(this, _CubeEngine_instances, switchMatrix_fn).call(this, tempFront, false);
|
|
516
|
-
this.STATES.BACK = __privateMethod(this, _CubeEngine_instances, switchMatrix_fn).call(this, tempBack, true);
|
|
517
|
-
this.STATES.RIGHT = __privateMethod(this, _CubeEngine_instances, switchMatrix_fn).call(this, tempDown, false);
|
|
518
|
-
this.STATES.DOWN = __privateMethod(this, _CubeEngine_instances, switchMatrix_fn).call(this, tempLeft, false);
|
|
519
|
-
this.STATES.LEFT = __privateMethod(this, _CubeEngine_instances, switchMatrix_fn).call(this, tempUpper, false);
|
|
520
|
-
this.STATES.UPPER = __privateMethod(this, _CubeEngine_instances, switchMatrix_fn).call(this, tempRight, false);
|
|
967
|
+
// Apply a precomputed permutation: newState[i] = oldState[perm[i]].
|
|
968
|
+
applyPerm_fn = function(perm) {
|
|
969
|
+
const current = __privateGet(this, _stickers);
|
|
970
|
+
const next = new Array(current.length);
|
|
971
|
+
for (let i = 0; i < current.length; i++) {
|
|
972
|
+
next[i] = current[perm[i]];
|
|
521
973
|
}
|
|
974
|
+
__privateSet(this, _stickers, next);
|
|
522
975
|
};
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
if (clockwise) {
|
|
529
|
-
this.STATES.UPPER = __privateMethod(this, _CubeEngine_instances, switchMatrix_fn).call(this, this.STATES.UPPER, true);
|
|
530
|
-
this.STATES.DOWN = __privateMethod(this, _CubeEngine_instances, switchMatrix_fn).call(this, this.STATES.DOWN, false);
|
|
531
|
-
this.STATES.FRONT = [...tempRight];
|
|
532
|
-
this.STATES.RIGHT = [...tempBack];
|
|
533
|
-
this.STATES.LEFT = [...tempFront];
|
|
534
|
-
this.STATES.BACK = [...tempLeft];
|
|
535
|
-
} else {
|
|
536
|
-
this.STATES.UPPER = __privateMethod(this, _CubeEngine_instances, switchMatrix_fn).call(this, this.STATES.UPPER, false);
|
|
537
|
-
this.STATES.DOWN = __privateMethod(this, _CubeEngine_instances, switchMatrix_fn).call(this, this.STATES.DOWN, true);
|
|
538
|
-
this.STATES.FRONT = [...tempLeft];
|
|
539
|
-
this.STATES.RIGHT = [...tempFront];
|
|
540
|
-
this.STATES.LEFT = [...tempBack];
|
|
541
|
-
this.STATES.BACK = [...tempRight];
|
|
542
|
-
}
|
|
976
|
+
// Core move dispatch. dir is "cw" or "ccw"; record controls history logging.
|
|
977
|
+
apply_fn = function(key, dir, record) {
|
|
978
|
+
if (this.size === 2 && NOOP_SIZE2.has(key)) return;
|
|
979
|
+
__privateMethod(this, _CubeEngine_instances, applyPerm_fn).call(this, __privateGet(this, _perms)[key][dir]);
|
|
980
|
+
if (record) this.MOVES.push(dir === "ccw" ? key + "'" : key);
|
|
543
981
|
};
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
const
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
];
|
|
556
|
-
} else {
|
|
557
|
-
return [
|
|
558
|
-
[tempMatrix[2], tempMatrix[5], tempMatrix[8]],
|
|
559
|
-
[tempMatrix[1], tempMatrix[4], tempMatrix[7]],
|
|
560
|
-
[tempMatrix[0], tempMatrix[3], tempMatrix[6]]
|
|
561
|
-
];
|
|
982
|
+
// Build a single face matrix from the flat sticker array.
|
|
983
|
+
faceMatrix_fn = function(faceIndex) {
|
|
984
|
+
const size = this.size;
|
|
985
|
+
const base = faceIndex * size * size;
|
|
986
|
+
const matrix = [];
|
|
987
|
+
for (let r = 0; r < size; r++) {
|
|
988
|
+
const row = [];
|
|
989
|
+
for (let c = 0; c < size; c++) {
|
|
990
|
+
row.push(__privateGet(this, _stickers)[base + r * size + c]);
|
|
991
|
+
}
|
|
992
|
+
matrix.push(row);
|
|
562
993
|
}
|
|
994
|
+
return matrix;
|
|
563
995
|
};
|
|
564
|
-
|
|
565
|
-
return structuredClone(matrix).reverse().map((row) => [...row].reverse());
|
|
566
|
-
};
|
|
567
|
-
// Internal: parses and applies moves. If record=false, uses private methods to avoid logging.
|
|
996
|
+
// Internal: parses and applies moves, optionally recording them in history.
|
|
568
997
|
applyMovesFromString_fn = function(sequence, record = true) {
|
|
569
998
|
if (typeof sequence !== "string") return;
|
|
570
999
|
const tokens = sequence.split(/\s+/).map((t) => t.trim()).filter((t) => t.length > 0);
|
|
@@ -573,122 +1002,55 @@ applyMovesFromString_fn = function(sequence, record = true) {
|
|
|
573
1002
|
const rest = token.slice(1);
|
|
574
1003
|
const isDouble = rest.includes("2");
|
|
575
1004
|
const isPrime = rest.includes("'");
|
|
576
|
-
const
|
|
577
|
-
|
|
578
|
-
if (isDouble) {
|
|
579
|
-
fnClockwise();
|
|
580
|
-
fnClockwise();
|
|
581
|
-
} else {
|
|
582
|
-
if (isPrime) {
|
|
583
|
-
fnCounter();
|
|
584
|
-
} else {
|
|
585
|
-
fnClockwise();
|
|
586
|
-
}
|
|
587
|
-
}
|
|
588
|
-
};
|
|
1005
|
+
const isWide = /w/i.test(rest);
|
|
1006
|
+
let key;
|
|
589
1007
|
switch (base) {
|
|
590
1008
|
case "U":
|
|
591
|
-
|
|
592
|
-
const isWide = /w/i.test(rest);
|
|
593
|
-
if (isWide) {
|
|
594
|
-
exec(
|
|
595
|
-
() => record ? this.rotateUw(true) : __privateMethod(this, _CubeEngine_instances, rotateUw_fn).call(this, true),
|
|
596
|
-
() => record ? this.rotateUw(false) : __privateMethod(this, _CubeEngine_instances, rotateUw_fn).call(this, false)
|
|
597
|
-
);
|
|
598
|
-
} else {
|
|
599
|
-
exec(
|
|
600
|
-
() => record ? this.rotateU(true) : __privateMethod(this, _CubeEngine_instances, rotateU_fn).call(this, true),
|
|
601
|
-
() => record ? this.rotateU(false) : __privateMethod(this, _CubeEngine_instances, rotateU_fn).call(this, false)
|
|
602
|
-
);
|
|
603
|
-
}
|
|
604
|
-
}
|
|
1009
|
+
key = isWide ? "Uw" : "U";
|
|
605
1010
|
break;
|
|
606
1011
|
case "D":
|
|
607
|
-
|
|
608
|
-
const isWide = /w/i.test(rest);
|
|
609
|
-
if (isWide) {
|
|
610
|
-
exec(
|
|
611
|
-
() => record ? this.rotateDw(true) : __privateMethod(this, _CubeEngine_instances, rotateDw_fn).call(this, true),
|
|
612
|
-
() => record ? this.rotateDw(false) : __privateMethod(this, _CubeEngine_instances, rotateDw_fn).call(this, false)
|
|
613
|
-
);
|
|
614
|
-
} else {
|
|
615
|
-
exec(
|
|
616
|
-
() => record ? this.rotateD(true) : __privateMethod(this, _CubeEngine_instances, rotateD_fn).call(this, true),
|
|
617
|
-
() => record ? this.rotateD(false) : __privateMethod(this, _CubeEngine_instances, rotateD_fn).call(this, false)
|
|
618
|
-
);
|
|
619
|
-
}
|
|
620
|
-
}
|
|
1012
|
+
key = isWide ? "Dw" : "D";
|
|
621
1013
|
break;
|
|
622
1014
|
case "L":
|
|
623
|
-
|
|
624
|
-
const isWide = /w/i.test(rest);
|
|
625
|
-
if (isWide) {
|
|
626
|
-
exec(
|
|
627
|
-
() => record ? this.rotateLw(true) : __privateMethod(this, _CubeEngine_instances, rotateLw_fn).call(this, true),
|
|
628
|
-
() => record ? this.rotateLw(false) : __privateMethod(this, _CubeEngine_instances, rotateLw_fn).call(this, false)
|
|
629
|
-
);
|
|
630
|
-
} else {
|
|
631
|
-
exec(
|
|
632
|
-
() => record ? this.rotateL(true) : __privateMethod(this, _CubeEngine_instances, rotateL_fn).call(this, true),
|
|
633
|
-
() => record ? this.rotateL(false) : __privateMethod(this, _CubeEngine_instances, rotateL_fn).call(this, false)
|
|
634
|
-
);
|
|
635
|
-
}
|
|
636
|
-
}
|
|
1015
|
+
key = isWide ? "Lw" : "L";
|
|
637
1016
|
break;
|
|
638
1017
|
case "R":
|
|
639
|
-
|
|
640
|
-
const isWide = /w/i.test(rest);
|
|
641
|
-
if (isWide) {
|
|
642
|
-
exec(
|
|
643
|
-
() => record ? this.rotateRw(true) : __privateMethod(this, _CubeEngine_instances, rotateRw_fn).call(this, true),
|
|
644
|
-
() => record ? this.rotateRw(false) : __privateMethod(this, _CubeEngine_instances, rotateRw_fn).call(this, false)
|
|
645
|
-
);
|
|
646
|
-
} else {
|
|
647
|
-
exec(
|
|
648
|
-
() => record ? this.rotateR(true) : __privateMethod(this, _CubeEngine_instances, rotateR_fn).call(this, true),
|
|
649
|
-
() => record ? this.rotateR(false) : __privateMethod(this, _CubeEngine_instances, rotateR_fn).call(this, false)
|
|
650
|
-
);
|
|
651
|
-
}
|
|
652
|
-
}
|
|
1018
|
+
key = isWide ? "Rw" : "R";
|
|
653
1019
|
break;
|
|
654
1020
|
case "F":
|
|
655
|
-
|
|
656
|
-
() => record ? this.rotateF(true) : __privateMethod(this, _CubeEngine_instances, rotateF_fn).call(this, true),
|
|
657
|
-
() => record ? this.rotateF(false) : __privateMethod(this, _CubeEngine_instances, rotateF_fn).call(this, false)
|
|
658
|
-
);
|
|
1021
|
+
key = isWide ? "Fw" : "F";
|
|
659
1022
|
break;
|
|
660
1023
|
case "B":
|
|
661
|
-
|
|
662
|
-
() => record ? this.rotateB(true) : __privateMethod(this, _CubeEngine_instances, rotateB_fn).call(this, true),
|
|
663
|
-
() => record ? this.rotateB(false) : __privateMethod(this, _CubeEngine_instances, rotateB_fn).call(this, false)
|
|
664
|
-
);
|
|
1024
|
+
key = "B";
|
|
665
1025
|
break;
|
|
666
1026
|
case "x":
|
|
667
|
-
|
|
668
|
-
() => record ? this.rotateX(true) : __privateMethod(this, _CubeEngine_instances, rotateX_fn).call(this, true),
|
|
669
|
-
() => record ? this.rotateX(false) : __privateMethod(this, _CubeEngine_instances, rotateX_fn).call(this, false)
|
|
670
|
-
);
|
|
1027
|
+
key = "x";
|
|
671
1028
|
break;
|
|
672
1029
|
case "y":
|
|
673
|
-
|
|
674
|
-
() => record ? this.rotateY(true) : __privateMethod(this, _CubeEngine_instances, rotateY_fn).call(this, true),
|
|
675
|
-
() => record ? this.rotateY(false) : __privateMethod(this, _CubeEngine_instances, rotateY_fn).call(this, false)
|
|
676
|
-
);
|
|
1030
|
+
key = "y";
|
|
677
1031
|
break;
|
|
678
1032
|
case "z":
|
|
679
|
-
|
|
680
|
-
() => record ? this.rotateZ(true) : __privateMethod(this, _CubeEngine_instances, rotateZ_fn).call(this, true),
|
|
681
|
-
() => record ? this.rotateZ(false) : __privateMethod(this, _CubeEngine_instances, rotateZ_fn).call(this, false)
|
|
682
|
-
);
|
|
1033
|
+
key = "z";
|
|
683
1034
|
break;
|
|
684
1035
|
case "M":
|
|
685
|
-
|
|
686
|
-
() => record ? this.rotateM(true) : __privateMethod(this, _CubeEngine_instances, rotateM_fn).call(this, true),
|
|
687
|
-
() => record ? this.rotateM(false) : __privateMethod(this, _CubeEngine_instances, rotateM_fn).call(this, false)
|
|
688
|
-
);
|
|
1036
|
+
key = "M";
|
|
689
1037
|
break;
|
|
690
|
-
|
|
1038
|
+
case "E":
|
|
1039
|
+
key = "E";
|
|
1040
|
+
break;
|
|
1041
|
+
case "S":
|
|
1042
|
+
key = "S";
|
|
691
1043
|
break;
|
|
1044
|
+
default:
|
|
1045
|
+
continue;
|
|
1046
|
+
}
|
|
1047
|
+
if (isDouble) {
|
|
1048
|
+
__privateMethod(this, _CubeEngine_instances, apply_fn).call(this, key, "cw", record);
|
|
1049
|
+
__privateMethod(this, _CubeEngine_instances, apply_fn).call(this, key, "cw", record);
|
|
1050
|
+
} else if (isPrime) {
|
|
1051
|
+
__privateMethod(this, _CubeEngine_instances, apply_fn).call(this, key, "ccw", record);
|
|
1052
|
+
} else {
|
|
1053
|
+
__privateMethod(this, _CubeEngine_instances, apply_fn).call(this, key, "cw", record);
|
|
692
1054
|
}
|
|
693
1055
|
}
|
|
694
1056
|
};
|
|
@@ -703,5 +1065,9 @@ var COLOR = {
|
|
|
703
1065
|
// Annotate the CommonJS export names for ESM import in node:
|
|
704
1066
|
0 && (module.exports = {
|
|
705
1067
|
COLOR,
|
|
706
|
-
CubeEngine
|
|
1068
|
+
CubeEngine,
|
|
1069
|
+
analyzeSolution,
|
|
1070
|
+
getMovePermutations,
|
|
1071
|
+
invertSequence,
|
|
1072
|
+
simplifyMoves
|
|
707
1073
|
});
|