/**
* Copyright (C) 2023 Shuang Chen
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see .
-----------------------------------------------------------------------
Modified by Isaac Vega
*/
import { getEasyXCross } from "../lib/cross";
import {
getNPerm,
setNPerm,
set8Perm,
getNParity,
rn,
rndEl,
valuedArray,
idxArray,
setNOri,
getNOri,
} from "../lib/mathlib";
import { Search } from "../lib/min2phase";
import { getEasyCross } from "../tools/cross";
import { fixCase, regScrambler } from "./scramble";
function between(n: number, a: number, b: number): number {
const na = Math.min(a, b);
const nb = Math.max(a, b);
return Math.min(nb, Math.max(na, n));
}
const Ux1 = 0;
const Ux2 = 1;
const Ux3 = 2;
const Rx1 = 3;
const Rx2 = 4;
const Rx3 = 5;
const Fx1 = 6;
const Fx2 = 7;
const Fx3 = 8;
const Dx1 = 9;
const Dx2 = 10;
const Dx3 = 11;
const Lx1 = 12;
const Lx2 = 13;
const Lx3 = 14;
const Bx1 = 15;
const Bx2 = 16;
const Bx3 = 17;
function $setFlip(obj: CubieCube1, idx: number) {
let i, parity;
parity = 0;
for (i = 10; i >= 0; --i) {
parity ^= obj.eo[i] = idx & 1;
idx >>= 1;
}
obj.eo[11] = parity;
}
function $setTwist(obj: CubieCube1, idx: number) {
let i, twst;
twst = 0;
for (i = 6; i >= 0; --i) {
twst += obj.co[i] = idx % 3;
idx = ~~(idx / 3);
}
obj.co[7] = (15 - twst) % 3;
}
function CornMult(a: CubieCube1, b: CubieCube1, prod: CubieCube1) {
let corn, ori, oriA, oriB;
for (corn = 0; corn < 8; ++corn) {
prod.cp[corn] = a.cp[b.cp[corn]];
oriA = a.co[b.cp[corn]];
oriB = b.co[corn];
ori = oriA;
ori += oriA < 3 ? oriB : 6 - oriB;
ori %= 3;
oriA >= 3 !== oriB >= 3 && (ori += 3);
prod.co[corn] = ori;
}
}
class CubieCube {
cp: number[];
co: number[];
ep: number[];
eo: number[];
constructor() {
this.cp = [0, 1, 2, 3, 4, 5, 6, 7];
this.co = [0, 0, 0, 0, 0, 0, 0, 0];
this.ep = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11];
this.eo = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
}
}
class CubieCube1 {
cp: number[];
co: number[];
ep: number[];
eo: number[];
constructor(cperm: number, twist: number, eperm: number, flip: number) {
this.cp = [0, 1, 2, 3, 4, 5, 6, 7];
this.co = [0, 0, 0, 0, 0, 0, 0, 0];
this.ep = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11];
this.eo = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
set8Perm(this.cp, cperm);
$setTwist(this, twist);
setNPerm(this.ep, eperm, 12);
$setFlip(this, flip);
}
}
function EdgeMult(a: CubieCube1, b: CubieCube1, prod: CubieCube1) {
let ed;
for (ed = 0; ed < 12; ++ed) {
prod.ep[ed] = a.ep[b.ep[ed]];
prod.eo[ed] = b.eo[ed] ^ a.eo[b.ep[ed]];
}
}
let ret = false;
function initMove() {
if (ret) {
return;
}
ret = true;
let a, p;
moveCube[0] = new CubieCube1(15120, 0, 119750400, 0);
moveCube[3] = new CubieCube1(21021, 1494, 323403417, 0);
moveCube[6] = new CubieCube1(8064, 1236, 29441808, 550);
moveCube[9] = new CubieCube1(9, 0, 5880, 0);
moveCube[12] = new CubieCube1(1230, 412, 2949660, 0);
moveCube[15] = new CubieCube1(224, 137, 328552, 137);
for (a = 0; a < 18; a += 3) {
for (p = 0; p < 2; ++p) {
moveCube[a + p + 1] = new CubieCube();
EdgeMult(moveCube[a + p], moveCube[a], moveCube[a + p + 1]);
CornMult(moveCube[a + p], moveCube[a], moveCube[a + p + 1]);
}
}
}
const moveCube: CubieCube[] = [];
const cornerFacelet = [
[8, 9, 20],
[6, 18, 38],
[0, 36, 47],
[2, 45, 11],
[29, 26, 15],
[27, 44, 24],
[33, 53, 42],
[35, 17, 51],
];
const edgeFacelet = [
[5, 10],
[7, 19],
[3, 37],
[1, 46],
[32, 16],
[28, 25],
[30, 43],
[34, 52],
[23, 12],
[21, 41],
[50, 39],
[48, 14],
];
function toFaceCube(cc: CubieCube1) {
let c, e, f, i, j, n, ori, ts;
f = [];
ts = [85, 82, 70, 68, 76, 66];
for (i = 0; i < 54; ++i) {
f[i] = ts[~~(i / 9)];
}
for (c = 0; c < 8; ++c) {
j = cc.cp[c];
ori = cc.co[c];
for (n = 0; n < 3; ++n)
f[cornerFacelet[c][(n + ori) % 3]] = ts[~~(cornerFacelet[j][n] / 9)];
}
for (e = 0; e < 12; ++e) {
j = cc.ep[e];
ori = cc.eo[e];
for (n = 0; n < 2; ++n)
f[edgeFacelet[e][(n + ori) % 2]] = ts[~~(edgeFacelet[j][n] / 9)];
}
return String.fromCharCode.apply(null, f);
}
// SCRAMBLERS
// @ts-ignore
const search = new Search();
export function getRandomScramble() {
return getAnyScramble(0xffffffffffff, 0xffffffffffff, 0xffffffff, 0xffffffff);
}
export function getFMCScramble() {
let scramble = "",
axis1,
axis2,
axisl1,
axisl2;
do {
scramble = getRandomScramble();
const moveseq = scramble.split(" ");
if (moveseq.length < 3) {
continue;
}
axis1 = moveseq[0][0];
axis2 = moveseq[1][0];
axisl1 = moveseq[moveseq.length - 2][0];
axisl2 = moveseq[moveseq.length - 3][0];
} while (
axis1 == "F" ||
(axis1 == "B" && axis2 == "F") ||
axisl1 == "R" ||
(axisl1 == "L" && axisl2 == "R")
);
return "R' U' F " + scramble + "R' U' F";
}
function cntU(b: any) {
let c, a;
for (c = 0, a = 0; a < b.length; a++) -1 == b[a] && c++;
return c;
}
function fixOri(arr: number[], cntU: number, base: number) {
let sum = 0;
let idx = 0;
for (let i = 0; i < arr.length; i++) {
if (arr[i] != -1) {
sum += arr[i];
}
}
sum %= base;
for (let i = 0; i < arr.length - 1; i++) {
if (arr[i] == -1) {
if (cntU-- == 1) {
arr[i] = ((base << 4) - sum) % base;
} else {
arr[i] = rn(base);
sum += arr[i];
}
}
idx *= base;
idx += arr[i];
}
return idx;
}
function fixPerm(arr: number[], cntU: number, parity: number) {
const val = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11];
for (let i = 0; i < arr.length; i++) {
if (arr[i] != -1) {
val[arr[i]] = -1;
}
}
for (let i = 0, j = 0; i < val.length; i++) {
if (val[i] != -1) {
val[j++] = val[i];
}
}
let last: number = 0;
let i;
for (i = 0; i < arr.length && cntU > 0; i++) {
if (arr[i] == -1) {
const r = rn(cntU);
arr[i] = val[r];
for (let j = r; j < 11; j++) {
val[j] = val[j + 1];
}
if (cntU-- == 2) {
last = i;
}
}
}
if (getNParity(getNPerm(arr, arr.length), arr.length) == 1 - parity) {
const temp = arr[i - 1];
arr[i - 1] = arr[last];
arr[last] = temp;
}
return getNPerm(arr, arr.length);
}
//arr: 53 bit integer
function parseMask(arr: any, length: number) {
if ("number" !== typeof arr) {
return arr;
}
const ret = [];
for (let i = 0; i < length; i++) {
const val = arr & 0xf; // should use "/" instead of ">>" to avoid unexpected type conversion
ret[i] = val == 15 ? -1 : val;
arr /= 16;
}
return ret;
}
const aufsuff = [[], [Ux1], [Ux2], [Ux3]];
const rlpresuff = [[], [Rx1, Lx3], [Rx2, Lx2], [Rx3, Lx1]];
const rlappsuff = ["", "x'", "x2", "x"];
const emptysuff = [[]];
function getAnyScramble(
_ep: any,
_eo: any,
_cp: number,
_co: number,
_rndapp?: any,
_rndpre?: any,
) {
initMove();
_rndapp = _rndapp || emptysuff;
_rndpre = _rndpre || emptysuff;
const $_ep = parseMask(_ep, 12);
const $_eo = parseMask(_eo, 12);
const $_cp = parseMask(_cp, 8);
const $_co = parseMask(_co, 8);
let solution = "";
do {
const eo = $_eo.slice();
const ep = $_ep.slice();
const co = $_co.slice();
const cp = $_cp.slice();
const neo = fixOri(eo, cntU(eo), 2);
const nco = fixOri(co, cntU(co), 3);
let nep, ncp;
const ue = cntU(ep);
const uc = cntU(cp);
if (ue == 0 && uc == 0) {
nep = getNPerm(ep, 12);
ncp = getNPerm(cp, 8);
} else if (ue != 0 && uc == 0) {
ncp = getNPerm(cp, 8);
nep = fixPerm(ep, ue, getNParity(ncp, 8));
} else if (ue == 0 && uc != 0) {
nep = getNPerm(ep, 12);
ncp = fixPerm(cp, uc, getNParity(nep, 12));
} else {
nep = fixPerm(ep, ue, -1);
ncp = fixPerm(cp, uc, getNParity(nep, 12));
}
if (ncp + nco + nep + neo == 0) {
continue;
}
let cc = new CubieCube1(ncp, nco, nep, neo);
let cc2 = new CubieCube();
const rndpre = rndEl(_rndpre);
const rndapp = rndEl(_rndapp);
for (let i = 0; i < rndpre.length; i++) {
CornMult(moveCube[rndpre[i]], cc, cc2);
EdgeMult(moveCube[rndpre[i]], cc, cc2);
const tmp = cc2;
cc2 = cc;
cc = tmp;
}
for (let i = 0; i < rndapp.length; i++) {
CornMult(cc, moveCube[rndapp[i]], cc2);
EdgeMult(cc, moveCube[rndapp[i]], cc2);
const tmp = cc2;
cc2 = cc;
cc = tmp;
}
const posit = toFaceCube(cc);
// @ts-ignore
const search0 = new Search();
solution = search0.solution(posit, 21, 1e9, 50, 2);
} while (solution.length <= 3);
return solution.replace(/ +/g, " ");
}
export function getEdgeScramble() {
return getAnyScramble(0xffffffffffff, 0xffffffffffff, 0x76543210, 0x00000000);
}
export function getCornerScramble() {
return getAnyScramble(0xba9876543210, 0x000000000000, 0xffffffff, 0xffffffff);
}
export function getLLScramble() {
return getAnyScramble(0xba987654ffff, 0x00000000ffff, 0x7654ffff, 0x0000ffff);
}
export const f2l_map = [
[0x2000, 4, "Easy-01"],
[0x1011, 4, "Easy-02"],
[0x2012, 4, "Easy-03"],
[0x1003, 4, "Easy-04"],
[0x2003, 4, "RE-05"],
[0x1012, 4, "RE-06"],
[0x2002, 4, "RE-07"],
[0x1013, 4, "RE-08"],
[0x2013, 4, "REFC-09"],
[0x1002, 4, "REFC-10"],
[0x2010, 4, "REFC-11"],
[0x1001, 4, "REFC-12"],
[0x2011, 4, "REFC-13"],
[0x1000, 4, "REFC-14"],
[0x2001, 4, "SPGO-15"],
[0x1010, 4, "SPGO-16"],
[0x0000, 4, "SPGO-17"],
[0x0011, 4, "SPGO-18"],
[0x0003, 4, "PMS-19"],
[0x0012, 4, "PMS-20"],
[0x0002, 4, "PMS-21"],
[0x0013, 4, "PMS-22"],
[0x0001, 4, "Weird-23"],
[0x0010, 4, "Weird-24"],
[0x0400, 4, "CPEU-25"],
[0x0411, 4, "CPEU-26"],
[0x1400, 4, "CPEU-27"],
[0x2411, 4, "CPEU-28"],
[0x1411, 4, "CPEU-29"],
[0x2400, 4, "CPEU-30"],
[0x0018, 4, "EPCU-31"],
[0x0008, 4, "EPCU-32"],
[0x2008, 4, "EPCU-33"],
[0x1008, 4, "EPCU-34"],
[0x2018, 4, "EPCU-35"],
[0x1018, 4, "EPCU-36"],
[0x0418, 1, "ECP-37"],
[0x1408, 1, "ECP-38"],
[0x2408, 1, "ECP-39"],
[0x1418, 1, "ECP-40"],
[0x2418, 1, "ECP-41"],
[0x0408, 1, "Solved-42"],
] as const;
const f2lprobs = idxArray(f2l_map, 1);
export const f2lfilter = idxArray(f2l_map, 2);
export function getLSLLScramble(type: any, length: any, cases: any) {
const caze = f2l_map[fixCase(cases, f2lprobs)][0];
const ep = Math.pow(16, caze & 0xf);
const eo = 0xf ^ ((caze >> 4) & 1);
const cp = Math.pow(16, (caze >> 8) & 0xf);
const co = 0xf ^ ((caze >> 12) & 3);
return getAnyScramble(
0xba9f7654ffff - 7 * ep,
0x000f0000ffff - eo * ep,
0x765fffff - 0xb * cp,
0x000fffff - co * cp,
);
}
const crossProbs = [
[0xffffffff3210, 0xffffffff0000],
[0xbff8fff4fff0, 0x0ff0fff0fff0],
[0xff98ff5fff1f, 0xff00ff0fff0f],
[0xffff7654ffff, 0xffff0000ffff],
[0xfa9ff6fff2ff, 0xf00ff0fff0ff],
[0xbaff7fff3fff, 0x00ff0fff0fff],
];
const crossFilter = ["U", "R", "F", "D", "L", "B"];
export function getF2LScramble(_type: any, _length: any, prob: any) {
/*
0xabcdefghijkl
a = BR b = BL c = FL d = FR
e = DB f = DL g = DF h = DR
i = UB j = UL k = UF l = UR
*/
const p = between(prob || 0, 0, crossProbs.length - 1);
let _prob = crossProbs[p];
if (typeof prob != "number" || prob < 0 || prob >= crossProbs.length) {
_prob = rndEl(crossProbs);
}
return getAnyScramble(_prob[0], _prob[1], 0xffffffff, 0xffffffff);
}
function genZBLLMap() {
let isVisited: number[] = [];
let zbll_map = [];
let cc = new CubieCube();
for (let idx = 0; idx < 27 * 24 * 24; idx++) {
if ((isVisited[idx >> 5] >> (idx & 0x1f)) & 1) {
continue;
}
let epi = idx % 24;
let cpi = ~~(idx / 24) % 24;
let coi = ~~(idx / 24 / 24);
if (getNParity(cpi, 4) != getNParity(epi, 4)) {
continue;
}
let co = setNOri(cc.co, coi, 4, -3);
let cp = setNPerm(cc.cp, cpi, 4, 0);
let ep = setNPerm(cc.ep, epi, 4, 0);
let zbcase: any[] = [0, 0, 0, 0, null];
for (let i = 0; i < 4; i++) {
zbcase[0] += cp[i] << (i * 4);
zbcase[1] += co[i] << (i * 4);
zbcase[2] += ep[i] << (i * 4);
}
for (let conj = 0; conj < 16; conj++) {
let c0 = conj >> 2;
let c1 = conj & 3;
let co2 = [],
cp2 = [],
ep2 = [];
for (let i = 0; i < 4; i++) {
co2[(i + c0) & 3] = co[i];
cp2[(i + c0) & 3] = (cp[i] + c1) & 3;
ep2[(i + c0) & 3] = (ep[i] + c1) & 3;
}
let co2i = getNOri(co2, 4, -3);
let cp2i = getNPerm(cp2, 4, 0);
let ep2i = getNPerm(ep2, 4, 0);
let idx2 = (co2i * 24 + cp2i) * 24 + ep2i;
if ((isVisited[idx2 >> 5] >> (idx2 & 0x1f)) & 1) {
continue;
}
isVisited[idx2 >> 5] |= 1 << (idx2 & 0x1f);
zbcase[3]++;
}
if (idx > 0) {
// skip solved state
zbll_map.push(zbcase);
}
}
let coNames: Record = {};
coNames[0x0000] = "O";
coNames[0x0012] = "U";
coNames[0x0021] = "T";
coNames[0x0102] = "L";
coNames[0x0111] = "aS";
coNames[0x0222] = "S";
coNames[0x1122] = "Pi";
coNames[0x1212] = "H";
let coCnts: Record = {};
for (let i = 0; i < zbll_map.length; i++) {
let zbcase = zbll_map[i];
let coName = coNames[zbcase[1]];
coCnts[coName] = coCnts[coName] || [];
let coCnt = coCnts[coName];
let cpIdx = coCnt.indexOf(zbcase[0]);
if (cpIdx == -1) {
cpIdx = coCnt.length;
coCnt.push(zbcase[0], 1);
} else {
coCnt[cpIdx + 1]++;
}
zbcase[4] = coName + ((cpIdx >> 1) + 1) + "-" + coCnts[coName][cpIdx + 1];
}
return zbll_map;
}
const zbll_map = genZBLLMap();
const zbprobs = idxArray(zbll_map, 3);
const zbfilter = idxArray(zbll_map, 4);
const coll_map: any[] = [
[0x3210, 0x1101, "LeFeeeDeRRGFDGLDGBDGB", 4, "aS-1"],
[0x2301, 0x1110, "ReFeeeDeLRGBDGLDGFDGB", 4, "aS-2"],
[0x3021, 0x1101, "LeBeeeDeFFGLDGRDGBDGR", 4, "aS-3"],
[0x2013, 0x1011, "LeFeeeDeBFGRDGLDGBDGR", 4, "aS-4"],
[0x1203, 0x1011, "FeBeeeDeLFGBDGRDGLDGR", 4, "aS-5"],
[0x3102, 0x1101, "FeBeeeDeRBGFDGRDGLDGL", 4, "aS-6"],
[0x3210, 0x2121, "FeFeeeBeBLGRDGDRGLDGD", 2, "H-1"],
[0x2301, 0x1212, "ReLeeeReLBGBDGDFGFDGD", 2, "H-2"],
[0x1203, 0x1212, "ReBeeeLeBFGRDGDLGFDGD", 4, "H-3"],
[0x2013, 0x1212, "LeReeeFeFRGLDGDBGBDGD", 4, "H-4"],
[0x3021, 0x1020, "DeLeeeReDBGRFGBDGFLGD", 4, "L-1"],
[0x1203, 0x0201, "DeReeeLeDFDBRDFDGLBGD", 4, "L-2"],
[0x2301, 0x0102, "DeBeeeLeDFGRFGRDGLBGD", 4, "L-3"],
[0x3210, 0x1020, "DeLeeeFeDRGFLGBDGBRGD", 4, "L-4"],
[0x3102, 0x1020, "DeLeeeLeDFGBRGBDGRFGD", 4, "L-5"],
[0x2013, 0x0201, "DeReeeReDBGLBGFDGFLGD", 4, "L-6"],
[0x3210, 0x1122, "LeFeeeReFBGDRGLDGBDGD", 4, "Pi-1"],
[0x2301, 0x2112, "FeLeeeFeRRGDBGBDGLDGD", 4, "Pi-2"],
[0x1203, 0x1221, "ReLeeeReLBGDFGBDGFDGD", 4, "Pi-3"],
[0x3102, 0x1122, "BeFeeeFeBRGDLGLDGRDGD", 4, "Pi-4"],
[0x2013, 0x1221, "BeLeeeLeFFGDRGBDGRDGD", 4, "Pi-5"],
[0x3021, 0x1122, "BeReeeLeBFGDLGFDGRDGD", 4, "Pi-6"],
[0x3210, 0x2220, "ReBeeeFeDRGFLGDLGDBGD", 4, "S-1"],
[0x2301, 0x0222, "BeReeeLeDFGRFGDBGDLGD", 4, "S-2"],
[0x3021, 0x2220, "BeReeeFeDRGFLGDBGDLGD", 4, "S-3"],
[0x2013, 0x2202, "ReBeeeLeDFGRFGDLGDBGD", 4, "S-4"],
[0x3102, 0x2220, "FeBeeeLeDFGBRGDLGDRGD", 4, "S-5"],
[0x1203, 0x2202, "LeReeeFeDRGLBGDBGDFGD", 4, "S-6"],
[0x1203, 0x1002, "BeLeeeDeDBGRFGDFGRDGL", 4, "T-1"],
[0x3102, 0x2100, "ReBeeeDeDLGBRGDLGFDGF", 4, "T-2"],
[0x2301, 0x0210, "BeFeeeDeDBGFLGDRGRDGL", 4, "T-3"],
[0x3210, 0x2100, "FeFeeeDeDBGBRGDRGLDGL", 4, "T-4"],
[0x2013, 0x1002, "BeBeeeDeDLGRFGDLGRDGF", 4, "T-5"],
[0x3021, 0x2100, "FeBeeeDeDRGRFGDLGLDGB", 4, "T-6"],
[0x2301, 0x0120, "LeLeeeDeDFGBRGBDGDFGR", 4, "U-1"],
[0x3210, 0x1200, "LeReeeDeDBGBRGFDGDFGL", 4, "U-2"],
[0x3021, 0x1200, "FeFeeeDeDBGBRGLDGDRGL", 4, "U-3"],
[0x2013, 0x2001, "BeFeeeDeDFGBRGLDGDLGR", 4, "U-4"],
[0x1203, 0x2001, "ReFeeeDeDBGRFGLDGDBGL", 4, "U-5"],
[0x3102, 0x1200, "LeBeeeDeDBGRFGRDGDFGL", 4, "U-6"],
[0x3021, 0x0000, "DeDeeeDeDBGRFGBRGFLGL", 4, "O-Adj"],
[0x2301, 0x0000, "DeDeeeDeDBGFLGRFGBRGL", 1, "O-Diag"],
[0x3210, 0x0000, "DeDeeeDeDBGBRGRFGFLGL", 1, "O-AUF"],
];
const coprobs = idxArray(coll_map, 3);
const cofilter = idxArray(coll_map, 4);
function getCOLLScramble(type: any, length: any, cases: any) {
let cocase = coll_map[fixCase(cases, coprobs)];
return getAnyScramble(
0xba987654ffff,
0,
cocase[0] + 0x76540000,
cocase[1],
aufsuff,
aufsuff,
);
}
export function getZBLLScramble(type: any, length: any, cases: any) {
const zbcase = zbll_map[fixCase(cases, zbprobs)];
return getAnyScramble(
0xba987654ffff,
0,
zbcase[0] + 0x76540000,
zbcase[1],
aufsuff,
aufsuff,
);
}
export function getZZLLScramble() {
return getAnyScramble(
0xba9876543f1f,
0x000000000000,
0x7654ffff,
0x0000ffff,
aufsuff,
);
}
export function getZBLSScramble() {
return getAnyScramble(0xba9f7654ffff, 0x000000000000, 0x765fffff, 0x000fffff);
}
export function getLSEScramble() {
const rnd4 = rn(4);
return (
getAnyScramble(
0xba98f6f4ffff,
0x0000f0f0ffff,
0x76543210,
0x00000000,
[rlpresuff[rnd4]],
aufsuff,
) + rlappsuff[rnd4]
);
}
const cmll_map = [
0x0000, // O or solved
0x1212, // H
0x0102, // L
0x1122, // Pi
0x0222, // S
0x0021, // T
0x0012, // U
0x0111, // aS
];
const cmprobs = [6, 12, 24, 24, 24, 24, 24, 24];
const cmfilter = ["O", "H", "L", "Pi", "S", "T", "U", "aS"];
export function getCMLLScramble(type: any, length: any, cases: any) {
const rnd4 = rn(4);
const presuff = [];
for (let i = 0; i < aufsuff.length; i++) {
presuff.push(aufsuff[i].concat(rlpresuff[rnd4]));
}
return (
getAnyScramble(
0xba98f6f4ffff,
0x0000f0f0ffff,
0x7654ffff,
cmll_map[fixCase(cases, cmprobs)],
presuff,
aufsuff,
) + rlappsuff[rnd4]
);
}
export function getCLLScramble() {
return getAnyScramble(0xba9876543210, 0x000000000000, 0x7654ffff, 0x0000ffff);
}
export function getELLScramble() {
return getAnyScramble(0xba987654ffff, 0x00000000ffff, 0x76543210, 0x00000000);
}
export function get2GLLScramble() {
return getAnyScramble(
0xba987654ffff,
0x000000000000,
0x76543210,
0x0000ffff,
aufsuff,
);
}
const pll_map = [
[0x3210, 0x3021, 4, "Aa"],
[0x3210, 0x3102, 4, "Ab"],
[0x3210, 0x2301, 2, "E"],
[0x3012, 0x3201, 4, "F"],
[0x2130, 0x3021, 4, "Ga"],
[0x1320, 0x3102, 4, "Gb"],
[0x3021, 0x3102, 4, "Gc"],
[0x3102, 0x3021, 4, "Gd"],
[0x1032, 0x3210, 1, "H"],
[0x3201, 0x3201, 4, "Ja"],
[0x3120, 0x3201, 4, "Jb"],
[0x1230, 0x3012, 1, "Na"],
[0x3012, 0x3012, 1, "Nb"],
[0x0213, 0x3201, 4, "Ra"],
[0x2310, 0x3201, 4, "Rb"],
[0x1230, 0x3201, 4, "T"],
[0x3102, 0x3210, 4, "Ua"],
[0x3021, 0x3210, 4, "Ub"],
[0x3120, 0x3012, 4, "V"],
[0x3201, 0x3012, 4, "Y"],
[0x2301, 0x3210, 2, "Z"],
] as const;
const pllprobs = idxArray(pll_map, 2);
export const pllfilter: string[] = idxArray(pll_map, 3);
export function getPLLScramble(type: any, length: any, cases: any) {
const pllcase = pll_map[fixCase(cases, pllprobs)];
return getAnyScramble(
pllcase[0] + 0xba9876540000,
0x000000000000,
pllcase[1] + 0x76540000,
0x00000000,
aufsuff,
aufsuff,
);
}
const oll_map = [
[0x1111, 0x1212, 2, "Point-1", 0xeba00],
[0x1111, 0x1122, 4, "Point-2", 0xdda00],
[0x1111, 0x0222, 4, "Point-3", 0x5b620],
[0x1111, 0x0111, 4, "Point-4", 0x6d380],
[0x0011, 0x2022, 4, "Square-5", 0x8360b],
[0x0011, 0x1011, 4, "Square-6", 0x60b16],
[0x0011, 0x2202, 4, "SLBS-7", 0x1362a],
[0x0011, 0x0111, 4, "SLBS-8", 0x64392],
[0x0011, 0x1110, 4, "Fish-9", 0x2538a],
[0x0011, 0x2220, 4, "Fish-10", 0x9944c],
[0x0011, 0x0222, 4, "SLBS-11", 0x9160e],
[0x0011, 0x1101, 4, "SLBS-12", 0x44b13],
[0x0101, 0x2022, 4, "Knight-13", 0x1a638],
[0x0101, 0x0111, 4, "Knight-14", 0x2c398],
[0x0101, 0x0222, 4, "Knight-15", 0x8a619],
[0x0101, 0x1011, 4, "Knight-16", 0x28b1c],
[0x1111, 0x0102, 4, "Point-17", 0x4b381],
[0x1111, 0x0012, 4, "Point-18", 0x49705],
[0x1111, 0x0021, 4, "Point-19", 0xc9a05],
[0x1111, 0x0000, 1, "CO-20", 0x492a5],
[0x0000, 0x1212, 2, "OCLL-21", 0x1455a],
[0x0000, 0x1122, 4, "OCLL-22", 0xa445a],
[0x0000, 0x0012, 4, "OCLL-23", 0x140fa],
[0x0000, 0x0021, 4, "OCLL-24", 0x101de],
[0x0000, 0x0102, 4, "OCLL-25", 0x2047e],
[0x0000, 0x0111, 4, "OCLL-26", 0x2095e],
[0x0000, 0x0222, 4, "OCLL-27", 0x1247a],
[0x0011, 0x0000, 4, "CO-28", 0x012af],
[0x0011, 0x0210, 4, "Awkward-29", 0x1138e],
[0x0011, 0x2100, 4, "Awkward-30", 0x232aa],
[0x0011, 0x0021, 4, "P-31", 0x50396],
[0x0011, 0x1002, 4, "P-32", 0x0562b],
[0x0101, 0x0021, 4, "T-33", 0x1839c],
[0x0101, 0x0210, 4, "C-34", 0x2a2b8],
[0x0011, 0x1020, 4, "Fish-35", 0x4a1d1],
[0x0011, 0x0102, 4, "W-36", 0xc4293],
[0x0011, 0x2010, 4, "Fish-37", 0x0338b],
[0x0011, 0x0201, 4, "W-38", 0x11a2e],
[0x0101, 0x1020, 4, "BLBS-39", 0x18a3c],
[0x0101, 0x0102, 4, "BLBS-40", 0x8c299],
[0x0011, 0x1200, 4, "Awkward-41", 0x152aa],
[0x0011, 0x0120, 4, "Awkward-42", 0x0954d],
[0x0011, 0x0012, 4, "P-43", 0xe0296],
[0x0011, 0x2001, 4, "P-44", 0x03a2b],
[0x0101, 0x0012, 4, "T-45", 0xa829c],
[0x0101, 0x0120, 4, "C-46", 0x43863],
[0x0011, 0x1221, 4, "L-47", 0x52b12],
[0x0011, 0x1122, 4, "L-48", 0xa560a],
[0x0011, 0x2112, 4, "L-49", 0xe4612],
[0x0011, 0x2211, 4, "L-50", 0xec450],
[0x0101, 0x1221, 4, "I-51", 0x1ab18],
[0x0101, 0x1122, 4, "I-52", 0x53942],
[0x0011, 0x2121, 4, "L-53", 0x54712],
[0x0011, 0x1212, 4, "L-54", 0x1570a],
[0x0101, 0x2121, 2, "I-55", 0x1c718],
[0x0101, 0x1212, 2, "I-56", 0xaaa18],
[0x0101, 0x0000, 2, "CO-57", 0x082bd],
] as const;
const ollprobs = idxArray(oll_map, 2);
export const ollfilter: string[] = idxArray(oll_map, 3);
export function getOLLScramble(type: any, length: any, cases: any) {
const ollcase = oll_map[fixCase(cases, ollprobs)];
return getAnyScramble(
0xba987654ffff,
ollcase[0],
0x7654ffff,
ollcase[1],
aufsuff,
aufsuff,
);
}
export function getEOLineScramble() {
return getAnyScramble(0xffff7f5fffff, 0x000000000000, 0xffffffff, 0xffffffff);
}
export function getEasyCrossScramble(type: any, length: any) {
const cases = getEasyCross(length);
return getAnyScramble(cases[0], cases[1], 0xffffffff, 0xffffffff);
}
export function genFacelet(facelet: string) {
return search.solution(facelet, 21, 1e9, 50, 2);
}
export function solvFacelet(facelet: string) {
return search.solution(facelet, 21, 1e9, 50, 0);
}
export function getCustomScramble(type: string, length: number, cases: any) {
let ep = 0;
let eo = 0;
let cp = 0;
let co = 0;
let chk = 0x1100; //ep+cp|ep+1|cp+1|eo|co
cases = cases || valuedArray(40, 1);
for (let i = 0; i < 12; i++) {
chk += (cases[i] ? 0x11000 : 0) + (cases[i + 20] ? 0x10 : 0);
ep += (cases[i] ? 0xf : i) * Math.pow(16, i);
eo += (cases[i + 20] ? 0xf : 0) * Math.pow(16, i);
}
for (let i = 0; i < 8; i++) {
chk += (cases[i + 12] ? 0x10100 : 0) + (cases[i + 32] ? 0x1 : 0);
cp += (cases[i + 12] ? 0xf : i) * Math.pow(16, i);
co += (cases[i + 32] ? 0xf : 0) * Math.pow(16, i);
}
if ((chk & 0x1cccee) == 0) {
return "U' U ";
}
return getAnyScramble(ep, eo, cp, co);
}
const daufsuff = [[], [Dx1], [Dx2], [Dx3]];
const daufrot = ["", "y", "y2", "y'"];
function getMehta3QBScramble() {
const rnd4 = rn(4);
return (
getAnyScramble(0xffff765fffff, 0xffff000fffff, 0xf65fffff, 0xf00fffff, [
daufsuff[rnd4],
]) + daufrot[rnd4]
);
}
function getMehtaEOLEScramble() {
const skip = rn(4);
const rnd4 = rn(4);
return (
getAnyScramble(
0xba98765fffff + (0x4567 & (0xf << (skip * 4))) * 0x100000000,
0x0000000fffff + (0xf << (skip * 4)) * 0x100000000,
0xf65fffff,
0xf00fffff,
[daufsuff[rnd4]],
) + daufrot[rnd4]
);
}
function getMehtaTDRScramble() {
return getAnyScramble(0xba98765fffff, 0x000000000000, 0xf65fffff, 0xf00fffff);
}
function getMehta6CPScramble() {
return getAnyScramble(0xba98765fffff, 0x000000000000, 0xf65fffff, 0x00000000);
}
function getMehtaL5EPScramble() {
return getAnyScramble(0xba98765fffff, 0x000000000000, 0x76543210, 0x00000000);
}
function getMehtaCDRLLScramble() {
return getAnyScramble(0xba98765fffff, 0x000000000000, 0x7654ffff, 0x0000ffff);
}
const customfilter = [
"UR",
"UF",
"UL",
"UB",
"DR",
"DF",
"DL",
"DB",
"RF",
"LF",
"LB",
"RB",
"URF",
"UFL",
"ULB",
"UBR",
"DFR",
"DLF",
"DBL",
"DRB",
];
for (let i = 0; i < 20; i++) {
const piece = customfilter[i];
customfilter[i + 20] = (piece.length == 2 ? "OriE-" : "OriC-") + piece;
customfilter[i] = (piece.length == 2 ? "PermE-" : "PermC-") + piece;
}
const customprobs = valuedArray(40, 0);
const ttll_map: { 0: number; 1: number; 2: string }[] = [
[0x32410, 0x3210, "FBar-1"],
[0x32410, 0x3102, "FBar-2"],
[0x32410, 0x3021, "FBar-3"],
[0x32410, 0x2301, "FBar-4"],
[0x32410, 0x2130, "FBar-5"],
[0x32410, 0x2013, "FBar-6"],
[0x32410, 0x1320, "FBar-7"],
[0x32410, 0x1203, "FBar-8"],
[0x32410, 0x1032, "FBar-9"],
[0x32410, 0x0312, "FBar-10"],
[0x32410, 0x0231, "FBar-11"],
[0x32410, 0x0123, "FBar-12"],
[0x32401, 0x3201, "2Opp-1"],
[0x32401, 0x3120, "2Opp-2"],
[0x32401, 0x3012, "2Opp-3"],
[0x32401, 0x2310, "2Opp-4"],
[0x32401, 0x2103, "2Opp-5"],
[0x32401, 0x2031, "2Opp-6"],
[0x32401, 0x1302, "2Opp-7"],
[0x32401, 0x1230, "2Opp-8"],
[0x32401, 0x1023, "2Opp-9"],
[0x32401, 0x0321, "2Opp-10"],
[0x32401, 0x0213, "2Opp-11"],
[0x32401, 0x0132, "2Opp-12"],
[0x31420, 0x3201, "ROpp-1"],
[0x31420, 0x3120, "ROpp-2"],
[0x31420, 0x3012, "ROpp-3"],
[0x31420, 0x2310, "ROpp-4"],
[0x31420, 0x2103, "ROpp-5"],
[0x31420, 0x2031, "ROpp-6"],
[0x31420, 0x1302, "ROpp-7"],
[0x31420, 0x1230, "ROpp-8"],
[0x31420, 0x1023, "ROpp-9"],
[0x31420, 0x0321, "ROpp-10"],
[0x31420, 0x0213, "ROpp-11"],
[0x31420, 0x0132, "ROpp-12"],
[0x31402, 0x3210, "RBar-1"],
[0x31402, 0x3102, "RBar-2"],
[0x31402, 0x3021, "RBar-3"],
[0x31402, 0x2301, "RBar-4"],
[0x31402, 0x2130, "RBar-5"],
[0x31402, 0x2013, "RBar-6"],
[0x31402, 0x1320, "RBar-7"],
[0x31402, 0x1203, "RBar-8"],
[0x31402, 0x1032, "RBar-9"],
[0x31402, 0x0312, "RBar-10"],
[0x31402, 0x0231, "RBar-11"],
[0x31402, 0x0123, "RBar-12"],
[0x30421, 0x3210, "2Bar-1"],
[0x30421, 0x3102, "2Bar-2"],
[0x30421, 0x3021, "2Bar-3"],
[0x30421, 0x2301, "2Bar-4"],
[0x30421, 0x2130, "2Bar-5"],
[0x30421, 0x2013, "2Bar-6"],
[0x30421, 0x1320, "2Bar-7"],
[0x30421, 0x1203, "2Bar-8"],
[0x30421, 0x1032, "2Bar-9"],
[0x30421, 0x0312, "2Bar-10"],
[0x30421, 0x0231, "2Bar-11"],
[0x30421, 0x0123, "2Bar-12"],
[0x30412, 0x3201, "FOpp-1"],
[0x30412, 0x3120, "FOpp-2"],
[0x30412, 0x3012, "FOpp-3"],
[0x30412, 0x2310, "FOpp-4"],
[0x30412, 0x2103, "FOpp-5"],
[0x30412, 0x2031, "FOpp-6"],
[0x30412, 0x1302, "FOpp-7"],
[0x30412, 0x1230, "FOpp-8"],
[0x30412, 0x1023, "FOpp-9"],
[0x30412, 0x0321, "FOpp-10"],
[0x30412, 0x0213, "FOpp-11"],
[0x30412, 0x0132, "FOpp-12"],
];
const ttllprobs: number[] = [];
const ttllfilter: string[] = [];
for (let i = 0; i < ttll_map.length; i++) {
ttllprobs[i] = 1;
ttllfilter[i] = ttll_map[i][2];
}
function getTTLLScramble(type: any, length: any, cases: any) {
const ttllcase = ttll_map[fixCase(cases, ttllprobs)];
return getAnyScramble(
0xba9876540000 + ttllcase[1],
0x000000000000,
0x76500000 + ttllcase[0],
0x00000000,
aufsuff,
aufsuff,
);
}
const eols_map: number[] = [];
const eolsprobs: any[] = [];
const eolsfilter = [];
for (let i = 0; i < f2l_map.length; i++) {
if (f2l_map[i][0] & 0xf0) {
continue;
}
eols_map.push(f2l_map[i][0]);
eolsprobs.push(f2lprobs[i]);
eolsfilter.push(f2lfilter[i]);
}
function getEOLSScramble(type: any, length: any, cases: any) {
const caze = eols_map[fixCase(cases, eolsprobs)];
const ep = Math.pow(16, caze & 0xf);
const cp = Math.pow(16, (caze >> 8) & 0xf);
const co = 0xf ^ ((caze >> 12) & 3);
return getAnyScramble(
0xba9f7654ffff - 7 * ep,
0x000000000000,
0x765fffff - 0xb * cp,
0x000fffff - co * cp,
aufsuff,
);
}
const wvls_map: number[] = [];
const wvlsprobs: any[] = [];
const wvlsfilter = [
"Oriented",
"Rectangle-1",
"Rectangle-2",
"Tank-1",
"Bowtie-1",
"Bowtie-3",
"Tank-2",
"Bowtie-2",
"Bowtie-4",
"Snake-1",
"Adjacent-1",
"Adjacent-2",
"Gun-Far",
"Sune-1",
"Pi-Near",
"Gun-Back",
"Pi-Front",
"H-Side",
"Snake-2",
"Adjacent-3",
"Adjacent-4",
"Gun-Sides",
"H-Front",
"Pi-Back",
"Gun-Near",
"Pi-Far",
"Sune-2",
];
for (let i = 0; i < 27; i++) {
wvls_map[i] = (~~(i / 9) << 12) | (~~(i / 3) % 3 << 8) | i % 3;
wvlsprobs[i] = 1;
}
function getWVLSScramble(type: any, length: any, cases: any) {
const caze = wvls_map[fixCase(cases, wvlsprobs)];
return getAnyScramble(
0xba9f7654ff8f,
0x000000000000,
0x765fff4f,
0x000f0020 | caze,
);
}
const vls_map: number[][] = [];
const vlsprobs: any[] = [];
const vlsfilter = [];
for (let i = 0; i < 27 * 8; i++) {
const co = i % 27;
const eo = ~~(i / 27);
vls_map[i] = [
(~~(co / 9) % 3 << 12) | (~~(co / 3) % 3 << 8) | co % 3,
(((eo >> 2) & 1) << 12) | (((eo >> 1) & 1) << 8) | (eo & 1),
];
vlsprobs[i] = 1;
vlsfilter[i] =
["WVLS", "UB", "UF", "UF UB", "UL", "UB UL", "UF UL", "No Edge"][eo] +
"-" +
(co + 1);
}
function getVLSScramble(type: any, length: any, cases: any) {
const caze = vls_map[fixCase(cases, vlsprobs)];
return getAnyScramble(
0xba9f7654ff8f,
0x000f00000000 + caze[1],
0x765fff4f,
0x000f0020 + caze[0],
[[Ux3]],
);
}
function getSBRouxScramble() {
const rnd4 = rn(4);
return (
getAnyScramble(0xfa9ff6ffffff, 0xf00ff0ffffff, 0xf65fffff, 0xf00fffff, [
rlpresuff[rnd4],
]) + rlappsuff[rnd4]
);
}
function getEasyXCrossScramble(type: any, length: any) {
const cases: any = getEasyXCross(length);
return getAnyScramble(cases[0], cases[1], cases[2], cases[3]);
}
regScrambler("333", getRandomScramble)("333oh", getRandomScramble)(
"333ft",
getRandomScramble,
)("333fm", getFMCScramble)("edges", getEdgeScramble)(
"corners",
getCornerScramble,
)("ll", getLLScramble)("lsll2", getLSLLScramble, [f2lfilter, f2lprobs])(
"f2l",
getF2LScramble,
[crossFilter, crossProbs],
)("zbll", getZBLLScramble, [zbfilter, zbprobs])("zzll", getZZLLScramble)(
"zbls",
getZBLSScramble,
)("lse", getLSEScramble)("cmll", getCMLLScramble, [cmfilter, cmprobs])(
"cll",
getCLLScramble,
)("ell", getELLScramble)("pll", getPLLScramble, [pllfilter, pllprobs])(
"oll",
getOLLScramble,
[ollfilter, ollprobs],
)("2gll", get2GLLScramble)("easyc", getEasyCrossScramble)(
"eoline",
getEOLineScramble,
)("333custom", getCustomScramble, [customfilter, customprobs])(
"ttll",
getTTLLScramble,
[ttllfilter, ttllprobs],
)("eols", getEOLSScramble, [eolsfilter, eolsprobs])("wvls", getWVLSScramble, [
wvlsfilter,
wvlsprobs,
])("vls", getVLSScramble, [vlsfilter, vlsprobs])("coll", getCOLLScramble, [
cofilter,
coprobs,
])("sbrx", getSBRouxScramble)("mt3qb", getMehta3QBScramble)(
"mteole",
getMehtaEOLEScramble,
)("mttdr", getMehtaTDRScramble)("mt6cp", getMehta6CPScramble)(
"mtl5ep",
getMehtaL5EPScramble,
)("mtcdrll", getMehtaCDRLLScramble)("easyxc", getEasyXCrossScramble);