/** * 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 { acycle, createMove, createPrun, get8Perm, getPruning, rn, set8Perm } from "../lib/mathlib"; import { regScrambler } from "./scramble"; const cmv = []; const emv = []; const prun = [[], [], []]; const moveEdges = [ [0, 3, 2, 1], [0, 1], [0, 3], ]; function cornerMove(arr, m) { acycle(arr, [0, m + 1]); } function edgeMove(idx, m) { const arr = set8Perm([], ~~(idx / 3), 4); acycle(arr, moveEdges[m]); return get8Perm(arr, 4) * 3 + (((idx % 3) + (m == 0 ? 1 : 0)) % 3); } function doMove(off, idx, m) { let edge = idx % 72; let corner = ~~(idx / 72); corner = cmv[m][corner]; edge = emv[(m + off) % 3][edge]; return corner * 72 + edge; } function getPrun(state) { return Math.max( getPruning(prun[0], state[0] * 72 + state[1]), getPruning(prun[1], state[0] * 72 + state[2]), getPruning(prun[2], state[0] * 72 + state[3]) ); } function search(state, maxl, lm, sol) { if (maxl == 0) { return state[0] == 0 && state[1] == 0 && state[2] == 0 && state[3] == 0; } if (getPrun(state) > maxl) { return false; } for (let m = 0; m < 3; m++) { if (m == lm) { continue; } const statex = state.slice(); for (let a = 0; a < 11; a++) { statex[0] = cmv[m][statex[0]]; for (let i = 1; i < 4; i++) { statex[i] = emv[(m + i - 1) % 3][statex[i]]; } if (search(statex, maxl - 1, m, sol)) { sol.push("URF".charAt(m) + ["'", "2'", "3'", "4'", "5'", "6", "5", "4", "3", "2", ""][a]); return true; } } } } let initRet = false; function init() { if (initRet) { return; } initRet = true; createMove(emv, 72, edgeMove, 3); createMove(cmv, 24, [cornerMove, "p", 4], 3); for (let i = 0; i < 3; i++) { createPrun(prun[i], 0, 24 * 72, 5, doMove.bind(null, i), 3, 12, 0); } } function getRandomState() { const ret = [rn(24)]; for (let i = 0; i < 3; i++) { do { ret[i + 1] = rn(72); } while (getPruning(prun[i], ret[0] * 72 + ret[i + 1]) == 15); } return ret; } export function generateGearScramble(type) { init(); let state; do { state = getRandomState(); } while (state == 0); let len = type == "gearso" ? 4 : 0; const sol = []; while (true) { if (search(state, len, -1, sol)) { break; } len++; } return sol.reverse().join(" "); } regScrambler(["gearo", "gearso"], generateGearScramble);