예제 #1
0
        public void PermutedCubesTest()
        {
            //make sure that every cube is unique and no cube is null
            for (int index = 0; index < Symmetries.NumSymmetries;
                 index++)
            {
                Assert.IsNotNull(Symmetries.SymmetryCubes[index]);
                for (int prev = 0; prev < index; prev++)
                {
                    Assert.AreNotEqual(Symmetries.SymmetryCubes[prev],
                                       Symmetries.SymmetryCubes[index]);
                }
            }

            CubieCube expected = CubieCube.CreateSolved();

            expected.Mirror(Axis.x);
            Assert.AreEqual(expected, Symmetries.SymmetryCubes[1]);

            expected = CubieCube.CreateSolved();
            expected.Rotate(Rotation.y1);
            Assert.AreEqual(expected, Symmetries.SymmetryCubes[2]);

            expected = CubieCube.CreateSolved();
            expected.Rotate(Rotation.z2);
            Assert.AreEqual(expected, Symmetries.SymmetryCubes[8]);

            expected = CubieCube.CreateSolved();
            expected.Rotate(Rotation.x1);
            expected.Rotate(Rotation.y1);
            Assert.AreEqual(expected, Symmetries.SymmetryCubes[16]);
        }
예제 #2
0
        public static FaceCube ToFaceCube(this CubieCube cubieCube)
        {
            var faceCube = new FaceCube();

            for (var i = 0; i < cubieCube.CO.Length; i++)
            {
                int perm = (int)cubieCube.CP[i];
                int ori  = cubieCube.CO[i];

                for (int j = 0; j < 3; j++)
                {
                    faceCube.Facelets[(int)Defs.CornerFacelet[i][(j + ori) % 3]] = Defs.CornerColor[perm][j];
                }
            }
            for (var i = 0; i < cubieCube.EO.Length; i++)
            {
                int perm = (int)cubieCube.EP[i];
                int ori  = cubieCube.EO[i];

                for (int j = 0; j < 2; j++)
                {
                    faceCube.Facelets[(int)Defs.EdgeFacelet[i][(j + ori) % 2]] = Defs.EdgeColor[perm][j];
                }
            }
            return(faceCube);
        }
예제 #3
0
        /// <summary>
        /// Create a move table for U- and D-edge order. Only valid for cubes
        /// in the subgroup G1.
        /// </summary>
        /// <returns>
        /// A move table for U- and D-edge order.
        /// </returns>
        public static ushort[,] CreateUdEdgeOrderMoveTable()
        {
            ushort[,] udEdgeOrderMoveTable = new ushort[Coordinates.NumUdEdgeOrders, TwoPhaseConstants.NumMovesPhase2];

            //invalidate table
            for (int udEdgeOrder = 0; udEdgeOrder < Coordinates.NumUdEdgeOrders; udEdgeOrder++)
            {
                for (int move = 0; move < TwoPhaseConstants.NumMovesPhase2; move++)
                {
                    udEdgeOrderMoveTable[udEdgeOrder, move] = ushort.MaxValue;
                }
            }

            //populate table
            for (int udEdgeOrder = 0; udEdgeOrder < Coordinates.NumCornerPermutations; udEdgeOrder++)
            {
                for (int face = 0; face < NumFaces; face++)
                {
                    CubieCube cube = CubieCube.CreateSolved();
                    Coordinates.SetUdEdgeOrder(cube, udEdgeOrder);
                    for (int move = 0; move < 3; move++)
                    {
                        cube.MultiplyEdges(CubieCube.MovesArray[face * 3]);
                        if (TwoPhaseConstants.Phase2Moves.Contains((Move)(face * 3 + move)))
                        {
                            udEdgeOrderMoveTable[udEdgeOrder, Phase1IndexToPhase2Index[face * 3 + move]] = (ushort)Coordinates.GetUdEdgeOrder(cube);
                        }
                    }
                }
            }

            return(udEdgeOrderMoveTable);
        }
예제 #4
0
        public static void HaveEqualEquatorEdgePermutation(CubieCube expected, CubieCube actual)
        {
            CubingAssert.HasFourEquatorEdges(expected);
            CubingAssert.HasFourEquatorEdges(actual);

            IEnumerator <(Edge edge, int index)> enumerator1 = expected.EdgePermutation.Select((edge, index) => (edge, index)).GetEnumerator();
            IEnumerator <(Edge edge, int index)> enumerator2 = actual.EdgePermutation.Select((edge, index) => (edge, index)).GetEnumerator();

            for (int equatorEdge = 0; equatorEdge < Constants.NumEquatorEdges; equatorEdge++)
            {
                while (enumerator1.MoveNext() && enumerator1.Current.edge < Edge.FR)
                {
                    ;
                }
                while (enumerator2.MoveNext() && enumerator2.Current.edge < Edge.FR)
                {
                    ;
                }

                if (enumerator1.Current.edge != enumerator2.Current.edge)
                {
                    throw new AssertFailedException("The two cubes do not have the same equator edge permutation: " +
                                                    enumerator1.Current.edge + " at index " + enumerator1.Current.index + " of " + nameof(expected) + " is not equal to " +
                                                    enumerator2.Current.edge + " at index " + enumerator2.Current.index + " of " + nameof(actual) + ".");
                }
            }
        }
예제 #5
0
        /// <summary>
        /// Create a move table for corner permutation.
        /// </summary>
        /// <returns>
        /// A move table for corner permutation.
        /// </returns>
        public static ushort[,] CreateCornerPermutationMoveTable()
        {
            CubieCube cube = CubieCube.CreateSolved();

            ushort[,] cornerPermutationMoveTable = new ushort[Coordinates.NumCornerPermutations, NumMoves];

            //invalidate table
            for (int cornerPermutation = 0; cornerPermutation < Coordinates.NumCornerPermutations; cornerPermutation++)
            {
                for (int move = 0; move < NumMoves; move++)
                {
                    cornerPermutationMoveTable[cornerPermutation, move] = ushort.MaxValue;
                }
            }

            //populate table
            for (int cornerPermutation = 0; cornerPermutation < Coordinates.NumCornerPermutations; cornerPermutation++)
            {
                for (int face = 0; face < NumFaces; face++)
                {
                    Coordinates.SetCornerPermutation(cube, cornerPermutation);
                    for (int move = 0; move < 3; move++)
                    {
                        cube.MultiplyCorners(CubieCube.MovesArray[face * 3]);
                        cornerPermutationMoveTable[cornerPermutation, face * 3 + move] = (ushort)Coordinates.GetCornerPermutation(cube);
                    }
                }
            }

            return(cornerPermutationMoveTable);
        }
        // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
        // Generate a CoordCube from a CubieCube
        internal CoordCubeBuildTables(CubieCube c, bool unpackTables = false)
        {
            twist    = c.getTwist();
            flip     = c.getFlip();
            parity   = c.cornerParity();
            FRtoBR   = c.getFRtoBR();
            URFtoDLF = c.getURFtoDLF();
            URtoUL   = c.getURtoUL();
            UBtoDF   = c.getUBtoDF();
            URtoDF   = c.getURtoDF();// only needed in phase2

            if (unpackTables)
            {
                //Generate move tables
                Tools.SerializeTable("twist", twistMove);
                Tools.SerializeTable("flip", flipMove);
                Tools.SerializeTable("FRtoBR", FRtoBR_Move);
                Tools.SerializeTable("URFtoDLF", URFtoDLF_Move);
                Tools.SerializeTable("URtoDF", URtoDF_Move);
                Tools.SerializeTable("URtoUL", URtoUL_Move);
                Tools.SerializeTable("UBtoDF", UBtoDF_Move);
                Tools.SerializeTable("MergeURtoULandUBtoDF", MergeURtoULandUBtoDF);


                //Generate Pruning tables
                Tools.SerializeSbyteArray("Slice_URFtoDLF_Parity_Prun", Slice_URFtoDLF_Parity_Prun);
                Tools.SerializeSbyteArray("Slice_URtoDF_Parity_Prun", Slice_URtoDF_Parity_Prun);
                Tools.SerializeSbyteArray("Slice_Twist_Prun", Slice_Twist_Prun);
                Tools.SerializeSbyteArray("Slice_Flip_Prun", Slice_Flip_Prun);
            }
        }
예제 #7
0
    static FlipMoveClass()
    {
        CubieCube a = new CubieCube();

        for (short i = 0; i < CoordCube.N_FLIP; i++)
        {
            a.setFlip(i);
            for (int j = 0; j < 6; j++)
            {
                for (int k = 0; k < 3; k++)
                {
                    a.edgeMultiply(CubieCube.moveCube[j]);
                    try
                    {
                        flipMove[i, (3 * j + k)] = a.getFlip(); // [2047, 17]
                    }
                    catch (Exception e)
                    {
                        Debug.Log(e);
                        return;
                    }
                }
                a.edgeMultiply(CubieCube.moveCube[j]);
                // a
            }
        }
    }
예제 #8
0
        public void CombineUAndDEdgeCoordsTest()
        {
            Random random      = new Random(7777777);
            int    length      = 50;
            int    repetitions = 50;

            double[] phase2probabilities =
            {
                0d, 1d, 0d, 1d, 1d, 1d, 0d, 1d, 0d,
                0d, 1d, 0d, 1d, 1d, 1d, 0d, 1d, 0d
            };

            for (int repetition = 0; repetition < repetitions; repetition++)
            {
                Alg       alg  = Alg.FromRandomMoves(length, random, phase2probabilities);
                CubieCube cube = CubieCube.FromAlg(alg);

                int uEdgeCoord = Coordinates.GetUEdgePermutation(cube);
                int dEdgeCoord = Coordinates.GetDEdgePermutation(cube);
                int result     = Coordinates.CombineUEdgePermutationAndDEdgeOrder(uEdgeCoord, dEdgeCoord % Coordinates.NumDEdgeOrders);
                int expected   = Coordinates.GetUdEdgeOrder(cube);

                Assert.AreEqual(expected, result);
            }
        }
예제 #9
0
        public void EoCoordTest() //Tests GetEOCoord, SetEOCoord
        {
            Random random = new Random(7777777);
            int    length = 50;

            //if applying GetEOCoord and SetEOCoord results in the same array as at the beginning
            CubieCube expected = CubieCube.FromAlg(Alg.FromRandomMoves(length, random));
            CubieCube result   = CubieCube.CreateSolved();

            int coord = Coordinates.GetEdgeOrientation(expected);

            Coordinates.SetEdgeOrientation(result, coord);

            CollectionAssert.AreEqual(expected.EdgeOrientation, result.EdgeOrientation);

            //if solved orientation corresponds to the coordinate 0
            expected = CubieCube.CreateSolved();
            result   = CubieCube.FromAlg(Alg.FromRandomMoves(length, random));
            Coordinates.SetEdgeOrientation(result, 0);

            CollectionAssert.AreEqual(expected.EdgeOrientation, result.EdgeOrientation);

            result = CubieCube.CreateSolved();

            Assert.AreEqual(0, Coordinates.GetEdgeOrientation(result));

            //exceptions
            Assert.ThrowsException <ArgumentNullException>(() => Coordinates.GetEdgeOrientation(null));

            Assert.ThrowsException <ArgumentNullException>(() => Coordinates.SetEdgeOrientation(null, 0));
            Assert.ThrowsException <ArgumentOutOfRangeException>(() => Coordinates.SetEdgeOrientation(CubieCube.CreateSolved(), -1));
            Assert.ThrowsException <ArgumentOutOfRangeException>(() => Coordinates.SetEdgeOrientation(CubieCube.CreateSolved(), Coordinates.NumEdgeOrientations));
        }
예제 #10
0
파일: Util.cs 프로젝트: zjuluxi/BLD-Master
 public 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++)
     {
         int j = cc.ca[c] & 0x7;  // cornercubie with index j is at
                                  // cornerposition with index c
         int ori = cc.ca[c] >> 3; // 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++)
     {
         int j = cc.ea[e] >> 1;  // edgecubie with index j is at edgeposition
                                 // with index e
         int ori = cc.ea[e] & 1; // 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));
 }
예제 #11
0
        public void EquatorPermutationCoordTest() //Tests GetEquatorPermutationCoord, SetEquatorPermutationCoord
        {
            Random random      = new Random(7777777);
            int    length      = 50;
            int    repetitions = 50;

            //if solved permutation corresponds to the coordinate 0
            //SetEquatorPermutationCoord()
            CubieCube expected = CubieCube.CreateSolved();
            CubieCube result   = CubieCube.FromAlg(Alg.FromRandomMoves(length, random));

            Coordinates.SetEquatorOrder(result, 0);
            CubingAssert.HaveEqualEquatorEdgePermutation(expected, result);

            expected = CubieCube.FromAlg(Alg.FromString("R2 L2"));
            result   = CubieCube.FromAlg(Alg.FromRandomMoves(length, random));
            Coordinates.SetEquatorOrder(result, Coordinates.NumEquatorOrders - 1);

            //GetEquatorPermutationCoord()
            result = CubieCube.CreateSolved();
            Assert.AreEqual(0, Coordinates.GetEquatorOrder(result));

            result.ApplyAlg(Alg.FromString("F' R' B' D' L2"));
            Assert.AreEqual(0, Coordinates.GetEquatorOrder(result));

            //apply B1
            int       expectedCoord = 17;
            CubieCube cube          = CubieCube.CreateSolved();

            cube.ApplyMove(Move.B1);
            int resultCoord = Coordinates.GetEquatorOrder(cube);

            Assert.AreEqual(expectedCoord, resultCoord);

            //apply B2
            expectedCoord = 6;
            cube          = CubieCube.CreateSolved();
            cube.ApplyMove(Move.B2);
            resultCoord = Coordinates.GetEquatorOrder(cube);
            Assert.AreEqual(expectedCoord, resultCoord);

            //if applying GetEquatorPermutationCoord() and SetEquatorPermutationCoord() results in the same array as at the beginning
            for (int repetition = 0; repetition < repetitions; repetition++)
            {
                expected = CubieCube.FromAlg(Alg.FromRandomMoves(length, random));
                result   = CubieCube.CreateSolved();

                int coord = Coordinates.GetEquatorOrder(expected);
                Coordinates.SetEquatorOrder(result, coord);

                CubingAssert.HaveEqualEquatorEdgePermutation(expected, result);
            }

            //exceptions
            Assert.ThrowsException <ArgumentNullException>(() => Coordinates.GetEquatorOrder(null));

            Assert.ThrowsException <ArgumentNullException>(() => Coordinates.SetEquatorOrder(null, 0));
            Assert.ThrowsException <ArgumentOutOfRangeException>(() => Coordinates.SetEquatorOrder(CubieCube.CreateSolved(), -1));
            Assert.ThrowsException <ArgumentOutOfRangeException>(() => Coordinates.SetEquatorOrder(CubieCube.CreateSolved(), Coordinates.NumEquatorOrders));
        }
 // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 // Compute the inverse CubieCube
 private void invCubieCube(CubieCube c)
 {
     foreach (Edge edge in Enums.Edges)
     {
         c.ep[(int)ep[(int)edge]] = edge;
     }
     foreach (Edge edge in Enums.Edges)
     {
         c.eo[(int)edge] = eo[(int)c.ep[(int)edge]];
     }
     foreach (Corner corn in Enums.Corners)
     {
         c.cp[(int)cp[(int)corn]] = corn;
     }
     foreach (Corner corn in Enums.Corners)
     {
         sbyte ori = co[(int)c.cp[(int)corn]];
         if (ori >= 3) // Just for completeness. We do not invert mirrored
         // cubes in the program.
         {
             c.co[(int)corn] = ori;
         }
         else
         {
             // the standard case
             c.co[(int)corn] = (sbyte)-ori;
             if (c.co[(int)corn] < 0)
             {
                 c.co[(int)corn] += 3;
             }
         }
     }
 }
예제 #13
0
        /// <summary>
        /// Create a move table for edge orientation.
        /// </summary>
        /// <returns>
        /// A move table for edge orientation.
        /// </returns>
        public static short[,] CreateEdgeOrientationMoveTable()
        {
            CubieCube cube = CubieCube.CreateSolved();

            short[,] edgeOrientationMoveTable = new short[Coordinates.NumEdgeOrientations, NumMoves];

            //invalidate table
            for (int edgeOrientation = 0; edgeOrientation < Coordinates.NumEdgeOrientations; edgeOrientation++)
            {
                for (int move = 0; move < NumMoves; move++)
                {
                    edgeOrientationMoveTable[edgeOrientation, move] = -1;
                }
            }

            //populate table
            for (int edgeOrientation = 0; edgeOrientation < Coordinates.NumEdgeOrientations; edgeOrientation++)
            {
                for (int face = 0; face < NumFaces; face++)
                {
                    Coordinates.SetEdgeOrientation(cube, edgeOrientation);
                    for (int move = 0; move < 3; move++)
                    {
                        cube.MultiplyEdges(CubieCube.MovesArray[face * 3]);
                        edgeOrientationMoveTable[edgeOrientation, face * 3 + move] = (short)Coordinates.GetEdgeOrientation(cube);
                    }
                }
            }

            return(edgeOrientationMoveTable);
        }
예제 #14
0
        //TODO remove redundant indexes
        /// <summary>
        /// Create a move table for equator order. Only valid for cubes in the
        /// subgroup G1.
        /// </summary>
        /// <returns>
        /// A move table for equator order.
        /// </returns>
        public static sbyte[,] CreateEquatorOrderMoveTable()
        {
            sbyte[,] equatorOrderMoveTable = new sbyte[Coordinates.NumEquatorOrders, NumMoves];

            //invalidate table
            for (int equatorOrder = 0; equatorOrder < Coordinates.NumEquatorOrders; equatorOrder++)
            {
                for (int move = 0; move < NumMoves; move++)
                {
                    equatorOrderMoveTable[equatorOrder, move] = -1;
                }
            }

            //populate table
            for (int equatorOrder = 0; equatorOrder < Coordinates.NumEquatorOrders; equatorOrder++)
            {
                for (int face = 0; face < NumFaces; face++)
                {
                    CubieCube cube = CubieCube.CreateSolved();
                    Coordinates.SetEquatorOrder(cube, equatorOrder);
                    for (int move = 0; move < 3; move++)
                    {
                        cube.MultiplyEdges(CubieCube.MovesArray[face * 3]);
                        if (TwoPhaseConstants.Phase2Moves.Contains((Move)(face * 3 + move)))
                        {
                            equatorOrderMoveTable[equatorOrder, face * 3 + move] = (sbyte)Coordinates.GetEquatorOrder(cube);
                        }
                    }
                }
            }

            return(equatorOrderMoveTable);
        }
예제 #15
0
    static TwistMoveClass()
    {
        CubieCube a = new CubieCube();

        for (short i = 0; i < CoordCube.N_TWIST; i++)
        {
            a.setTwist(i);
            for (int j = 0; j < 6; j++)
            {
                for (int k = 0; k < 3; k++)
                {
                    a.cornerMultiply(CubieCube.moveCube[j]);
                    try
                    {
                        twistMove[i, (3 * j) + k] = a.getTwist();
                        //[2187, 17]
                    }
                    catch (Exception e)
                    {
                        break;
                    }
                }
                a.cornerMultiply(CubieCube.moveCube[j]);// 4. faceturn restores
                // a
            }
        }
    }
예제 #16
0
        public void ReductionSymmetryTest()
        {
            CubieCube cube = CubieCube.CreateSolved();

            for (int equator = 0; equator < NumEquatorDistributions; equator++)
            {
                SetEquatorDistribution(cube, equator);
                for (int eo = 0; eo < NumEdgeOrientations; eo++)
                {
                    SetEdgeOrientation(cube, eo);

                    int reducedCoord  = SymmetryReduction.ReduceEoEquatorCoordinate[equator * NumEdgeOrientations + eo];
                    int expandedCoord = SymmetryReduction.ExpandEoEquatorCoordinate[reducedCoord];

                    int symmetryIndex = SymmetryReduction.EoEquatorReductionSymmetry[equator * NumEdgeOrientations + eo];

                    CubieCube symCube = Symmetries.SymmetryCubes[symmetryIndex].Clone();
                    symCube.Multiply(cube);
                    symCube.Multiply(Symmetries.SymmetryCubes[Symmetries.InverseIndex[symmetryIndex]]);

                    Assert.AreEqual(expandedCoord % NumEdgeOrientations, GetEdgeOrientation(symCube));
                    Assert.AreEqual(expandedCoord / NumEdgeOrientations, GetEquatorDistribution(symCube));
                }
            }
        }
예제 #17
0
        public void RandomTest()
        {
            Random random      = new Random(7777777);
            int    repetitions = 20;

            TimeSpan timeout        = TimeSpan.FromSeconds(1);
            int      returnLength   = 18;
            int      requiredLength = 20;

            for (int repetition = 0; repetition < repetitions; repetition++)
            {
                Alg       scramble = Alg.FromRandomMoves(random.Next(20, 30), random);
                CubieCube cube     = CubieCube.FromAlg(scramble);

                Alg solution = TwoPhaseSolver.FindSolution(cube, timeout, returnLength, requiredLength);
                Console.WriteLine("\nScramble: " + scramble + "\nSolution: " + solution + "\nLength: " + solution.Length);

                Assert.IsTrue(solution.Length <= 20);

                CubieCube expected = CubieCube.CreateSolved();
                CubieCube result   = CubieCube.CreateSolved();

                result.ApplyAlg(scramble);
                result.ApplyAlg(solution);

                Assert.AreEqual(expected, result);
            }
        }
예제 #18
0
        public void EoEquatorCoordinateTest()
        {
            bool found;

            for (int expanded = 0; expanded < NumEquatorDistributions * NumEdgeOrientations; expanded++)
            {
                found = false;

                int reduced     = SymmetryReduction.ReduceEoEquatorCoordinate[expanded];
                int expandedSym = SymmetryReduction.ExpandEoEquatorCoordinate[reduced];

                CubieCube expandedCube = CubieCube.CreateSolved();
                SetEdgeOrientation(expandedCube, expanded % 2048);
                SetEquatorDistribution(expandedCube, expanded / 2048);

                for (int sym = 0; sym < NumSymmetriesDh4; sym++)
                {
                    CubieCube symCube = Symmetries.SymmetryCubes[sym].Clone();
                    symCube.MultiplyEdges(expandedCube);
                    symCube.MultiplyEdges(Symmetries.SymmetryCubes[Symmetries.InverseIndex[sym]]);

                    if (expandedSym % 2048 == GetEdgeOrientation(symCube) &&
                        expandedSym / 2048 == GetEquatorDistribution(symCube))
                    {
                        found = true;
                        break;
                    }
                }
                if (!found)
                {
                    Assert.Fail();
                }
            }
        }
예제 #19
0
        public void ReduceEoEquatorCoordinateTest()
        {
            Random random = new Random(7777777);
            int    length = 30;
            int    count  = 100;

            for (int i = 0; i < count; i++)
            {
                CubieCube cube = CubieCube.FromAlg(Alg.FromRandomMoves(length, random));
                for (int sym = 0; sym < NumSymmetriesDh4; sym++)
                {
                    CubieCube symCube = Symmetries.SymmetryCubes[sym].Clone();
                    symCube.Multiply(cube);
                    symCube.Multiply(Symmetries.SymmetryCubes[Symmetries.InverseIndex[sym]]);

                    int cubeEoEquator        = GetEoEquatorCoord(cube);
                    int cubeReducedEoEquator = SymmetryReduction.ReduceEoEquatorCoordinate[cubeEoEquator];

                    int symCubeEoEquator       = GetEoEquatorCoord(symCube);
                    int symCubeReducedEoEqutor = SymmetryReduction.ReduceEoEquatorCoordinate[symCubeEoEquator];

                    Assert.AreEqual(cubeReducedEoEquator, symCubeReducedEoEqutor);
                }
            }
        }
예제 #20
0
 // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 // Compute the inverse CubieCube
 void invCubieCube(CubieCube c)
 {
     foreach (Edge edge in (Edge[])Enum.GetValues(typeof(Edge)))
     {
         c.ep[(int)ep[(int)edge]] = edge;
     }
     foreach (Edge edge in (Edge[])Enum.GetValues(typeof(Edge)))
     {
         c.eo[(int)edge] = eo[(int)c.ep[(int)edge]];
     }
     foreach (Corner corn in (Corner[])Enum.GetValues(typeof(Corner)))
     {
         c.cp[(int)cp[(int)corn]] = corn;
     }
     foreach (Corner corn in (Corner[])Enum.GetValues(typeof(Corner)))
     {
         int ori = co[(int)c.cp[(int)corn]];
         if (ori >= 3)   // Just for completeness. We do not invert mirrored cubes in the program.
         {
             c.co[(int)corn] = ori;
         }
         else
         {               // the standard case
             c.co[(int)corn] = -ori;
             if (c.co[(int)corn] < 0)
             {
                 c.co[(int)corn] += 3;
             }
         }
     }
 }
예제 #21
0
        public static CubieCube ToCubieCube(this FaceCube faceCube)
        {
            var facelets  = faceCube.Facelets;
            var cubieCube = new CubieCube();

            cubieCube.CP = cubieCube.CP.Select((c) => Corner.Invalid).ToArray();
            cubieCube.EP = cubieCube.EP.Select((E) => Edge.Invalid).ToArray();


            for (var i = 0; i < Defs.CornerFacelet.Length; i++)
            {
                Facelet[] corner = Defs.CornerFacelet[i];
                int       ori    = -1;
                var       color3 = Color.Invalid;
                var       color2 = Color.Invalid;

                if (facelets[(int)corner[0]] == Color.U || facelets[(int)corner[0]] == Color.D)
                {
                    ori    = 0;
                    color2 = facelets[(int)corner[1]];
                    color3 = facelets[(int)corner[2]];
                }
                else if (facelets[(int)corner[1]] == Color.U || facelets[(int)corner[1]] == Color.D)
                {
                    ori    = 1;
                    color2 = facelets[(int)corner[2]];
                    color3 = facelets[(int)corner[0]];
                }
                else if (facelets[(int)corner[2]] == Color.U || facelets[(int)corner[2]] == Color.D)
                {
                    ori    = 2;
                    color2 = facelets[(int)corner[0]];
                    color3 = facelets[(int)corner[1]];
                }

                cubieCube.CP[i] = (Corner)Defs.CornerColor.FirstIndexWhere(cornerC => cornerC[1] == color2 && cornerC[2] == color3, (int)Corner.Invalid);
                cubieCube.CO[i] = ori;
            }

            for (var i = 0; i < Defs.EdgeFacelet.Length; i++)
            {
                Facelet[] edge = Defs.EdgeFacelet[i];
                foreach (Color[] edgeColors in Defs.EdgeColor)
                {
                    if (edgeColors[0] == facelets[(int)edge[0]] && edgeColors[1] == facelets[(int)edge[1]])
                    {
                        cubieCube.EP[i] = (Edge)i;
                        cubieCube.EO[i] = 0;
                    }
                    else if (edgeColors[0] == facelets[(int)edge[0]] && edgeColors[1] == facelets[(int)edge[1]])
                    {
                        cubieCube.EP[i] = (Edge)i;
                        cubieCube.EO[i] = 1;
                    }
                }
            }

            return(cubieCube);
        }
예제 #22
0
        static void Main(string[] args)
        {
            var faceCube = new FaceCube() == new FaceCube();
            var cube     = new CubieCube() == new CubieCube();
            var cubes    = new CubieCube().Equals(new CubieCube());

            new CubieCube().ToFaceCube();
        }
예제 #23
0
        public void CpCoordTest() //Tests GetCpCoord, SetCpCoord
        {
            Random random = new Random(7777777);
            int    length = 50;

            //if applying GetCpCoord and SetCpCoord results in the same array as at the beginning
            CubieCube expected = CubieCube.FromAlg(Alg.FromRandomMoves(length, random));
            CubieCube result   = CubieCube.CreateSolved();

            int coord = Coordinates.GetCornerPermutation(expected);

            Coordinates.SetCornerPermutation(result, coord);

            CollectionAssert.AreEqual(expected.CornerPermutation, result.CornerPermutation);

            //apply R2 to a solved cube
            CubieCube cube = CubieCube.CreateSolved();

            cube.ApplyMove(Move.R2);

            int expectedCoord = 36177;
            int resultCoord   = Coordinates.GetCornerPermutation(cube);

            Assert.AreEqual(expectedCoord, resultCoord);

            expected = CubieCube.CreateSolved();
            expected.ApplyMove(Move.R2);

            result = CubieCube.CreateSolved();
            Coordinates.SetCornerPermutation(result, expectedCoord);

            CollectionAssert.AreEqual(expected.CornerPermutation, result.CornerPermutation);

            //if solved permutation corresponds to the coordinate 0
            expected = CubieCube.CreateSolved();
            result   = CubieCube.FromAlg(Alg.FromRandomMoves(length, random));
            Coordinates.SetCornerPermutation(result, 0);

            CollectionAssert.AreEqual(expected.CornerPermutation, result.CornerPermutation);

            result = CubieCube.CreateSolved();

            Assert.AreEqual(0, Coordinates.GetCornerPermutation(result));

            //example from http://kociemba.org/math/coordlevel
            Corner[] cp = new Corner[] { Corner.DFR, Corner.UFL, Corner.ULB, Corner.URF, Corner.DRB, Corner.DLF, Corner.DBL, Corner.UBR };
            cube          = CubieCube.Create(cp, CubieCube.SolvedCO, CubieCube.SolvedEP, CubieCube.SolvedEO, CubieCube.SolvedCenters);
            resultCoord   = Coordinates.GetCornerPermutation(cube);
            expectedCoord = 21021;
            Assert.AreEqual(expectedCoord, resultCoord);

            //exceptions
            Assert.ThrowsException <ArgumentNullException>(() => Coordinates.GetCornerPermutation(null));

            Assert.ThrowsException <ArgumentNullException>(() => Coordinates.SetCornerPermutation(null, 0));
            Assert.ThrowsException <ArgumentOutOfRangeException>(() => Coordinates.SetCornerPermutation(CubieCube.CreateSolved(), -1));
            Assert.ThrowsException <ArgumentOutOfRangeException>(() => Coordinates.SetCornerPermutation(CubieCube.CreateSolved(), Coordinates.NumCornerPermutations));
        }
        // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
        // Multiply this CubieCube with another cubiecube b, restricted to the corners.<br>
        // Because we also describe reflections of the whole cube by permutations, we get a complication with the corners. The
        // orientations of mirrored corners are described by the numbers 3, 4 and 5. The composition of the orientations
        // cannot
        // be computed by addition modulo three in the cyclic group C3 any more. Instead the rules below give an addition in
        // the dihedral group D3 with 6 elements.<br>
        //
        // NOTE: Because we do not use symmetry reductions and hence no mirrored cubes in this simple implementation of the
        // Two-Phase-Algorithm, some code is not necessary here.
        //
        public void cornerMultiply(CubieCube b)
        {
            Corner[] cPerm = new Corner[8];
            sbyte[]  cOri  = new sbyte[8];
            foreach (Corner corn in Enums.Corners)
            {
                cPerm[(int)corn] = cp[(int)b.cp[(int)corn]];

                sbyte oriA = co[(int)b.cp[(int)corn]];
                sbyte oriB = b.co[(int)corn];
                sbyte ori  = 0;
                ;
                if (oriA < 3 && oriB < 3)       // if both cubes are regular cubes...
                {
                    ori = (sbyte)(oriA + oriB); // just do an addition modulo 3 here
                    if (ori >= 3)
                    {
                        ori -= 3; // the composition is a regular cube
                    }
                    // +++++++++++++++++++++not used in this implementation +++++++++++++++++++++++++++++++++++
                }
                else if (oriA < 3 && oriB >= 3) // if cube b is in a mirrored
                                                // state...
                {
                    ori = (sbyte)(oriA + oriB);
                    if (ori >= 6)
                    {
                        ori -= 3; // the composition is a mirrored cube
                    }
                }
                else if (oriA >= 3 && oriB < 3) // if cube a is an a mirrored
                                                // state...
                {
                    ori = (sbyte)(oriA - oriB);
                    if (ori < 3)
                    {
                        ori += 3; // the composition is a mirrored cube
                    }
                }
                else if (oriA >= 3 && oriB >= 3) // if both cubes are in mirrored
                                                 // states...
                {
                    ori = (sbyte)(oriA - oriB);
                    if (ori < 0)
                    {
                        ori += 3; // the composition is a regular cube
                    }
                    // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
                }
                cOri[(int)corn] = ori;
            }
            foreach (Corner c in Enums.Corners)
            {
                int cornerIdx = (int)c;
                cp[cornerIdx] = cPerm[cornerIdx];
                co[cornerIdx] = cOri[cornerIdx];
            }
        }
예제 #25
0
            public void SettingCoordParityCorrect()
            {
                var cubieCube = new CubieCube();

                Assert.Equal(0, cubieCube.EO[11]);

                cubieCube.EdgeOriCoord = 1;
                Assert.Equal(1, cubieCube.EO[11]);
            }
예제 #26
0
    // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
    // Multiply this CubieCube with another cubiecube b, restricted to the corners.<br>
    // Because we also describe reflections of the whole cube by permutations, we get a complication with the corners. The
    // orientations of mirrored corners are described by the numbers 3, 4 and 5. The composition of the orientations
    // cannot
    // be computed by addition modulo three in the cyclic group C3 any more. Instead the rules below give an addition in
    // the dihedral group D3 with 6 elements.<br>
    //
    // NOTE: Because we do not use symmetry reductions and hence no mirrored cubes in this simple implementation of the
    // Two-Phase-Algorithm, some code is not necessary here.
    //
    public void cornerMultiply(CubieCube b)
    {
        Corner[] cPerm = new Corner[8];
        int[]    cOri  = new int[8];
        foreach (Corner corn in (Corner[])Enum.GetValues(typeof(Corner)))
        {
            cPerm[(int)corn] = cp[(int)b.cp[(int)corn]];

            int oriA = co[(int)b.cp[(int)corn]];
            int oriB = b.co[(int)corn];
            int ori  = 0;
            ;
            if (oriA < 3 && oriB < 3)    // if both cubes are regular cubes...
            {
                ori = (oriA + oriB);     // just do an addition modulo 3 here
                if (ori >= 3)
                {
                    ori -= 3;     // the composition is a regular cube
                }
                // +++++++++++++++++++++not used in this implementation +++++++++++++++++++++++++++++++++++
            }
            else if (oriA < 3 && oriB >= 3)     // if cube b is in a mirrored
                                                // state...
            {
                ori = (oriA + oriB);
                if (ori >= 6)
                {
                    ori -= 3;     // the composition is a mirrored cube
                }
            }
            else if (oriA >= 3 && oriB < 3)     // if cube a is an a mirrored
                                                // state...
            {
                ori = (oriA - oriB);
                if (ori < 3)
                {
                    ori += 3;     // the composition is a mirrored cube
                }
            }
            else if (oriA >= 3 && oriB >= 3)     // if both cubes are in mirrored
                                                 // states...
            {
                ori = (oriA - oriB);
                if (ori < 0)
                {
                    ori += 3;     // the composition is a regular cube
                }
                // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
            }
            cOri[(int)corn] = ori;
        }
        foreach (Corner c in (Corner[])Enum.GetValues(typeof(Corner)))
        {
            cp[(int)c] = cPerm[(int)c];
            co[(int)c] = cOri[(int)c];
        }
    }
예제 #27
0
        public static void HasFourEquatorEdges(CubieCube cube)
        {
            int count = cube.EdgePermutation.Count(edge => edge >= Edge.FR);

            if (count != Constants.NumEquatorEdges)
            {
                throw new AssertFailedException("Cube has " + count + " equator edges instead of 4.");
            }
        }
예제 #28
0
파일: Util.cs 프로젝트: zjuluxi/BLD-Master
        public static void ToCubieCube(sbyte[] f, CubieCube ccRet)
        {
            sbyte ori;

            for (int i = 0; i < 8; i++)
            {
                ccRet.ca[i] = 0;// invalidate corners
            }
            for (int i = 0; i < 12; i++)
            {
                ccRet.ea[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.ca[i] = (sbyte)((sbyte)(ori % 3 << 3) | j);
                        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.ea[i] = (sbyte)(j << 1);
                        break;
                    }
                    if (f[edgeFacelet[i, 0]] == edgeFacelet[j, 1] / 9 &&
                        f[edgeFacelet[i, 1]] == edgeFacelet[j, 0] / 9)
                    {
                        ccRet.ea[i] = (sbyte)(j << 1 | 1);
                        break;
                    }
                }
            }
        }
예제 #29
0
            public void SettingCoordReverses()
            {
                var cubieCube = new CubieCube();

                for (var i = 0; i <= 2047; i++)
                {
                    cubieCube.EdgeOriCoord = i;
                    Assert.Equal(i, cubieCube.EdgeOriCoord);
                }
            }
예제 #30
0
            public void SettingCoordReverses()
            {
                var cubieCube = new CubieCube();

                for (var i = 0; i <= 479001599; i += 10000)
                {
                    cubieCube.EdgePermCoord = i;
                    Assert.Equal(i, cubieCube.EdgePermCoord);
                }
            }