Пример #1
0
        public static ImmutableArray <ushort> Create()
        {
            var udEdgesConj = new ushort[NUdEdges * NSymD4H];

            for (var t = 0; t < 0 + NUdEdges; t++)
            {
                if ((t + 1) % 400 == 0)
                {
                    Console.Write(".");
                }
                if ((t + 1) % 32000 == 0)
                {
                    Console.WriteLine("");
                }
                var cc = SolvedCube.Instance.Clone();

                cc.set_ud_edges(t);
                for (var s = 0; s < 0 + NSymD4H; s++)
                {
                    var ss = Basic.Cubes[s].Clone();
                    ss.EdgeMultiply(cc);
                    ss.EdgeMultiply(Inverse.GetCube(s));
                    udEdgesConj[NSymD4H * t + s] = Convert.ToUInt16(ss.get_ud_edges()); //TODO remove all these
                }
            }

            return(udEdgesConj.ToImmutableArray());
        }
Пример #2
0
        public void InversesShouldMultiplyToSolvedCube(int i)
        {
            var sym = Basic.Cubes[i].Clone();
            var inv = Inverse.GetCube(i);

            sym.Multiply(inv);

            sym.Should().Be(SolvedCube.Instance);
        }
Пример #3
0
        /// <summary>
        /// Get the symmetries and antisymmetries of the cube
        /// </summary>
        public static IEnumerable <int> Symmetries(this ICubieCube cubieCube)
        {
            for (var j = 0; j < Definitions.NSym; j++)
            {
                var c = Basic.Cubes[j].Clone();
                c.Multiply(cubieCube);
                c.Multiply(Inverse.GetCube(j));

                if (CubeComparer.Instance.Equals(cubieCube, c))
                {
                    yield return(j);
                }
                var d = c.Invert();

                if (CubeComparer.Instance.Equals(cubieCube, d))
                {
                    yield return(j + Definitions.NSym);
                }
            }
        }
Пример #4
0
        /// <summary>
        /// Creates the new table in memory
        /// </summary>
        /// <returns></returns>
        public override uint[] Create()
        {
            const int total = NCornersClass * NUdEdges;
            var       table = new uint[total / 16];

            Array.Fill(table, uint.MaxValue);

            // ##################### create table with the symmetries of the corners classes ################################
            var cc   = SolvedCube.Instance.Clone();
            var cSym = new ushort[NCornersClass];

            for (var i = 0; i < 0 + NCornersClass; i++)
            {
                if ((i + 1) % 1000 == 0)
                {
                    Console.Write(".");
                }
                var rep = CornerSymmetries.CornerRep[i];
                cc.set_corners(rep);

                for (byte s = 0; s < NSymD4H; s++)
                {
                    var ss = Basic.Cubes[s].Clone();
                    ss.CornerMultiply(cc);
                    ss.CornerMultiply(Inverse.GetCube(s));
                    if (ss.get_corners() == rep)
                    {
                        const ushort u = 1;
                        var          q = Convert.ToUInt16(u << s);
                        cSym[i] |= q;
                    }
                }
            }

            Console.WriteLine();
            //###############################################################################################################
            var udEdge = 0;

            set_corners_ud_edges_depth3(NUdEdges * 0 + udEdge, 0, table);
            var  done  = 1;
            uint depth = 0;

            Console.WriteLine($"depth: {depth} done: {done}/{total}");
            while (depth < 10)
            {
                // we fill the table only do depth 9 + 1
                var depth3 = depth % 3;
                var idx    = 0;
                var mult   = 2;
                if (depth > 9)
                {
                    mult = 1;
                }

                for (var cClassIndex = 0; cClassIndex < NCornersClass; cClassIndex++)
                {
                    {
                        if ((cClassIndex + 1) % (20 * mult) == 0)
                        {
                            Console.Write(".");
                        }

                        if ((cClassIndex + 1) % (1600 * mult) == 0)
                        {
                            Console.WriteLine("");
                        }

                        udEdge = 0;
                        while (udEdge < NUdEdges)
                        {
                            // ################ if table entries are not populated, this is very fast: ##########################
                            if (idx % 16 == 0 && table[idx / 16] == uint.MaxValue && udEdge < NUdEdges - 16)
                            {
                                udEdge += 16;
                                idx    += 16;
                                continue;
                            }

                            //###################################################################################################
                            if (get_corners_ud_edges_depth3(idx, table) == depth3)
                            {
                                var corner = CornerSymmetries.CornerRep[cClassIndex];
                                // only iterate phase 2 SpecialMoves
                                foreach (var m in Phase2MoveEnums)
                                {
                                    var udEdge1      = SpecialMoves.UdEdgesMove[18 * udEdge + (int)m];
                                    var corner1      = SpecialMoves.CornersMove[18 * corner + (int)m];
                                    var c1ClassIndex = CornerSymmetries.CornerClassidx[corner1];
                                    var c1Sym        = CornerSymmetries.CornerSym[corner1];
                                    udEdge1 = UdEdges.GetUdEdgesConj(udEdge1, c1Sym);// Symmetries.UdEdgesConjugation.UdEdgesConj[(udEdge1 << 4) + c1Sym];
                                    var idx1 = 40320 * c1ClassIndex + udEdge1;
                                    if (get_corners_ud_edges_depth3(idx1, table) == 3)
                                    {
                                        // entry not yet filled
                                        set_corners_ud_edges_depth3(idx1, (depth + 1) % 3, table);
                                        done += 1;
                                        // ######symmetric position has eventually more than one representation #############
                                        var sym = cSym[c1ClassIndex];
                                        if (sym != 1)
                                        {
                                            for (byte j = 1; j < 16; j++)
                                            {
                                                sym >>= 1;
                                                if (sym % 2 == 1)
                                                {
                                                    var udEdge2 = UdEdges.GetUdEdgesConj(udEdge1, j);
                                                    // c1_classidx does not change
                                                    var idx2 = 40320 * c1ClassIndex + udEdge2;
                                                    if (get_corners_ud_edges_depth3(idx2, table) == 3)
                                                    {
                                                        set_corners_ud_edges_depth3(idx2, (depth + 1) % 3, table);
                                                        done += 1;
                                                        //###################################################################################
                                                    }
                                                }
                                            }
                                        }
                                    }
                                }
                            }

                            udEdge += 1;
                            idx    += 1;
                        }
                    }
                }

                depth += 1;
                Console.WriteLine();
                Console.WriteLine($"depth: {depth} done: {done}/{total}");
            }

            return(table);
        }
Пример #5
0
        public override uint[] Create()
        {
            const int total = NFlipsliceClass * NTwist;

            var table = new uint[total / 16 + 1];

            Array.Fill(table, uint.MaxValue);

            // #################### create table with the symmetries of the flipslice classes ###############################
            var cc    = SolvedCube.Instance.Clone();
            var fsSym = new int[NFlipsliceClass];


            for (var i = 0; i < NFlipsliceClass; i++)
            {
                if ((i + 1) % 1000 == 0)
                {
                    Console.Write(".");
                }

                var rep        = FlipSlice.FlipsliceRep[i];
                var repModFlip = Convert.ToInt32(rep % NFlip);

                cc.set_slice(Convert.ToUInt16(rep / NFlip));
                cc.set_flip(repModFlip);
                for (var s = 0; s < NSymD4H; s++)
                {
                    var ss = Basic.Cubes[s].Clone();
                    ss.EdgeMultiply(cc);
                    ss.EdgeMultiply(Inverse.GetCube(s));
                    if (ss.get_slice() == rep / NFlip && ss.get_flip() == repModFlip)
                    {
                        fsSym[i] |= 1 << s;
                    }
                }
            }

            Console.WriteLine();
            // ##################################################################################################################

            var twist = 0;

            set_flipslice_twist_depth3(NTwist * 0 + twist, 0, table);
            var  done       = 1;
            uint depth      = 0;
            var  backSearch = false;

            Console.WriteLine($"depth: {depth} done: {done}/{total}");
            while (done < total)
            {
                var depth3 = depth % 3;
                if (depth == 9)
                {
                    // backwards search is faster for depth >= 9
                    Console.WriteLine("flipping to backwards search...");
                    backSearch = true;
                }

                var mult = depth < 8 ? 5 : 1;

                var idx = 0;
                for (var fsClassidx = 0; fsClassidx < NFlipsliceClass; fsClassidx++)
                {
                    if ((fsClassidx + 1) % (200 * mult) == 0)
                    {
                        Console.Write(".");
                    }
                    if ((fsClassidx + 1) % (16000 * mult) == 0)
                    {
                        Console.WriteLine("");
                    }
                    twist = 0;
                    while (twist < NTwist)
                    {
                        // ########## if table entries are not populated, this is very fast: ################################
                        if (!backSearch && idx % 16 == 0 && table[idx / 16] == uint.MaxValue &&
                            twist < NTwist - 16)
                        {
                            twist += 16;
                            idx   += 16;
                            continue;
                        }

                        //###################################################################################################
                        bool match;
                        if (backSearch)
                        {
                            match = get_flipslice_twist_depth3(idx, table) == 3;
                        }
                        else
                        {
                            match = get_flipslice_twist_depth3(idx, table) == depth3;
                        }

                        if (match)
                        {
                            var flipslice = FlipSlice.FlipsliceRep[fsClassidx];
                            var flip      = Convert.ToInt32(flipslice % 2048);
                            var slice     = Convert.ToInt32(flipslice >> 11);
                            foreach (var m in Extensions.GetEnumValues <Move>())
                            {
                                var twist1      = SpecialMoves.TwistMove[18 * twist + (int)m];
                                var flip1       = SpecialMoves.FlipMove[18 * flip + (int)m];
                                var slice1      = SpecialMoves.SliceSortedMove[432 * slice + (int)m] / 24;
                                var flipslice1  = (slice1 << 11) + flip1;
                                var fs1Classidx = FlipSlice.FlipsliceClassidx[flipslice1];
                                var fs1Sym      = FlipSlice.FlipsliceSym[flipslice1];
                                twist1 = ConjTwist.GetTwistConj(twist1, fs1Sym);
                                var idx1 = Convert.ToInt32(2187 * fs1Classidx + twist1);
                                if (!backSearch)
                                {
                                    if (get_flipslice_twist_depth3(idx1, table) == 3)
                                    {
                                        // entry not yet filled
                                        set_flipslice_twist_depth3(idx1, (depth + 1) % 3, table);
                                        done += 1;
                                        // ####symmetric position has eventually more than one representation ###############
                                        var sym = fsSym[fs1Classidx];
                                        if (sym != 1)
                                        {
                                            for (byte j = 1; j < 16; j++)
                                            {
                                                sym >>= 1;
                                                if (sym % 2 == 1)
                                                {
                                                    var twist2 = ConjTwist.GetTwistConj(twist1, j);
                                                    // fs2_classidx = fs1_classidx due to symmetry
                                                    var idx2 = Convert.ToInt32(2187 * fs1Classidx + twist2);
                                                    if (get_flipslice_twist_depth3(idx2, table) == 3)
                                                    {
                                                        set_flipslice_twist_depth3(idx2, (depth + 1) % 3, table);
                                                        done += 1;
                                                    }
                                                }
                                            }
                                        }
                                    }
                                }
                                else
                                {
                                    // backwards search
                                    if (get_flipslice_twist_depth3(idx1, table) == depth3)
                                    {
                                        set_flipslice_twist_depth3(idx, (depth + 1) % 3, table);
                                        done += 1; //this doesn't seem to be working
                                        break;
                                    }
                                }
                            }
                        }

                        twist += 1;
                        idx   += 1;
                    }
                }

                depth += 1;
                Console.WriteLine();
                Console.WriteLine($"depth: {depth} done: {done}/{total}");
            }

            return(table);
        }