コード例 #1
0
ファイル: Search.cs プロジェクト: stesta/TNoodle.NET
 private bool Phase2(int eidx, int esym, int cidx, int csym, int mid, int maxl, int depth, int lm)
 {
     if (maxl == 0)
     {
         // We've done the last move we're allowed to do, make sure it's permitted
         // by lastAxisRestriction.
         if (lastAxisRestriction != -1)
         {
             int stdLm    = CubieCube.URFMove[urfIdx][Util.Ud2std[lm]];
             int lastAxis = (stdLm / 3) * 3;
             if (lastAxisRestriction == lastAxis || lastAxisRestriction == lastAxis + 9)
             {
                 return(false);
             }
         }
         return(eidx == 0 && cidx == 0 && mid == 0);
     }
     for (int m = 0; m < 10; m++)
     {
         if (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 & 15][csym];
         cidxx = (int)((uint)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 & 15][esym];
         eidxx = (int)((uint)eidxx >> 4);
         if (CoordCube.GetPruning(CoordCube.MEPermPrun,
                                  eidxx * 24 + CoordCube.MPermConj[midx][esymx]) >= maxl)
         {
             continue;
         }
         if (Phase2(eidxx, esymx, cidxx, csymx, midx, maxl - 1, depth + 1, m))
         {
             move[depth] = Util.Ud2std[m];
             return(true);
         }
     }
     return(false);
 }
コード例 #2
0
ファイル: Tools.cs プロジェクト: stesta/TNoodle.NET
        private static void InitIdx(int idx)
        {
            switch (idx)
            {
            case 0: CubieCube.InitMove(); break;            //-

            case 1: CubieCube.InitSym(); break;             //0

            case 2: CubieCube.InitFlipSym2Raw(); break;     //1

            case 3: CubieCube.InitTwistSym2Raw(); break;    //1

            case 4: CubieCube.InitPermSym2Raw(); break;     //1

            case 5: CoordCube.InitFlipMove(); break;        //0, 1, 2

            case 6: CoordCube.InitTwistMove(); break;       //0, 1, 3

            case 7: CoordCube.InitUDSliceMoveConj(); break; //0, 1

            case 8: CoordCube.InitCPermMove(); break;       //0, 1, 4

            case 9: CoordCube.InitEPermMove(); break;       //0, 1, 4

            case 10: CoordCube.InitMPermMoveConj(); break;  //0, 1

            case 11: if (USE_TWIST_FLIP_PRUN)
                {
                    CoordCube.InitTwistFlipPrun();
                }
                break;                                      //1, 2, 3, 5, 6

            case 12: CoordCube.InitSliceTwistPrun(); break; //1, 3, 6, 7

            case 13: CoordCube.InitSliceFlipPrun(); break;  //1, 2, 5, 7

            case 14: CoordCube.InitMEPermPrun(); break;     //1, 4, 9, 10

            case 15: CoordCube.InitMCPermPrun(); break;     //1, 4, 8, 10
            }
        }
コード例 #3
0
ファイル: Search.cs プロジェクト: stesta/TNoodle.NET
        /**
         * @return
         *      0: Found or Timeout
         *      1: Try Next Power
         *      2: Try Next Axis
         */
        private int Phase1(int twist, int tsym, int flip, int fsym, int slice, int maxl, int lastAxis)
        {
            if (twist == 0 && flip == 0 && slice == 0 && maxl < 5)
            {
                return(maxl == 0 ? InitPhase2() : 1);
            }
            for (int axis = 0; axis < 18; axis += 3)
            {
                if (axis == lastAxis || axis == lastAxis - 9)
                {
                    continue;
                }
                for (int power = 0; power < 3; power++)
                {
                    int m = axis + power;

                    int slicex = CoordCube.UDSliceMove[slice][m] & 0x1ff;
                    int twistx = CoordCube.TwistMove[twist][CubieCube.Sym8Move[tsym][m]];
                    int tsymx  = CubieCube.Sym8Mult[twistx & 7][tsym];
                    twistx = (int)((uint)twistx >> 3);
                    int prun = CoordCube.GetPruning(CoordCube.UDSliceTwistPrun,
                                                    twistx * 495 + CoordCube.UDSliceConj[slicex][tsymx]);
                    if (prun > maxl)
                    {
                        break;
                    }
                    else if (prun == maxl)
                    {
                        continue;
                    }
                    int flipx = CoordCube.FlipMove[flip][CubieCube.Sym8Move[fsym][m]];
                    int fsymx = CubieCube.Sym8Mult[flipx & 7][fsym];
                    flipx = (int)((uint)flipx >> 3);
                    if (Tools.USE_TWIST_FLIP_PRUN)
                    {
                        prun = CoordCube.GetPruning(CoordCube.TwistFlipPrun,
                                                    (twistx * 336 + flipx) << 3 | CubieCube.Sym8MultInv[fsymx][tsymx]);
                        if (prun > maxl)
                        {
                            break;
                        }
                        else if (prun == maxl)
                        {
                            continue;
                        }
                    }
                    prun = CoordCube.GetPruning(CoordCube.UDSliceFlipPrun,
                                                flipx * 495 + CoordCube.UDSliceConj[slicex][fsymx]);
                    if (prun > maxl)
                    {
                        break;
                    }
                    else if (prun == maxl)
                    {
                        continue;
                    }
                    move[depth1 - maxl] = m;
                    valid1 = Math.Min(valid1, depth1 - maxl);
                    int ret = Phase1(twistx, tsymx, flipx, fsymx, slicex, maxl - 1, axis);
                    if (ret != 1)
                    {
                        return(ret >> 1);
                    }
                }
            }
            return(1);
        }
コード例 #4
0
ファイル: Search.cs プロジェクト: stesta/TNoodle.NET
        /**
         * @return
         *      0: Found or Timeout
         *      1: Try Next Power
         *      2: Try Next Axis
         */
        private int InitPhase2()
        {
            if (Environment.TickCount >= (solution == null ? timeOut : timeMin))
            {
                return(0);
            }
            valid2 = Math.Min(valid2, valid1);
            int cidx = (int)((uint)corn[valid1] >> 4);
            int csym = corn[valid1] & 0xf;

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

                int cx = CoordCube.UDSliceMove[mid4[i] & 0x1ff][m];
                mid4[i + 1] = Util.PermMult[(uint)mid4[i] >> 9][(uint)cx >> 9] << 9 | cx & 0x1ff;
            }
            valid1 = depth1;
            int mid  = (int)((uint)mid4[depth1] >> 9);
            int prun = CoordCube.GetPruning(CoordCube.MCPermPrun, cidx * 24 + CoordCube.MPermConj[mid][csym]);

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

            int u4e = (int)((uint)ud8e[valid2] >> 16);
            int d4e = ud8e[valid2] & 0xffff;

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

                int cx = CoordCube.UDSliceMove[u4e & 0x1ff][m];
                u4e = Util.PermMult[(uint)u4e >> 9][(uint)cx >> 9] << 9 | cx & 0x1ff;

                cx  = CoordCube.UDSliceMove[d4e & 0x1ff][m];
                d4e = Util.PermMult[(uint)d4e >> 9][(uint)cx >> 9] << 9 | cx & 0x1ff;

                ud8e[i + 1] = u4e << 16 | d4e;
            }
            valid2 = depth1;

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

            edge = (int)((uint)edge >> 4);

            prun = Math.Max(CoordCube.GetPruning(CoordCube.MEPermPrun, edge * 24 + CoordCube.MPermConj[mid][esym]), prun);
            if (prun >= maxDep2)
            {
                return(prun > maxDep2 ? 2 : 1);
            }

            int firstAxisRestrictionUd = firstAxisRestriction == -1 ? 10 : Util.Std2ud[CubieCube.URFMoveInv[urfIdx][firstAxisRestriction] / 3 * 3 + 1];
            int lm = depth1 == 0 ? firstAxisRestrictionUd : Util.Std2ud[move[depth1 - 1] / 3 * 3 + 1];

            for (int depth2 = prun; depth2 < maxDep2; depth2++)
            {
                if (Phase2(edge, esym, cidx, csym, mid, depth2, depth1, lm))
                {
                    sol      = depth1 + depth2;
                    maxDep2  = Math.Min(12, sol - depth1);
                    solution = SolutionToString();
                    return(Environment.TickCount >= timeMin ? 0 : 1);
                }
            }
            return(1);
        }
コード例 #5
0
ファイル: Search.cs プロジェクト: stesta/TNoodle.NET
        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);
        }