internal static void InitTwistSym2Raw()
        {
            CubieCube c = new CubieCube();
            CubieCube d = new CubieCube();

            int[] occ   = new int[2187 / 32 + 1];
            int   count = 0;

            for (int i = 0; i < 2187 / 32 + 1; occ[i++] = 0)
            {
                ;
            }
            TwistR2S = new char[2187];
            for (int i = 0; i < 2187; i++)
            {
                if ((occ[i >> 5] & (1 << (i & 0x1f))) == 0)
                {
                    c.SetTwist(i);
                    for (int s = 0; s < 16; s += 2)
                    {
                        CornConjugate(c, s, d);
                        int idx = d.GetTwist();
                        if (idx == i)
                        {
                            SymStateTwist[count] |= (char)(1 << (s >> 1));
                        }
                        occ[idx >> 5] |= 1 << (idx & 0x1f);
                        TwistR2S[idx]  = (char)((count << 3) | (s >> 1));
                    }
                    TwistS2R[count++] = (char)i;
                }
            }
        }
        internal static void InitFlipSym2Raw()
        {
            CubieCube c = new CubieCube();
            CubieCube d = new CubieCube();

            int[] occ   = new int[2048 >> 5];
            int   count = 0;

            for (int i = 0; i < 2048 >> 5; occ[i++] = 0)
            {
                ;
            }
            FlipR2S = new char[2048];
            for (int i = 0; i < 2048; i++)
            {
                if ((occ[i >> 5] & (1 << (i & 0x1f))) == 0)
                {
                    c.SetFlip(i);
                    for (int s = 0; s < 16; s += 2)
                    {
                        EdgeConjugate(c, s, d);
                        int idx = d.GetFlip();
                        if (idx == i)
                        {
                            SymStateFlip[count] |= (char)(1 << (s >> 1));
                        }
                        occ[idx >> 5] |= 1 << (idx & 0x1f);
                        FlipR2S[idx]   = (char)((count << 3) | (s >> 1));
                    }
                    FlipS2R[count++] = (char)i;
                }
            }
        }
Example #3
0
 internal static string ToFaceCube(CubieCube cc)
 {
     char[] f  = new char[54];
     char[] ts = { 'U', 'R', 'F', 'D', 'L', 'B' };
     for (int i = 0; i < 54; i++)
     {
         f[i] = ts[i / 9];
     }
     for (sbyte c = 0; c < 8; c++)
     {
         sbyte j = cc.CP[c];   // cornercubie with index j is at
                               // cornerposition with index c
         sbyte ori = cc.CO[c]; // Orientation of this cubie
         for (sbyte n = 0; n < 3; n++)
         {
             f[CornerFacelet[c][(n + ori) % 3]] = ts[CornerFacelet[j][n] / 9];
         }
     }
     for (sbyte e = 0; e < 12; e++)
     {
         sbyte j = cc.EP[e];   // edgecubie with index j is at edgeposition
                               // with index e
         sbyte ori = cc.EO[e]; // Orientation of this cubie
         for (sbyte n = 0; n < 2; n++)
         {
             f[EdgeFacelet[e][(n + ori) % 2]] = ts[EdgeFacelet[j][n] / 9];
         }
     }
     return(new string(f));
 }
Example #4
0
        internal static void InitUDSliceMoveConj()
        {
            CubieCube c = new CubieCube();
            CubieCube d = new CubieCube();

            for (int i = 0; i < N_SLICE; i++)
            {
                c.SetUDSlice(i);
                for (int j = 0; j < N_MOVES; j += 3)
                {
                    CubieCube.EdgeMult(c, CubieCube.MoveCube[j], d);
                    UDSliceMove[i][j] = (char)d.GetUDSlice();
                }
                for (uint j = 0; j < 16; j += 2)
                {
                    CubieCube.EdgeConjugate(c, CubieCube.SymInv[j], d);
                    UDSliceConj[i][j >> 1] = (char)(d.GetUDSlice() & 0x1ff);
                }
            }
            for (int i = 0; i < N_SLICE; i++)
            {
                for (int j = 0; j < N_MOVES; j += 3)
                {
                    int udslice = UDSliceMove[i][j];
                    for (int k = 1; k < 3; k++)
                    {
                        int cx = UDSliceMove[udslice & 0x1ff][j];
                        udslice = Util.PermMult[(uint)udslice >> 9][((uint)cx >> 9)] << 9 | cx & 0x1ff;
                        UDSliceMove[i][j + k] = (char)(udslice);
                    }
                }
            }
        }
Example #5
0
        internal static void ToCubieCube(sbyte[] f, CubieCube ccRet)
        {
            sbyte ori;

            for (int i = 0; i < 8; i++)
            {
                ccRet.CP[i] = 0;// invalidate corners
            }
            for (int i = 0; i < 12; i++)
            {
                ccRet.EP[i] = 0;// and edges
            }
            sbyte col1, col2;

            for (sbyte i = 0; i < 8; i++)
            {
                // get the colors of the cubie at corner i, starting with U/D
                for (ori = 0; ori < 3; ori++)
                {
                    if (f[CornerFacelet[i][ori]] == U || f[CornerFacelet[i][ori]] == D)
                    {
                        break;
                    }
                }
                col1 = f[CornerFacelet[i][(ori + 1) % 3]];
                col2 = f[CornerFacelet[i][(ori + 2) % 3]];

                for (sbyte j = 0; j < 8; j++)
                {
                    if (col1 == CornerFacelet[j][1] / 9 && col2 == CornerFacelet[j][2] / 9)
                    {
                        // in cornerposition i we have cornercubie j
                        ccRet.CP[i] = j;
                        ccRet.CO[i] = (sbyte)(ori % 3);
                        break;
                    }
                }
            }
            for (sbyte i = 0; i < 12; i++)
            {
                for (sbyte j = 0; j < 12; j++)
                {
                    if (f[EdgeFacelet[i][0]] == EdgeFacelet[j][0] / 9 &&
                        f[EdgeFacelet[i][1]] == EdgeFacelet[j][1] / 9)
                    {
                        ccRet.EP[i] = j;
                        ccRet.EO[i] = 0;
                        break;
                    }
                    if (f[EdgeFacelet[i][0]] == EdgeFacelet[j][1] / 9 &&
                        f[EdgeFacelet[i][1]] == EdgeFacelet[j][0] / 9)
                    {
                        ccRet.EP[i] = j;
                        ccRet.EO[i] = 1;
                        break;
                    }
                }
            }
        }
 internal static void EdgeMult(CubieCube a, CubieCube b, CubieCube prod)
 {
     for (int ed = 0; ed < 12; ed++)
     {
         prod.EP[ed] = a.EP[b.EP[ed]];
         prod.EO[ed] = (sbyte)(b.EO[ed] ^ a.EO[b.EP[ed]]);
     }
 }
 internal void URFConjugate()
 {
     if (temps == null)
     {
         temps = new CubieCube();
     }
     CornMult(URF2, this, temps);
     CornMult(temps, URF1, this);
     EdgeMult(URF2, this, temps);
     EdgeMult(temps, URF1, this);
 }
        internal static void EdgeConjugate(CubieCube a, int idx, CubieCube b)
        {
            CubieCube sinv = CubeSym[SymInv[idx]];
            CubieCube s    = CubeSym[idx];

            for (int ed = 0; ed < 12; ed++)
            {
                b.EP[ed] = sinv.EP[a.EP[s.EP[ed]]];
                b.EO[ed] = (sbyte)(s.EO[ed] ^ a.EO[s.EP[ed]] ^ sinv.EO[a.EP[s.EP[ed]]]);
            }
        }
        internal static void CornConjugate(CubieCube a, int idx, CubieCube b)
        {
            CubieCube sinv = CubeSym[SymInv[idx]];
            CubieCube s    = CubeSym[idx];

            for (int corn = 0; corn < 8; corn++)
            {
                b.CP[corn] = sinv.CP[a.CP[s.CP[corn]]];
                sbyte oriA = sinv.CO[a.CP[s.CP[corn]]];
                sbyte oriB = a.CO[s.CP[corn]];
                b.CO[corn] = (oriA < 3) ? oriB : (sbyte)((3 - oriB) % 3);
            }
        }
 private void Copy(CubieCube c)
 {
     for (int i = 0; i < 8; i++)
     {
         CP[i] = c.CP[i];
         CO[i] = c.CO[i];
     }
     for (int i = 0; i < 12; i++)
     {
         EP[i] = c.EP[i];
         EO[i] = c.EO[i];
     }
 }
Example #11
0
        internal static void InitFlipMove()
        {
            CubieCube c = new CubieCube();
            CubieCube d = new CubieCube();

            for (int i = 0; i < N_FLIP_SYM; i++)
            {
                c.SetFlip(CubieCube.FlipS2R[i]);
                for (int j = 0; j < N_MOVES; j++)
                {
                    CubieCube.EdgeMult(c, CubieCube.MoveCube[j], d);
                    FlipMove[i][j] = (char)d.GetFlipSym();
                }
            }
        }
Example #12
0
        internal static void InitTwistMove()
        {
            CubieCube c = new CubieCube();
            CubieCube d = new CubieCube();

            for (int i = 0; i < N_TWIST_SYM; i++)
            {
                c.SetTwist(CubieCube.TwistS2R[i]);
                for (int j = 0; j < N_MOVES; j++)
                {
                    CubieCube.CornMult(c, CubieCube.MoveCube[j], d);
                    TwistMove[i][j] = (char)d.GetTwistSym();
                }
            }
        }
Example #13
0
        internal static void InitCPermMove()
        {
            CubieCube c = new CubieCube();
            CubieCube d = new CubieCube();

            for (int i = 0; i < N_PERM_SYM; i++)
            {
                c.SetCPerm(CubieCube.EPermS2R[i]);
                for (int j = 0; j < N_MOVES; j++)
                {
                    CubieCube.CornMult(c, CubieCube.MoveCube[j], d);
                    CPermMove[i][j] = (char)d.GetCPermSym();
                }
            }
        }
Example #14
0
        internal static void InitEPermMove()
        {
            CubieCube c = new CubieCube();
            CubieCube d = new CubieCube();

            for (int i = 0; i < N_PERM_SYM; i++)
            {
                c.SetEPerm(CubieCube.EPermS2R[i]);
                for (int j = 0; j < N_MOVES2; j++)
                {
                    CubieCube.EdgeMult(c, CubieCube.MoveCube[Util.Ud2std[j]], d);
                    EPermMove[i][j] = (char)d.GetEPermSym();
                }
            }
        }
 internal static void CornMult(CubieCube a, CubieCube b, CubieCube prod)
 {
     for (int corn = 0; corn < 8; corn++)
     {
         prod.CP[corn] = a.CP[b.CP[corn]];
         sbyte oriA = a.CO[b.CP[corn]];
         sbyte oriB = b.CO[corn];
         sbyte ori  = oriA;
         ori += (oriA < 3) ? oriB : (sbyte)(6 - oriB);
         ori %= 3;
         if ((oriA >= 3) ^ (oriB >= 3))
         {
             ori += 3;
         }
         prod.CO[corn] = ori;
     }
 }
        // ********************************************* Initialization functions *********************************************

        internal static void InitMove()
        {
            MoveCube[0]  = new CubieCube(15120, 0, 119750400, 0);
            MoveCube[3]  = new CubieCube(21021, 1494, 323403417, 0);
            MoveCube[6]  = new CubieCube(8064, 1236, 29441808, 550);
            MoveCube[9]  = new CubieCube(9, 0, 5880, 0);
            MoveCube[12] = new CubieCube(1230, 412, 2949660, 0);
            MoveCube[15] = new CubieCube(224, 137, 328552, 137);
            for (int a = 0; a < 18; a += 3)
            {
                for (int p = 0; p < 2; p++)
                {
                    MoveCube[a + p + 1] = new CubieCube();
                    EdgeMult(MoveCube[a + p], MoveCube[a], MoveCube[a + p + 1]);
                    CornMult(MoveCube[a + p], MoveCube[a], MoveCube[a + p + 1]);
                }
            }
        }
Example #17
0
        internal static void InitMPermMoveConj()
        {
            CubieCube c = new CubieCube();
            CubieCube d = new CubieCube();

            for (int i = 0; i < N_MPERM; i++)
            {
                c.SetMPerm(i);
                for (int j = 0; j < N_MOVES2; j++)
                {
                    CubieCube.EdgeMult(c, CubieCube.MoveCube[Util.Ud2std[j]], d);
                    MPermMove[i][j] = (char)d.GetMPerm();
                }
                for (int j = 0; j < 16; j++)
                {
                    CubieCube.EdgeConjugate(c, CubieCube.SymInv[j], d);
                    MPermConj[i][j] = (char)d.GetMPerm();
                }
            }
        }
Example #18
0
        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
            }
        }
 internal int GetTwistSym()
 {
     if (TwistR2S != null)
     {
         return(TwistR2S[GetTwist()]);
     }
     if (temps == null)
     {
         temps = new CubieCube();
     }
     for (int k = 0; k < 16; k += 2)
     {
         CornConjugate(this, SymInv[k], temps);
         int idx = Util.BinarySearch(TwistS2R, temps.GetTwist());
         if (idx != 0xffff)
         {
             return((idx << 3) | (k >> 1));
         }
     }
     return(0);
 }
 internal int GetEPermSym()
 {
     if (EPermR2S != null)
     {
         return(EPermR2S[GetEPerm()]);
     }
     if (temps == null)
     {
         temps = new CubieCube();
     }
     for (int k = 0; k < 16; k++)
     {
         EdgeConjugate(this, SymInv[k], temps);
         int idx = Util.BinarySearch(EPermS2R, temps.GetEPerm());
         if (idx != 0xffff)
         {
             return((idx << 4) | k);
         }
     }
     return(0);
 }
 internal int GetCPermSym()
 {
     if (EPermR2S != null)
     {
         int idx = EPermR2S[GetCPerm()];
         idx ^= E2C[idx & 0x0f];
         return(idx);
     }
     if (temps == null)
     {
         temps = new CubieCube();
     }
     for (int k = 0; k < 16; k++)
     {
         CornConjugate(this, SymInv[k], temps);
         int idx = Util.BinarySearch(EPermS2R, temps.GetCPerm());
         if (idx != 0xffff)
         {
             return((idx << 4) | k);
         }
     }
     return(0);
 }
        internal static void InitPermSym2Raw()
        {
            CubieCube c = new CubieCube();
            CubieCube d = new CubieCube();

            int[] occ   = new int[40320 / 32];
            int   count = 0;

            for (int i = 0; i < 40320 / 32; occ[i++] = 0)
            {
                ;
            }
            EPermR2S = new char[40320];
            for (int i = 0; i < 40320; i++)
            {
                if ((occ[i >> 5] & (1 << (i & 0x1f))) == 0)
                {
                    c.SetEPerm(i);
                    for (int s = 0; s < 16; s++)
                    {
                        EdgeConjugate(c, s, d);
                        int idx = d.GetEPerm();
                        if (idx == i)
                        {
                            SymStatePerm[count] |= (char)(1 << s);
                        }
                        occ[idx >> 5] |= 1 << (idx & 0x1f);
                        int a = d.GetU4Comb();
                        int b = d.GetD4Comb() >> 9;
                        int m = 494 - (a & 0x1ff) + (a >> 9) * 70 + b * 1680;
                        MtoEPerm[m] = EPermR2S[idx] = (char)(count << 4 | s);
                    }
                    EPermS2R[count++] = (char)i;
                }
            }
        }
Example #23
0
        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);
        }
 internal CubieCube(CubieCube c)
 {
     Copy(c);
 }
        internal static void InitSym()
        {
            CubieCube c = new CubieCube();
            CubieCube d = new CubieCube();
            CubieCube t;

            CubieCube f2  = new CubieCube(28783, 0, 259268407, 0);
            CubieCube u4  = new CubieCube(15138, 0, 119765538, 7);
            CubieCube lr2 = new CubieCube(5167, 0, 83473207, 0);

            lr2.CO = new sbyte[] { 3, 3, 3, 3, 3, 3, 3, 3 };

            for (int i = 0; i < 16; i++)
            {
                CubeSym[i] = new CubieCube(c);
                CornMult(c, u4, d);
                EdgeMult(c, u4, d);
                t = d; d = c; c = t;
                if (i % 4 == 3)
                {
                    CornMult(c, lr2, d);
                    EdgeMult(c, lr2, d);
                    t = d; d = c; c = t;
                }
                if (i % 8 == 7)
                {
                    CornMult(c, f2, d);
                    EdgeMult(c, f2, d);
                    t = d; d = c; c = t;
                }
            }
            for (int i = 0; i < 16; i++)
            {
                for (int j = 0; j < 16; j++)
                {
                    CornMult(CubeSym[i], CubeSym[j], c);
                    for (int k = 0; k < 16; k++)
                    {
                        if (CubeSym[k].CP[0] == c.CP[0] && CubeSym[k].CP[1] == c.CP[1] && CubeSym[k].CP[2] == c.CP[2])
                        {
                            SymMult[i][j] = k;
                            if (k == 0)
                            {
                                SymInv[i] = j;
                            }
                            break;
                        }
                    }
                }
            }
            for (int j = 0; j < 18; j++)
            {
                for (int s = 0; s < 16; s++)
                {
                    CornConjugate(MoveCube[j], SymInv[s], c);
                    for (int m = 0; m < 18; m++)
                    {
                        for (int i = 0; i < 8; i += 2)
                        {
                            if (c.CP[i] != MoveCube[m].CP[i])
                            {
                                goto CONTINUE;
                            }
                        }
                        SymMove[s][j] = m;
                        break;
                        CONTINUE : { }
                    }
                }
            }
            for (int j = 0; j < 10; j++)
            {
                for (int s = 0; s < 16; s++)
                {
                    SymMoveUD[s][j] = Util.Std2ud[SymMove[s][Util.Ud2std[j]]];
                }
            }
            for (int j = 0; j < 8; j++)
            {
                for (int s = 0; s < 8; s++)
                {
                    Sym8Mult[j][s]    = SymMult[j << 1][s << 1] >> 1;
                    Sym8MultInv[j][s] = SymMult[j << 1][SymInv[s << 1]] >> 1;
                }
            }
            for (int j = 0; j < 18; j++)
            {
                for (int s = 0; s < 8; s++)
                {
                    Sym8Move[s][j] = SymMove[s << 1][j];
                }
            }
        }