示例#1
0
        protected string Searchopt()
        {
            int maxprun1 = 0;
            int maxprun2 = 0;

            for (int i = 0; i < 6; i++)
            {
                urfCoordCube[i].CalcPruning(false);
                if (i < 3)
                {
                    maxprun1 = Math.Max(maxprun1, urfCoordCube[i].prun);
                }
                else
                {
                    maxprun2 = Math.Max(maxprun2, urfCoordCube[i].prun);
                }
            }
            urfIdx         = maxprun2 > maxprun1 ? 3 : 0;
            phase1Cubie[0] = urfCubieCube[urfIdx];
            for (length1 = isRec ? length1 : 0; length1 < sol; length1++)
            {
                CoordCube ud = urfCoordCube[0 + urfIdx];
                CoordCube rl = urfCoordCube[1 + urfIdx];
                CoordCube fb = urfCoordCube[2 + urfIdx];

                if (ud.prun <= length1 && rl.prun <= length1 && fb.prun <= length1 &&
                    Phase1opt(ud, rl, fb, selfSym, length1, -1) == 0)
                {
                    return(solution ?? "Error 8");
                }
            }
            return(solution ?? "Error 7");
        }
示例#2
0
 public int DoMovePrunConj(CoordCube cc, int m)
 {
     m      = CubieCube.SymMove[3, m];
     flipc  = FlipMove[cc.flipc >> 3, CubieCube.Sym8Move[m << 3 | cc.flipc & 7]] ^ (cc.flipc & 7);
     twistc = TwistMove[cc.twistc >> 3, CubieCube.Sym8Move[m << 3 | cc.twistc & 7]] ^ (cc.twistc & 7);
     return(GetPruning(TwistFlipPrun,
                       (twistc >> 3) << 11 | CubieCube.FlipS2RF[flipc ^ (twistc & 7)]));
 }
示例#3
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);
        }
示例#4
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);
            }
        }
示例#5
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);
        }
示例#6
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);
        }
示例#7
0
        public void Set(CoordCube node)
        {
            this.twist = node.twist;
            this.tsym  = node.tsym;
            this.flip  = node.flip;
            this.fsym  = node.fsym;
            this.slice = node.slice;
            this.prun  = node.prun;

            if (Search.USE_CONJ_PRUN)
            {
                this.twistc = node.twistc;
                this.flipc  = node.flipc;
            }
        }
示例#8
0
 public Search()
 {
     for (int i = 0; i < 21; i++)
     {
         nodeUD[i]      = new CoordCube();
         nodeRL[i]      = new CoordCube();
         nodeFB[i]      = new CoordCube();
         phase1Cubie[i] = new CubieCube();
     }
     for (int i = 0; i < 6; i++)
     {
         urfCubieCube[i] = new CubieCube();
         urfCoordCube[i] = new CoordCube();
     }
     for (int i = 0; i < MAX_PRE_MOVES; i++)
     {
         preMoveCubes[i + 1] = new CubieCube();
     }
 }
示例#9
0
        public string Solution(string facelets, int maxDepth, long probeMax, long probeMin, int verbose)
        {
            int check = Verify(facelets);

            if (check != 0)
            {
                return("Error " + Math.Abs(check));
            }
            this.sol      = maxDepth + 1;
            this.probe    = 0;
            this.probeMax = probeMax;
            this.probeMin = Math.Min(probeMin, probeMax);
            this.verbose  = verbose;
            this.solution = null;
            this.isRec    = false;

            CoordCube.Init();
            InitSearch();

            return((verbose & OPTIMAL_SOLUTION) == 0 ? SSearch() : Searchopt());
        }
示例#10
0
        /**
         * @return pruning value
         */
        public int DoMovePrun(CoordCube cc, int m, bool isPhase1)
        {
            slice = UDSliceMove[cc.slice, m];

            flip   = FlipMove[cc.flip, CubieCube.Sym8Move[m << 3 | cc.fsym]];
            fsym   = (flip & 7) ^ cc.fsym;
            flip >>= 3;

            twist   = TwistMove[cc.twist, CubieCube.Sym8Move[m << 3 | cc.tsym]];
            tsym    = (twist & 7) ^ cc.tsym;
            twist >>= 3;

            prun = Math.Max(
                Math.Max(
                    GetPruning(UDSliceTwistPrun,
                               twist * N_SLICE + UDSliceConj[slice, tsym]),
                    GetPruning(UDSliceFlipPrun,
                               flip * N_SLICE + UDSliceConj[slice, fsym])),
                Search.USE_TWIST_FLIP_PRUN ? GetPruning(TwistFlipPrun,
                                                        twist << 11 | CubieCube.FlipS2RF[flip << 3 | (fsym ^ tsym)]) : 0);
            return(prun);
        }
示例#11
0
        /** <returns>
         * <para>0: Found or Probe limit exceeded</para>
         * <para>1: Try Next Power</para>
         * <para>2: Try Next Axis</para>
         * </returns>
         */
        protected int Phase1opt(CoordCube ud, CoordCube rl, CoordCube fb, long ssym, int maxl, int lm)
        {
            if (ud.prun == 0 && rl.prun == 0 && fb.prun == 0 && maxl < 5)
            {
                maxDep2 = maxl + 1;
                depth1  = length1 - maxl;
                return(InitPhase2Pre() == 0 ? 0 : 1);
            }

            int skipMoves = CubieCube.GetSkipMoves(ssym);

            for (int axis = 0; axis < 18; axis += 3)
            {
                if (axis == lm || axis == lm - 9)
                {
                    continue;
                }
                for (int power = 0; power < 3; power++)
                {
                    int m = axis + power;

                    if (isRec && m != move[length1 - maxl] ||
                        skipMoves != 0 && (skipMoves & 1 << m) != 0)
                    {
                        continue;
                    }

                    // UD Axis
                    int prun_ud = Math.Max(nodeUD[maxl].DoMovePrun(ud, m, false),
                                           USE_CONJ_PRUN ? nodeUD[maxl].DoMovePrunConj(ud, m) : 0);
                    if (prun_ud > maxl)
                    {
                        break;
                    }
                    else if (prun_ud == maxl)
                    {
                        continue;
                    }

                    // RL Axis
                    m = CubieCube.urfMove[2, m];

                    int prun_rl = Math.Max(nodeRL[maxl].DoMovePrun(rl, m, false),
                                           USE_CONJ_PRUN ? nodeRL[maxl].DoMovePrunConj(rl, m) : 0);
                    if (prun_rl > maxl)
                    {
                        break;
                    }
                    else if (prun_rl == maxl)
                    {
                        continue;
                    }

                    // FB Axis
                    m = CubieCube.urfMove[2, m];

                    int prun_fb = Math.Max(nodeFB[maxl].DoMovePrun(fb, m, false),
                                           USE_CONJ_PRUN ? nodeFB[maxl].DoMovePrunConj(fb, m) : 0);
                    if (prun_ud == prun_rl && prun_rl == prun_fb && prun_fb != 0)
                    {
                        prun_fb++;
                    }

                    if (prun_fb > maxl)
                    {
                        break;
                    }
                    else if (prun_fb == maxl)
                    {
                        continue;
                    }

                    m = CubieCube.urfMove[2, m];

                    move[length1 - maxl] = m;
                    valid1 = Math.Min(valid1, length1 - maxl);
                    int ret = Phase1opt(nodeUD[maxl], nodeRL[maxl], nodeFB[maxl], ssym & CubieCube.moveCubeSym[m], maxl - 1, axis);
                    if (ret == 0)
                    {
                        return(0);
                    }
                }
            }
            return(1);
        }
示例#12
0
        /**
         * <returns>
         * <para>0: Found or Probe limit exceeded</para>
         * <para>1: Try Next Power</para>
         * <para>2: Try Next Axis</para>
         * </returns>
         */
        protected int Phase1(CoordCube node, int ssym, int maxl, int lm)
        {
            if (node.prun == 0 && maxl < 5)
            {
                if (allowShorter || maxl == 0)
                {
                    depth1 -= maxl;
                    int ret = InitPhase2Pre();
                    depth1 += maxl;
                    return(ret);
                }
                else
                {
                    return(1);
                }
            }

            int skipMoves = CubieCube.GetSkipMoves(ssym);

            for (int axis = 0; axis < 18; axis += 3)
            {
                if (axis == lm || axis == lm - 9)
                {
                    continue;
                }
                for (int power = 0; power < 3; power++)
                {
                    int m = axis + power;

                    if (isRec && m != move[depth1 - maxl] ||
                        skipMoves != 0 && (skipMoves & 1 << m) != 0)
                    {
                        continue;
                    }

                    int prun = nodeUD[maxl].DoMovePrun(node, m, true);
                    if (prun > maxl)
                    {
                        break;
                    }
                    else if (prun == maxl)
                    {
                        continue;
                    }

                    if (USE_CONJ_PRUN)
                    {
                        prun = nodeUD[maxl].DoMovePrunConj(node, m);
                        if (prun > maxl)
                        {
                            break;
                        }
                        else if (prun == maxl)
                        {
                            continue;
                        }
                    }

                    move[depth1 - maxl] = m;
                    valid1 = Math.Min(valid1, depth1 - maxl);
                    int ret = Phase1(nodeUD[maxl], ssym & (int)CubieCube.moveCubeSym[m], maxl - 1, axis);
                    if (ret == 0)
                    {
                        return(0);
                    }
                    else if (ret == 2)
                    {
                        break;
                    }
                }
            }
            return(1);
        }
示例#13
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);
        }
示例#14
0
        public int GetTwistSym()
        {
            int raw = GetTwist();

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