Example #1
0
 //-1: no solution found
 // X: solution with X moves shorter than expectation. Hence, the length of the solution is  depth - X
 private int phase2(int eidx, int esym, int cidx, int csym, int mid, int maxl, int depth, int lm)
 {
     if (eidx == 0 && cidx == 0 && mid == 0)
     {
         return(maxl);
     }
     for (int m = 0; m < 10; m++)
     {
         if (lm < 0 ? (m == -lm) : Util.ckmv2[lm, m])
         {
             continue;
         }
         int midx  = CoordCube.MPermMove[mid, m];
         int cidxx = CoordCube.CPermMove[cidx, CubieCube.SymMove[csym, Util.ud2std[m]]];
         int csymx = CubieCube.SymMult[cidxx & 0xf, csym];
         cidxx >>= 4;
         if (CoordCube.getPruning(CoordCube.MCPermPrun,
                                  cidxx * 24 + CoordCube.MPermConj[midx, csymx]) >= maxl)
         {
             continue;
         }
         int eidxx = CoordCube.EPermMove[eidx, CubieCube.SymMoveUD[esym, m]];
         int esymx = CubieCube.SymMult[eidxx & 0xf, esym];
         eidxx >>= 4;
         if (CoordCube.getPruning(CoordCube.EPermCCombPrun,
                                  eidxx * 70 + CoordCube.CCombConj[CubieCube.Perm2Comb[cidxx], CubieCube.SymMultInv[esymx, csymx]]) >= maxl)
         {
             continue;
         }
         if (CoordCube.getPruning(CoordCube.MEPermPrun,
                                  eidxx * 24 + CoordCube.MPermConj[midx, esymx]) >= maxl)
         {
             continue;
         }
         int ret = phase2(eidxx, esymx, cidxx, csymx, midx, maxl - 1, depth + 1, (lm < 0 && m + lm == -5) ? -lm : m);
         if (ret >= 0)
         {
             move[depth] = Util.ud2std[m];
             return(ret);
         }
     }
     return(-1);
 }
Example #2
0
        /**
         * @return
         *      0: Found or Probe limit exceeded
         *      1: Try Next Power
         *      2: Try Next Axis
         */
        private int initPhase2()
        {
            isRec = false;
            if (probe >= (this.solution_ == null ? probeMax : probeMin))
            {
                return(0);
            }
            ++probe;
            int cidx = corn0[urfIdx, preIdx] >> 4;
            int csym = corn0[urfIdx, preIdx] & 0xf;
            int mid  = node0[urfIdx, preIdx].slice;

            for (int i = 0; i < depth1; i++)
            {
                int m = move[i];
                cidx   = CoordCube.CPermMove[cidx, CubieCube.SymMove[csym, m]];
                csym   = CubieCube.SymMult[cidx & 0xf, csym];
                cidx >>= 4;

                int cx = CoordCube.UDSliceMove[mid & 0x1ff, m];
                mid = Util.permMult[mid >> 9, cx >> 9] << 9 | cx & 0x1ff;
            }
            mid >>= 9;
            int prun = CoordCube.getPruning(CoordCube.MCPermPrun, cidx * 24 + CoordCube.MPermConj[mid, csym]);

            if (prun >= maxDep2)
            {
                return(prun > maxDep2 ? 2 : 1);
            }

            int u4e = ud8e0[urfIdx, preIdx] >> 16;
            int d4e = ud8e0[urfIdx, preIdx] & 0xffff;

            for (int i = 0; i < depth1; i++)
            {
                int m = move[i];

                int cx = CoordCube.UDSliceMove[u4e & 0x1ff, m];
                u4e = Util.permMult[u4e >> 9, cx >> 9] << 9 | cx & 0x1ff;

                cx  = CoordCube.UDSliceMove[d4e & 0x1ff, m];
                d4e = Util.permMult[d4e >> 9, cx >> 9] << 9 | cx & 0x1ff;
            }

            int edge = CubieCube.MtoEPerm[494 - (u4e & 0x1ff) + (u4e >> 9) * 70 + (d4e >> 9) * 1680];
            int esym = edge & 0xf;

            edge >>= 4;

            prun = Math.Max(prun, Math.Max(
                                CoordCube.getPruning(CoordCube.MEPermPrun,
                                                     edge * 24 + CoordCube.MPermConj[mid, esym]),
                                CoordCube.getPruning(CoordCube.EPermCCombPrun,
                                                     edge * 70 + CoordCube.CCombConj[CubieCube.Perm2Comb[cidx], CubieCube.SymMultInv[esym, csym]])));

            if (prun >= maxDep2)
            {
                return(prun > maxDep2 ? 2 : 1);
            }

            int lm = 10;

            if (depth1 >= 2 && move[depth1 - 1] / 3 % 3 == move[depth1 - 2] / 3 % 3)
            {
                lm = Util.std2ud[Math.Max(move[depth1 - 1], move[depth1 - 2]) / 3 * 3 + 1];
            }
            else if (depth1 >= 1)
            {
                lm = Util.std2ud[move[depth1 - 1] / 3 * 3 + 1];
                if (move[depth1 - 1] > Util.Fx3)
                {
                    lm = -lm;
                }
            }

            int depth2;

            for (depth2 = maxDep2 - 1; depth2 >= prun; depth2--)
            {
                int ret = phase2(edge, esym, cidx, csym, mid, depth2, depth1, lm);
                if (ret < 0)
                {
                    break;
                }
                depth2 = depth2 - ret;
                sol    = depth1 + depth2;
                if (preIdx != 0)
                {
                    // assert depth2 > 0; //If depth2 == 0, the solution is optimal. In this case, we won't try preScramble to find shorter solutions.
                    int axisPre  = Util.preMove[preIdx] / 3;
                    int axisLast = move[sol - 1] / 3;
                    if (axisPre == axisLast)
                    {
                        int pow = (Util.preMove[preIdx] % 3 + move[sol - 1] % 3 + 1) % 4;
                        move[sol - 1] = axisPre * 3 + pow;
                    }
                    else if (depth2 > 1 &&
                             axisPre % 3 == axisLast % 3 &&
                             move[sol - 2] / 3 == axisPre)
                    {
                        int pow = (Util.preMove[preIdx] % 3 + move[sol - 2] % 3 + 1) % 4;
                        move[sol - 2] = axisPre * 3 + pow;
                    }
                    else
                    {
                        move[sol++] = Util.preMove[preIdx];
                    }
                }
                this.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);
            }
        }