internal static void InitUDSliceMoveConj() { CubieCube c = new CubieCube(); CubieCube d = new CubieCube(); for (int i = 0; i < N_SLICE; i++) { c.SetUDSlice(i); for (int j = 0; j < N_MOVES; j += 3) { CubieCube.EdgeMult(c, CubieCube.MoveCube[j], d); UDSliceMove[i][j] = (char)d.GetUDSlice(); } for (uint j = 0; j < 16; j += 2) { CubieCube.EdgeConjugate(c, CubieCube.SymInv[j], d); UDSliceConj[i][j >> 1] = (char)(d.GetUDSlice() & 0x1ff); } } for (int i = 0; i < N_SLICE; i++) { for (int j = 0; j < N_MOVES; j += 3) { int udslice = UDSliceMove[i][j]; for (int k = 1; k < 3; k++) { int cx = UDSliceMove[udslice & 0x1ff][j]; udslice = Util.PermMult[(uint)udslice >> 9][((uint)cx >> 9)] << 9 | cx & 0x1ff; UDSliceMove[i][j + k] = (char)(udslice); } } } }
private string Solve(CubieCube c) { Tools.Init(); int conjMask = 0; for (int i = 0; i < 6; i++) { twist[i] = c.GetTwistSym(); flip[i] = c.GetFlipSym(); slice[i] = c.GetUDSlice(); corn0[i] = c.GetCPermSym(); ud8e0[i] = c.GetU4Comb() << 16 | c.GetD4Comb(); for (int j = 0; j < i; j++) { //If S_i^-1 * C * S_i == C, It's unnecessary to compute it again. if (twist[i] == twist[j] && flip[i] == flip[j] && slice[i] == slice[j] && corn0[i] == corn0[j] && ud8e0[i] == ud8e0[j]) { conjMask |= 1 << i; break; } } if ((conjMask & (1 << i)) == 0) { prun[i] = Math.Max(Math.Max( CoordCube.GetPruning(CoordCube.UDSliceTwistPrun, ((int)(twist[i] >> 3)) * 495 + CoordCube.UDSliceConj[slice[i] & 0x1ff][twist[i] & 7]), CoordCube.GetPruning(CoordCube.UDSliceFlipPrun, ((int)((uint)flip[i] >> 3)) * 495 + CoordCube.UDSliceConj[slice[i] & 0x1ff][flip[i] & 7])), Tools.USE_TWIST_FLIP_PRUN ? CoordCube.GetPruning(CoordCube.TwistFlipPrun, ((int)(twist[i] >> 3)) * 2688 + (flip[i] & 0xfff8 | CubieCube.Sym8MultInv[flip[i] & 7][twist[i] & 7])) : 0); } c.URFConjugate(); if (i == 2) { c.InvCubieCube(); } } for (depth1 = 0; depth1 < sol; depth1++) { maxDep2 = Math.Min(12, sol - depth1); for (urfIdx = 0; urfIdx < 6; urfIdx++) { if ((firstAxisRestriction != -1 || lastAxisRestriction != -1) && urfIdx >= 3) { // When urfIdx >= 3, we're solving the // inverse cube. This doesn't work // when we're also restricting the // first turn, so we just skip inverse // solutions when firstAxisRestriction has // been set. continue; } if ((conjMask & (1 << urfIdx)) != 0) { continue; } corn[0] = corn0[urfIdx]; mid4[0] = slice[urfIdx]; ud8e[0] = ud8e0[urfIdx]; valid1 = 0; int lm = firstAxisRestriction == -1 ? -1 : CubieCube.URFMoveInv[urfIdx][firstAxisRestriction] / 3 * 3; if ((prun[urfIdx] <= depth1) && Phase1((int)((uint)twist[urfIdx] >> 3), twist[urfIdx] & 7, (int)((uint)flip[urfIdx] >> 3), flip[urfIdx] & 7, slice[urfIdx] & 0x1ff, depth1, lm) == 0) { return(solution == null ? "Error 8" : solution); } } } return(solution == null ? "Error 7" : solution); }