Beispiel #1
0
        /// <summary>
        /// Create a move table for corner orientation.
        /// </summary>
        /// <returns>
        /// A move table for corner orientation.
        /// </returns>
        public static short[,] CreateCornerOrientationMoveTable()
        {
            CubieCube cube = CubieCube.CreateSolved();

            short[,] cornerOrientationMoveTable = new short[Coordinates.NumCornerOrientations, NumMoves];

            //invalidate table
            for (int cornerOrientation = 0; cornerOrientation < Coordinates.NumCornerOrientations; cornerOrientation++)
            {
                for (int move = 0; move < NumMoves; move++)
                {
                    cornerOrientationMoveTable[cornerOrientation, move] = -1;
                }
            }

            //populate table
            for (int cornerOrientation = 0; cornerOrientation < Coordinates.NumCornerOrientations; cornerOrientation++)
            {
                for (int face = 0; face < NumFaces; face++)
                {
                    Coordinates.SetCornerOrientation(cube, cornerOrientation);
                    for (int move = 0; move < 3; move++)
                    {
                        cube.MultiplyCorners(CubieCube.MovesArray[face * 3]);
                        cornerOrientationMoveTable[cornerOrientation, face * 3 + move] = (short)Coordinates.GetCornerOrientation(cube);
                    }
                }
            }

            return(cornerOrientationMoveTable);
        }
        static SymmetryReduction()
        {
            //avoid naming conflicts
            CubieCube cube;
            int       reducedEoEquator, reducedCornerPermutation;

            #region initialize ConjugateCoCoordinate
            ConjugateCornerOrientationCoordinate = new int[NumCornerOrientations, NumSymmetriesDh4];

            //invalidate
            for (int cornerOrientation = 0; cornerOrientation < NumCornerOrientations; cornerOrientation++)
            {
                for (int symmetryIndex = 0; symmetryIndex < NumSymmetriesDh4; symmetryIndex++)
                {
                    ConjugateCornerOrientationCoordinate[cornerOrientation, symmetryIndex] = -1;
                }
            }

            //populate
            cube = CubieCube.CreateSolved();
            for (int cornerOrientation = 0; cornerOrientation < NumCornerOrientations; cornerOrientation++)
            {
                cube.IsMirrored = false; //TEST if necessary
                SetCornerOrientation(cube, cornerOrientation);
                for (int symmetryIndex = 0; symmetryIndex < NumSymmetriesDh4; symmetryIndex++)
                {
                    //conjugate cube
                    CubieCube symmetryCube = SymmetryCubes[symmetryIndex].Clone();
                    symmetryCube.MultiplyCorners(cube);
                    symmetryCube.MultiplyCorners(SymmetryCubes[InverseIndex[symmetryIndex]]);

                    //store result
                    ConjugateCornerOrientationCoordinate[cornerOrientation, symmetryIndex] = GetCornerOrientation(symmetryCube);
                }
            }
            #endregion initialize ConjugateCoCoordinate

            //TODO simplify
            #region initialize ReduceEoEquatorCoordinate, ExpandEoEquatorCoordinate and EoEquatorReductionSymmetry
            //initialize and invalidate
            ReduceEoEquatorCoordinate = Enumerable.Repeat(-1, NumEquatorDistributions * NumEdgeOrientations)
                                        .ToArray();
            ExpandEoEquatorCoordinate = Enumerable.Repeat(-1, NumEoEquatorSymmetryClasses)
                                        .ToArray();
            EoEquatorReductionSymmetry = Enumerable.Repeat(-1, NumEquatorDistributions * NumEdgeOrientations)
                                         .ToArray();

            //populate
            cube             = CubieCube.CreateSolved();
            reducedEoEquator = 0;
            for (int equatorDistribution = 0; equatorDistribution < NumEquatorDistributions; equatorDistribution++)
            {
                SetEquatorDistribution(cube, equatorDistribution);
                for (int edgeOrientation = 0; edgeOrientation < NumEdgeOrientations; edgeOrientation++)
                {
                    int eoEquator = NumEdgeOrientations * equatorDistribution + edgeOrientation;
                    if (ReduceEoEquatorCoordinate[eoEquator] == -1)
                    {
                        SetEdgeOrientation(cube, edgeOrientation);

                        //store representative
                        ReduceEoEquatorCoordinate[eoEquator]        = reducedEoEquator;
                        EoEquatorReductionSymmetry[eoEquator]       = 0;
                        ExpandEoEquatorCoordinate[reducedEoEquator] = eoEquator;

                        //go through all symmetries of the current cube and set
                        //their reduced index to the same full index
                        for (int symmetryIndex = 0; symmetryIndex < NumSymmetriesDh4; symmetryIndex++)
                        {
                            //symmetry ^ -1 * cube * symmetry
                            CubieCube symCube = SymmetryCubes[InverseIndex[symmetryIndex]].Clone();
                            symCube.MultiplyEdges(cube);
                            symCube.MultiplyEdges(SymmetryCubes[symmetryIndex]);

                            //store
                            int newEdgeOrientation     = GetEdgeOrientation(symCube);
                            int newEquatorDistribution = GetEquatorDistribution(symCube);
                            int newEoEquator           = NumEdgeOrientations * newEquatorDistribution + newEdgeOrientation;
                            //TODO test if necessary
                            if (ReduceEoEquatorCoordinate[newEoEquator] == -1)
                            {
                                ReduceEoEquatorCoordinate[newEoEquator]  = reducedEoEquator;
                                EoEquatorReductionSymmetry[newEoEquator] = symmetryIndex;
                            }
                        }
                        reducedEoEquator++;
                    }
                }
            }
            #endregion initialize ReduceEoEquatorCoordinate, ExpandEoEquatorCoordinate and EoEquatorReductionSymmetry

            #region initialize EoEquatorSymmetries
            //initialize and invalidate
            EoEquatorSymmetries = Enumerable.Repeat(0, NumEoEquatorSymmetryClasses)
                                  .ToArray();

            //populate
            cube = CubieCube.CreateSolved();
            for (reducedEoEquator = 0; reducedEoEquator < NumEoEquatorSymmetryClasses; reducedEoEquator++)
            {
                //set cube to the representative of the reduced index
                int eoEquator = ExpandEoEquatorCoordinate[reducedEoEquator];
                SetEoEquatorCoord(cube, eoEquator);

                //find all symmetries of the cube
                for (int symmetryIndex = 0; symmetryIndex < NumSymmetriesDh4; symmetryIndex++)
                {
                    //symmetry * cube * symmetry ^ -1
                    CubieCube symmetryCube = SymmetryCubes[symmetryIndex].Clone();
                    symmetryCube.MultiplyEdges(cube);
                    symmetryCube.MultiplyEdges(SymmetryCubes[InverseIndex[symmetryIndex]]);
                    //set flag if symmetrical
                    int newEoEquator = GetEoEquatorCoord(symmetryCube);
                    if (eoEquator == newEoEquator)
                    {
                        EoEquatorSymmetries[reducedEoEquator] |= 1 << symmetryIndex;
                    }
                }
            }
            #endregion initialize EoEoquatorSymmetries

            #region initialize ConjugateUdEdgeOrderCoordinate
            ConjugateUdEdgeOrderCoordinate = new int[NumUdEdgeOrders, NumSymmetriesDh4];

            //invalidate
            for (int udEdgeOrders = 0; udEdgeOrders < NumUdEdgeOrders; udEdgeOrders++)
            {
                for (int symmetryIndex = 0; symmetryIndex < NumSymmetriesDh4; symmetryIndex++)
                {
                    ConjugateUdEdgeOrderCoordinate[udEdgeOrders, symmetryIndex] = -1;
                }
            }

            //populate
            cube = CubieCube.CreateSolved();
            for (int udEdgePermutation = 0; udEdgePermutation < NumUdEdgeOrders; udEdgePermutation++)
            {
                SetUdEdgeOrder(cube, udEdgePermutation);
                for (int symmetryIndex = 0; symmetryIndex < NumSymmetriesDh4; symmetryIndex++)
                {
                    //conjugate cube
                    CubieCube symmetryCube = SymmetryCubes[symmetryIndex].Clone();
                    symmetryCube.MultiplyEdges(cube);
                    symmetryCube.MultiplyEdges(SymmetryCubes[InverseIndex[symmetryIndex]]);

                    //store result
                    ConjugateUdEdgeOrderCoordinate[udEdgePermutation, symmetryIndex] = GetUdEdgeOrder(symmetryCube);
                }
            }
            #endregion initialize ConjugateUdEdgeOrderCoordinate

            #region initialize ReduceCpCoordinate, ExpandCpCoordinate and CpReductionSymmetry
            //initialize and invalidate
            ReduceCornerPermutationCoordinate = Enumerable.Repeat(-1, NumCornerPermutations)
                                                .ToArray();
            ExpandCornerPermutationCoordinate = Enumerable.Repeat(-1, NumCornerPermutationSymmetryClasses)
                                                .ToArray();
            CornerPermutationReductionSymmetry = Enumerable.Repeat(-1, NumCornerPermutations)
                                                 .ToArray();

            //populate
            cube = CubieCube.CreateSolved();
            reducedCornerPermutation = 0;
            for (int cornerPermutation = 0; cornerPermutation < NumCornerPermutations; cornerPermutation++)
            {
                if (ReduceCornerPermutationCoordinate[cornerPermutation] == -1)
                {
                    cube.IsMirrored = false; //TEST if necessary
                    SetCornerPermutation(cube, cornerPermutation);

                    //store representative
                    ReduceCornerPermutationCoordinate[cornerPermutation]        = reducedCornerPermutation;
                    CornerPermutationReductionSymmetry[cornerPermutation]       = 0;
                    ExpandCornerPermutationCoordinate[reducedCornerPermutation] = cornerPermutation;

                    //go through all symmetries of the current cube and set
                    //their reduced index to the same full index
                    for (int symmetryIndex = 0; symmetryIndex < NumSymmetriesDh4; symmetryIndex++)
                    {
                        //symmetry ^ -1 * cube * symmetry
                        CubieCube symmetryCube = SymmetryCubes[InverseIndex[symmetryIndex]].Clone();
                        symmetryCube.MultiplyCorners(cube);
                        symmetryCube.MultiplyCorners(SymmetryCubes[symmetryIndex]);

                        //store
                        int newCornerPermutation = GetCornerPermutation(symmetryCube);
                        //TODO test if necessary
                        if (ReduceCornerPermutationCoordinate[newCornerPermutation] == -1)
                        {
                            ReduceCornerPermutationCoordinate[newCornerPermutation]  = reducedCornerPermutation;
                            CornerPermutationReductionSymmetry[newCornerPermutation] = symmetryIndex;
                        }
                    }
                    reducedCornerPermutation++;
                }
            }
            #endregion initialize ReduceCpCoordinate, ExpandCpCoordinate and CpReductionSymmetry

            #region initialize CpSymmetries
            CornerPermutationSymmetries = Enumerable.Repeat(0, NumCornerPermutationSymmetryClasses)
                                          .ToArray();

            cube = CubieCube.CreateSolved();
            for (reducedCornerPermutation = 0; reducedCornerPermutation < NumCornerPermutationSymmetryClasses; reducedCornerPermutation++)
            {
                //set cube to the representative of the reduced index
                int cornerPermutation = ExpandCornerPermutationCoordinate[reducedCornerPermutation];
                SetCornerPermutation(cube, cornerPermutation);

                //find all symmetries of the cube
                for (int symmetryIndex = 0; symmetryIndex < NumSymmetriesDh4; symmetryIndex++)
                {
                    //symmetry * cube * symmetry ^ -1
                    CubieCube symmetryCube = SymmetryCubes[symmetryIndex].Clone();
                    symmetryCube.MultiplyCorners(cube);
                    symmetryCube.MultiplyCorners(SymmetryCubes[InverseIndex[symmetryIndex]]);
                    //set flag if symmetrical
                    int newCornerPermutation = GetCornerPermutation(symmetryCube);
                    if (cornerPermutation == newCornerPermutation)
                    {
                        CornerPermutationSymmetries[reducedCornerPermutation] |= 1 << symmetryIndex;
                    }
                }
            }
            #endregion initialize CpSymmetries
        }