protected int InitPhase2() { int p2corn = phase2Cubie.GetCPermSym(); int p2csym = p2corn & 0xf; p2corn >>= 4; int p2edge = phase2Cubie.GetEPermSym(); int p2esym = p2edge & 0xf; p2edge >>= 4; int p2mid = phase2Cubie.GetMPerm(); int prun = Math.Max( CoordCube.GetPruning(CoordCube.EPermCCombPPrun, p2edge * CoordCube.N_COMB + CoordCube.CCombPConj[CubieCube.Perm2CombP[p2corn] & 0xff, CubieCube.SymMultInv[p2esym, p2csym]]), CoordCube.GetPruning(CoordCube.MCPermPrun, p2corn * CoordCube.N_MPERM + CoordCube.MPermConj[p2mid, p2csym])); if (prun >= maxDep2) { return(prun > maxDep2 ? 2 : 1); } int depth2; for (depth2 = maxDep2 - 1; depth2 >= prun; depth2--) { int ret = Phase2(p2edge, p2esym, p2corn, p2csym, p2mid, depth2, depth1, 10); if (ret < 0) { break; } depth2 -= ret; sol = 0; for (int i = 0; i < depth1 + depth2; i++) { AppendSolMove(move[i]); } for (int i = preMoveLen - 1; i >= 0; i--) { AppendSolMove(preMoves[i]); } solution = SolutionTostring(); } if (depth2 != maxDep2 - 1) { //At least one solution has been found. maxDep2 = Math.Min(MAX_DEPTH2, sol - length1); return(probe >= probeMin ? 0 : 1); } else { return(1); } }
///<returns> ///<para>-1: no solution found</para> ///<para>X: solution with X moves shorter than expectation. ///Hence, the length of the solution is depth - X</para> ///</returns> protected int Phase2(int edge, int esym, int corn, int csym, int mid, int maxl, int depth, int lm) { if (edge == 0 && corn == 0 && mid == 0) { return(maxl); } int moveMask = Util.ckmv2bit[lm]; for (int m = 0; m < 10; m++) { if ((moveMask >> m & 1) != 0) { m += 0x42 >> m & 3; continue; } int midx = CoordCube.MPermMove[mid, m]; int cornx = CoordCube.CPermMove[corn, CubieCube.SymMoveUD[csym, m]]; int csymx = CubieCube.SymMult[cornx & 0xf, csym]; cornx >>= 4; int edgex = CoordCube.EPermMove[edge, CubieCube.SymMoveUD[esym, m]]; int esymx = CubieCube.SymMult[edgex & 0xf, esym]; edgex >>= 4; int edgei = CubieCube.GetPermSymInv(edgex, esymx, false); int corni = CubieCube.GetPermSymInv(cornx, csymx, true); int prun = CoordCube.GetPruning(CoordCube.EPermCCombPPrun, (edgei >> 4) * CoordCube.N_COMB + CoordCube.CCombPConj[CubieCube.Perm2CombP[corni >> 4] & 0xff, CubieCube.SymMultInv[edgei & 0xf, corni & 0xf]]); if (prun > maxl + 1) { break; } else if (prun >= maxl) { m += 0x42 >> m & 3 & (maxl - prun); continue; } prun = Math.Max( CoordCube.GetPruning(CoordCube.MCPermPrun, cornx * CoordCube.N_MPERM + CoordCube.MPermConj[midx, csymx]), CoordCube.GetPruning(CoordCube.EPermCCombPPrun, edgex * CoordCube.N_COMB + CoordCube.CCombPConj[CubieCube.Perm2CombP[cornx] & 0xff, CubieCube.SymMultInv[esymx, csymx]])); if (prun >= maxl) { m += 0x42 >> m & 3 & (maxl - prun); continue; } int ret = Phase2(edgex, esymx, cornx, csymx, midx, maxl - 1, depth + 1, m); if (ret >= 0) { move[depth] = Util.ud2std[m]; return(ret); } } return(-1); }
public int GetCPermSym() { int k = ESym2CSym(CoordCube.GetPruning(EPermR2S, GetCPerm())) & 0xf; temps = temps ?? new CubieCube(); CornConjugate(this, SymMultInv[0, k], temps); int idx = Array.BinarySearch(EPermS2R, (char)temps.GetCPerm()); //assert idx >= 0; return(idx << 4 | k); }
public int GetEPermSym() { int raw = GetEPerm(); int k = CoordCube.GetPruning(EPermR2S, raw); temps = temps ?? new CubieCube(); EdgeConjugate(this, SymMultInv[0, k], temps); int idx = Array.BinarySearch(EPermS2R, (char)temps.GetEPerm()); //assert idx >= 0; return(idx << 4 | k); }
public static int InitSym2Raw(int N_RAW, char[] Sym2Raw, sbyte[] Raw2Sym, char[] SymState, int coord) { int N_RAW_HALF = (N_RAW + 1) / 2; CubieCube c = new CubieCube(); CubieCube d = new CubieCube(); int count = 0, idx = 0; int sym_inc = coord >= 2 ? 1 : 2; bool isEdge = coord != 1; for (int i = 0; i < N_RAW; i++) { if (CoordCube.GetPruning(Raw2Sym, i) != 0) { continue; } switch (coord) { case 0: c.SetFlip(i); break; case 1: c.SetTwist(i); break; case 2: c.SetEPerm(i); break; } for (int s = 0; s < 16; s += sym_inc) { if (isEdge) { EdgeConjugate(c, s, d); } else { CornConjugate(c, s, d); } switch (coord) { case 0: idx = d.GetFlip(); break; case 1: idx = d.GetTwist(); break; case 2: idx = d.GetEPerm(); break; } if (coord == 0 && Search.USE_TWIST_FLIP_PRUN) { FlipS2RF[count << 3 | s >> 1] = (char)idx; } if (idx == i) { SymState[count] |= (char)(1 << (s / sym_inc)); } int symIdx = (count << 4 | s) / sym_inc; if (CoordCube.GetPruning(Raw2Sym, idx) == 0) { CoordCube.SetPruning(Raw2Sym, idx, symIdx & 0xf); if (coord != 2) { Raw2Sym[idx + N_RAW_HALF] = (sbyte)(symIdx >> 4); } } } Sym2Raw[count++] = (char)i; } return(count); }
public int GetTwistSym() { int raw = GetTwist(); return(0xfff & TwistR2S[raw + CoordCube.N_TWIST_HALF] << 4 | CoordCube.GetPruning(TwistR2S, raw)); }
public static int FlipRaw2Sym(int raw) { return(0xfff & FlipR2S[raw + CoordCube.N_FLIP_HALF] << 4 | CoordCube.GetPruning(FlipR2S, raw)); }