Пример #1
0
        private static void Init()
        {
            if (inited)
            {
                return;
            }
            Min2phase.Tools.Init();

            Center1.InitSym();
            Center1.Raw2sym = new int[735471];
            Center1.InitSym2Raw();
            Center1.CreateMoveTable();
            Center1.Raw2sym = null;
            Center1.CreatePrun();

            Center2.Init();

            Center3.Init();

            Edge3.InitMvrot();
            Edge3.InitRaw2Sym();
            Edge3.CreatePrun();

            inited = true;
        }
Пример #2
0
        public static void InitRaw2Sym()
        {
            Edge3 e = new Edge3();

            sbyte[] occ   = new sbyte[11880 / 8];
            int     count = 0;

            for (int i = 0; i < 11880; i++)
            {
                if ((occ[(uint)i >> 3] & (1 << (i & 7))) == 0)
                {
                    e.Set(i * factX[8]);
                    for (int j = 0; j < 8; j++)
                    {
                        int idx = e.Get(4);
                        if (idx == i)
                        {
                            symstate[count] |= (char)(1 << j);
                        }
                        occ[idx >> 3] |= (sbyte)(1 << (idx & 7));
                        Raw2sym[idx]   = count << 3 | syminv[j];
                        e.Rot(0);
                        if (j % 2 == 1)
                        {
                            e.Rot(1);
                            e.Rot(2);
                        }
                    }
                    sym2raw[count++] = i;
                }
            }
        }
Пример #3
0
 public Search()
 {
     for (int i = 0; i < 20; i++)
     {
         tempe[i] = new Edge3();
     }
 }
Пример #4
0
        private bool Init3()
        {
            c2.Copy(c1);
            for (int i = 0; i < length2; i++)
            {
                c2.Move(move2[i]);
            }
            if (!c2.CheckEdge())
            {
                return(false);
            }
            int eparity = e12.Set(c2.GetEdge());

            ct3.Set(c2.GetCenter(), eparity ^ c2.GetCorner().GetParity());
            int ct   = ct3.Getct();
            int edge = e12.Get(10);
            int prun = Edge3.Getprun(e12.Getsym());

            if (arr2[arr2idx] == null)
            {
                arr2[arr2idx] = new FullCube(c2);
            }
            else
            {
                arr2[arr2idx].Copy(c2);
            }
            arr2[arr2idx].Value   = length1 + length2 + Math.Max(prun, Center3.Prun[ct]);
            arr2[arr2idx].Length2 = length2;
            arr2idx++;

            return(arr2idx == arr2.Length);
        }
Пример #5
0
 private void Set(Edge3 e)
 {
     for (int i = 0; i < 12; i++)
     {
         Edge[i]  = e.Edge[i];
         edgeo[i] = e.edgeo[i];
     }
     isStd = e.isStd;
 }
Пример #6
0
        private bool Search3(int edge, int ct, int prun, int maxl, int lm, int depth)
        {
            if (maxl == 0)
            {
                return(edge == 0 && ct == 0);
            }
            tempe[depth].Set(edge);
            for (int m = 0; m < 17; m++)
            {
                if (Ckmv3[lm][m])
                {
                    m = SkipAxis3[m];
                    continue;
                }
                int ctx   = Center3.Ctmove[ct][m];
                int prun1 = Center3.Prun[ctx];
                if (prun1 >= maxl)
                {
                    if (prun1 > maxl && m < 14)
                    {
                        m = SkipAxis3[m];
                    }
                    continue;
                }
                int edgex = Edge3.Getmvrot(tempe[depth].Edge, m << 3, 10);

                int cord1x    = edgex / Edge3.N_RAW;
                int symcord1x = Edge3.Raw2sym[cord1x];
                int symx      = symcord1x & 0x7;
                symcord1x >>= 3;
                int cord2x = Edge3.Getmvrot(tempe[depth].Edge, m << 3 | symx, 10) % Edge3.N_RAW;

                int prunx = Edge3.Getprun(symcord1x * Edge3.N_RAW + cord2x, prun);
                if (prunx >= maxl)
                {
                    if (prunx > maxl && m < 14)
                    {
                        m = SkipAxis3[m];
                    }
                    continue;
                }

                if (Search3(edgex, ctx, prunx, maxl - 1, m, depth + 1))
                {
                    move3[depth] = m;
                    return(true);
                }
            }
            return(false);
        }
Пример #7
0
        public static int Getprun(int edge)
        {
            Edge3 e     = new Edge3();
            int   depth = 0;
            int   depm3 = GetPruning(eprun, edge);

            if (depm3 == 0x3)
            {
                return(MAX_DEPTH);
            }
            while (edge != 0)
            {
                if (depm3 == 0)
                {
                    depm3 = 2;
                }
                else
                {
                    depm3--;
                }

                int symcord1 = edge / N_RAW;
                int cord1    = sym2raw[symcord1];
                int cord2    = edge % N_RAW;
                e.Set(cord1 * N_RAW + cord2);

                for (int m = 0; m < 17; m++)
                {
                    int cord1x    = Getmvrot(e.Edge, m << 3, 4);
                    int symcord1x = Raw2sym[cord1x];
                    int symx      = symcord1x & 0x7;
                    symcord1x >>= 3;
                    int cord2x = Getmvrot(e.Edge, m << 3 | symx, 10) % N_RAW;
                    int idx    = symcord1x * N_RAW + cord2x;
                    if (GetPruning(eprun, idx) == depm3)
                    {
                        depth++;
                        edge = idx;
                        break;
                    }
                }
            }
            return(depth);
        }
Пример #8
0
        public static void InitMvrot()
        {
            Edge3 e = new Edge3();

            for (int m = 0; m < 20; m++)
            {
                for (int r = 0; r < 8; r++)
                {
                    e.Set(0);
                    e.Move(m);
                    e.Rotate(r);
                    for (int i = 0; i < 12; i++)
                    {
                        mvrot[m << 3 | r][i] = e.Edge[i];
                    }
                    e.Std();
                    for (int i = 0; i < 12; i++)
                    {
                        mvroto[m << 3 | r][i] = e.temp[i];
                    }
                }
            }
        }
Пример #9
0
        private void DoSearch()
        {
            Init();
            solution = "";
            int ud     = new Center1(cubeToSolve.GetCenter(), 0).Getsym();
            int fb     = new Center1(cubeToSolve.GetCenter(), 1).Getsym();
            int rl     = new Center1(cubeToSolve.GetCenter(), 2).Getsym();
            int udprun = Center1.Csprun[ud >> 6];
            int fbprun = Center1.Csprun[fb >> 6];
            int rlprun = Center1.Csprun[rl >> 6];

            p1SolsCnt = 0;
            arr2idx   = 0;
            p1sols.Clear();

            for (length1 = Math.Min(Math.Min(udprun, fbprun), rlprun); length1 < 100; length1++)
            {
                if (rlprun <= length1 && Search1((int)((uint)rl >> 6), rl & 0x3f, length1, -1, 0) ||
                    udprun <= length1 && Search1((int)((uint)ud >> 6), ud & 0x3f, length1, -1, 0) ||
                    fbprun <= length1 && Search1((int)((uint)fb >> 6), fb & 0x3f, length1, -1, 0))
                {
                    break;
                }
            }

            //FullCube[] p1SolsArr = p1sols.ToArray(new FullCube[0]);
            FullCube[] p1SolsArr = new FullCube[p1sols.Count];
            p1sols.CopyTo(p1SolsArr, 0);
            Array.Sort(p1SolsArr, 0, p1SolsArr.Length);

            int MAX_LENGTH2 = 9;
            int length12;

            do
            {
                for (length12 = p1SolsArr[0].Value; length12 < 100; length12++)
                {
                    for (int i = 0; i < p1SolsArr.Length; i++)
                    {
                        if (p1SolsArr[i].Value > length12)
                        {
                            break;
                        }
                        if (length12 - p1SolsArr[i].Length1 > MAX_LENGTH2)
                        {
                            continue;
                        }
                        c1.Copy(p1SolsArr[i]);
                        ct2.Set(c1.GetCenter(), c1.GetEdge().GetParity());
                        int s2ct = ct2.Getct();
                        int s2rl = ct2.Getrl();
                        length1 = p1SolsArr[i].Length1;
                        length2 = length12 - p1SolsArr[i].Length1;

                        if (Search2(s2ct, s2rl, length2, 28, 0))
                        {
                            goto OUT;
                        }
                    }
                }
OUT:
                MAX_LENGTH2++;
            } while (length12 == 100);

            Array.Sort(arr2, 0, arr2idx);
            int length123, index = 0;
            int solcnt = 0;

            int MAX_LENGTH3 = 13;

            do
            {
                for (length123 = arr2[0].Value; length123 < 100; length123++)
                {
                    for (int i = 0; i < Math.Min(arr2idx, PHASE3_ATTEMPTS); i++)
                    {
                        if (arr2[i].Value > length123)
                        {
                            break;
                        }
                        if (length123 - arr2[i].Length1 - arr2[i].Length2 > MAX_LENGTH3)
                        {
                            continue;
                        }
                        int eparity = e12.Set(arr2[i].GetEdge());
                        ct3.Set(arr2[i].GetCenter(), eparity ^ arr2[i].GetCorner().GetParity());
                        int ct   = ct3.Getct();
                        int edge = e12.Get(10);
                        int prun = Edge3.Getprun(e12.Getsym());
                        int lm   = 20;

                        if (prun <= length123 - arr2[i].Length1 - arr2[i].Length2 &&
                            Search3(edge, ct, prun, length123 - arr2[i].Length1 - arr2[i].Length2, lm, 0))
                        {
                            solcnt++;
                            index = i;
                            goto OUT2;
                        }
                    }
                }
OUT2:
                MAX_LENGTH3++;
            } while (length123 == 100);

            FullCube solcube = new FullCube(arr2[index]);

            length1 = solcube.Length1;
            length2 = solcube.Length2;
            int length = length123 - length1 - length2;

            for (int i = 0; i < length; i++)
            {
                solcube.Move(Move3std[move3[i]]);
            }

            string facelet = solcube.To333Facelet();
            string sol     = search333.Solution(facelet, 20, 100, 50, 0);

            if (sol.StartsWith("Error 8"))
            {
                sol = search333.Solution(facelet, 21, 1000000, 30, 0);
            }
            int len333 = sol.Length / 3;

            if (sol.StartsWith("Error"))
            {
                throw new Exception();
            }
            int[] sol333 = Util.Tomove(sol);
            for (int i = 0; i < sol333.Length; i++)
            {
                solcube.Move(sol333[i]);
            }

            StringBuilder str = new StringBuilder();

            str.Append(solcube.GetMoveString(InverseSolution, WithRotation));

            solution = str.ToString();

            totlen = length1 + length2 + length + len333;
        }
Пример #10
0
        public static void CreatePrun()
        {
            Edge3 e = new Edge3();
            Edge3 f = new Edge3();
            Edge3 g = new Edge3();

            ArrayExtension.Fill(eprun, -1);

            int depth = 0;

            done = 1;
            SetPruning(eprun, 0, 0);

            while (done != N_EPRUN)
            {
                bool inv    = depth > 9;
                int  depm3  = depth % 3;
                int  dep1m3 = (depth + 1) % 3;
                int  find   = inv ? 0x3 : depm3;
                int  chk    = inv ? depm3 : 0x3;

                if (depth >= MAX_DEPTH - 1)
                {
                    break;
                }

                for (int i_ = 0; i_ < N_EPRUN; i_ += 16)
                {
                    int val = eprun[i_ >> 4];
                    if (!inv && val == -1)
                    {
                        continue;
                    }
                    for (int i = i_, end = i_ + 16; i < end; i++, val >>= 2)
                    {
                        if ((val & 0x3) != find)
                        {
                            continue;
                        }
                        int symcord1 = i / N_RAW;
                        int cord1    = sym2raw[symcord1];
                        int cord2    = i % N_RAW;
                        e.Set(cord1 * N_RAW + cord2);

                        for (int m = 0; m < 17; m++)
                        {
                            int cord1x    = Getmvrot(e.Edge, m << 3, 4);
                            int symcord1x = Raw2sym[cord1x];
                            int symx      = symcord1x & 0x7;
                            symcord1x >>= 3;
                            int cord2x = Getmvrot(e.Edge, m << 3 | symx, 10) % N_RAW;
                            int idx    = symcord1x * N_RAW + cord2x;
                            if (GetPruning(eprun, idx) != chk)
                            {
                                continue;
                            }
                            SetPruning(eprun, inv ? i : idx, dep1m3);
                            done++;

                            if (inv)
                            {
                                break;
                            }
                            char symState = symstate[symcord1x];
                            if (symState == 1)
                            {
                                continue;
                            }
                            f.Set(e);
                            f.Move(m);
                            f.Rotate(symx);
                            for (int j = 1; (symState >>= 1) != 0; j++)
                            {
                                if ((symState & 1) != 1)
                                {
                                    continue;
                                }
                                g.Set(f);
                                g.Rotate(j);
                                int idxx = symcord1x * N_RAW + g.Get(10) % N_RAW;
                                if (GetPruning(eprun, idxx) == chk)
                                {
                                    SetPruning(eprun, idxx, dep1m3);
                                    done++;
                                }
                            }
                        }
                    }
                }
                depth++;
            }
        }