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));
                }
            }
        }
        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);
                }
            }
        }
Beispiel #3
0
        private void StartSearch()
        {
            #region rotate cube
            CubieCube rotatedCube = CubieCube.CreateSolved();

            for (int i = 0; i < _rotation; i++)
            {
                rotatedCube.Rotate(Rotation.y3);
                rotatedCube.Rotate(Rotation.x3);
            }

            rotatedCube.Multiply(_notRotatedCube);

            for (int i = 0; i < _rotation; i++)
            {
                rotatedCube.Rotate(Rotation.x1);
                rotatedCube.Rotate(Rotation.y1);
            }

            if (_inversed)
            {
                rotatedCube.Inverse();
            }
            #endregion rotate cube

            //calculate coordinates
            int co      = Coordinates.GetCornerOrientation(rotatedCube);
            int cp      = Coordinates.GetCornerPermutation(rotatedCube);
            int eo      = Coordinates.GetEdgeOrientation(rotatedCube);
            int equator = Coordinates.GetEquatorPermutation(rotatedCube);
            int uEdges  = Coordinates.GetUEdgePermutation(rotatedCube);
            int dEdges  = Coordinates.GetDEdgePermutation(rotatedCube);

            //store coordinates used in phase 2
            _cp     = cp;
            _uEdges = uEdges;
            _dEdges = dEdges;

            int pruningIndex    = PruningTables.GetPhase1PruningIndex(co, eo, equator / Coordinates.NumEquatorOrders);
            int minPhase1Length = TableController.Phase1PruningTable[pruningIndex];
            int maxPhase1Length = (_requiredLength > 0 && _requiredLength < GodsNumber) ? _requiredLength : GodsNumber;

            _currentPhase1Solution = new int[maxPhase1Length];
            _currentPhase2Solution = new int[MaxPhase2Length];

            for (int phase1Length = minPhase1Length; phase1Length < maxPhase1Length; phase1Length++)
            {
                SearchPhase1(eo, co, equator, depth: 0, remainingMoves: phase1Length, minPhase1Length);
            }
        }
        public void ConjugateCoCoordinateTest()
        {
            Assert.AreEqual(2187, SymmetryReduction.ConjugateCornerOrientationCoordinate.GetLength(0));
            Assert.AreEqual(16, SymmetryReduction.ConjugateCornerOrientationCoordinate.GetLength(1));

            CubieCube coordCube = CubieCube.CreateSolved();

            for (int co = 0; co < NumCornerOrientations; co++)
            {
                SetCornerOrientation(coordCube, co);
                for (int sym = 0; sym < NumSymmetriesDh4; sym++)
                {
                    CubieCube symCube = Symmetries.SymmetryCubes[sym].Clone();
                    symCube.Multiply(coordCube);
                    symCube.Multiply(Symmetries.SymmetryCubes[Symmetries.InverseIndex[sym]]);

                    CubieCube result = CubieCube.CreateSolved();
                    SetCornerOrientation(result, SymmetryReduction.ConjugateCornerOrientationCoordinate[co, sym]);

                    CollectionAssert.AreEqual(symCube.CornerOrientation, result.CornerOrientation);
                }
            }
        }
Beispiel #5
0
        public void InverseIndexTest()
        {
            for (int index = 0; index < Symmetries.NumSymmetries; index++)
            {
                CubieCube permCube = Symmetries.SymmetryCubes[index];
                CubieCube invCube  = Symmetries.SymmetryCubes[Symmetries.InverseIndex[index]];
                CubieCube solved   = CubieCube.CreateSolved();

                CubieCube test1 = permCube.Clone();
                test1.Multiply(invCube);
                Assert.AreEqual(solved, test1);

                CubieCube test2 = invCube.Clone();
                test2.Multiply(permCube);
                Assert.AreEqual(solved, test2);
            }
        }
Beispiel #6
0
        public void MultiplyTest()
        {
            Random random = new Random(7777777);
            int    length = 50;

            Alg alg = Alg.FromRandomMoves(length, random);

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

            foreach (Move move in alg)
            {
                expected.ApplyMove(move);
                CubieCube moveCube = CubieCube.CreateSolved();
                moveCube.ApplyMove(move);
                result.Multiply(moveCube);
            }

            Assert.AreEqual(expected, result);
            Assert.ThrowsException <ArgumentNullException>(()
                                                           => CubieCube.CreateSolved().Multiply(null));
        }
Beispiel #7
0
        public void MultiplyTest()
        {
            for (int cp1 = 0; cp1 < Symmetries.NumSymmetries; cp1++)
            {
                for (int cp2 = 0; cp2 < Symmetries.NumSymmetries; cp2++)
                {
                    CubieCube expected
                        = Symmetries.SymmetryCubes[cp1].Clone();
                    expected.Multiply(Symmetries.SymmetryCubes[cp2]);

                    var sexpected = Symmetries.SymmetryCubes[21];
                    var sresult   = Symmetries.SymmetryCubes[1].Clone();
                    sresult.Multiply(Symmetries.SymmetryCubes[16]);

                    Assert.AreEqual(sexpected, sresult);

                    CubieCube result = Symmetries.SymmetryCubes[
                        Symmetries.MultiplyIndex[cp1, cp2]];

                    Assert.AreEqual(expected, result);
                }
            }
        }
        private void StartSearch()
        {
            #region rotate cube
            CubieCube rotatedCube = CubieCube.CreateSolved();

            for (int i = 0; i < _rotation; i++)
            {
                rotatedCube.Rotate(Rotation.y3);
                rotatedCube.Rotate(Rotation.x3);
            }

            rotatedCube.Multiply(_notRotatedCube);

            for (int i = 0; i < _rotation; i++)
            {
                rotatedCube.Rotate(Rotation.x1);
                rotatedCube.Rotate(Rotation.y1);
            }

            if (_inversed)
            {
                rotatedCube.Inverse();
            }
            #endregion rotate cube

            #region rotate weights
            _rotatedWeights = new float[NumMoves];

            for (int oldIndex = 0; oldIndex < NumMoves; oldIndex++)
            {
                int newIndex = oldIndex;
                for (int i = 0; i < _rotation; i++)
                {
                    newIndex = (int)((Move)newIndex).Rotate(Rotation.x1).Rotate(Rotation.y1);
                }
                _rotatedWeights[newIndex] = _nonRotatedWeights[oldIndex];
            }

            if (_inversed)
            {
                for (int face = 0; face < NumFaces; face++)
                {
                    //face * 3 = 90° cw, face * 3 + 2 = 90° ccw
                    float temp = _rotatedWeights[face * 3];
                    _rotatedWeights[face * 3]     = _rotatedWeights[face * 3 + 2];
                    _rotatedWeights[face * 3 + 2] = temp;
                }
            }
            #endregion rotate weights

            _phase1MoveOrder = MoveWeightsUtils.OrderedMoves((Move[])Enum.GetValues(typeof(Move)), _rotatedWeights);
            _phase2MoveOrder = MoveWeightsUtils.OrderedMoves(TwoPhaseConstants.Phase2Moves, _rotatedWeights);

            //calculate coordinates
            int co      = Coordinates.GetCornerOrientation(rotatedCube);
            int cp      = Coordinates.GetCornerPermutation(rotatedCube);
            int eo      = Coordinates.GetEdgeOrientation(rotatedCube);
            int equator = Coordinates.GetEquatorPermutation(rotatedCube);
            int uEdges  = Coordinates.GetUEdgePermutation(rotatedCube);
            int dEdges  = Coordinates.GetDEdgePermutation(rotatedCube);

            //store coordinates used in phase 2
            _cp     = cp;
            _uEdges = uEdges;
            _dEdges = dEdges;

            int pruningIndex    = PruningTables.GetPhase1PruningIndex(co, eo, equator / Coordinates.NumEquatorOrders);
            int minPhase1Length = TableController.Phase1PruningTable[pruningIndex];

            _currentPhase1Solution = new int[MaxPhase1Length];
            _currentPhase2Solution = new int[MaxPhase2Length];

            for (int phase1Length = minPhase1Length; phase1Length < MaxPhase1Length; phase1Length++)
            {
                SearchPhase1(eo, co, equator, depth: 0, remainingMoves: phase1Length, minPhase1Length);
            }
        }