Exemple #1
0
        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);
            }
        }
Exemple #2
0
        ///<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);
        }
Exemple #3
0
        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);
        }
Exemple #4
0
        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);
        }
Exemple #5
0
        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);
        }
Exemple #6
0
        public int GetTwistSym()
        {
            int raw = GetTwist();

            return(0xfff & TwistR2S[raw + CoordCube.N_TWIST_HALF] << 4 | CoordCube.GetPruning(TwistR2S, raw));
        }
Exemple #7
0
 public static int FlipRaw2Sym(int raw)
 {
     return(0xfff & FlipR2S[raw + CoordCube.N_FLIP_HALF] << 4 | CoordCube.GetPruning(FlipR2S, raw));
 }