Пример #1
0
        public void InverseTest()
        {
            Random random = new Random(7777777);
            int    length = 50;

            Alg original = Alg.FromString("R U R' F' R U R' U' R' F R2 U' R' U'");
            Alg expected = Alg.FromString("U R U R2 F' R U R U' R' F R U' R'");
            Alg result   = Alg.Inverse(original);

            Assert.AreEqual(expected, result);

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

            Assert.AreEqual(randomMoves, Alg.Inverse(Alg.Inverse(randomMoves)));
            Assert.AreEqual(randomMoves, randomMoves.Inverse().Inverse());
            Assert.AreEqual(randomMoves.Inverse(), Alg.Inverse(randomMoves));
            Assert.ThrowsException <ArgumentNullException>(() => Alg.Inverse(null));
        }
Пример #2
0
        public void RotateTest()
        {
            Random random = new Random(7777777);
            int    length = 50;

            Rotation rotation = Rotation.x1;

            Alg original = Alg.FromString("B2 D U'");
            Alg expected = Alg.FromString("D2 F B'");

            Assert.AreEqual(expected, original.Rotate(rotation));

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

            Assert.AreEqual(randomMoves.Inverse(), Alg.Inverse(randomMoves));
            Assert.ThrowsException <ArgumentNullException>(() =>
                                                           Alg.Rotate(null, rotation));
        }
Пример #3
0
        private void SearchPhase2(int cp, int equatorPermutation, int udEdgeOrder, int depth, int remainingMoves, int phase1Length)
        {
            if (IsTerminated.Value)
            {
                return;
            }

            if (remainingMoves == 0 && equatorPermutation == 0) //check if solved
            {
                Alg solution = Alg.FromEnumerable(_currentPhase1Solution.Take(phase1Length).Concat(_currentPhase2Solution.Take(depth)).Cast <Move>());

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

                if (_inversed)
                {
                    solution = solution.Inverse();
                }

                lock (_lockObject)
                {
                    if (solution.Length < _shortestSolutionLength.Value)
                    {
                        _shortestSolutionIndex.Value  = _solutions.Count;
                        _shortestSolutionLength.Value = solution.Length;
                    }

                    _solutions.Add(solution);
                }

                if (solution.Length <= _returnLength)
                {
                    IsTerminated.Value = true;
                }

                return;
            }

            //increase depth
            foreach (int move in TwoPhaseConstants.Phase2Moves)
            {
                //prevent two consecutive moves on the same face or two
                //consecutive moves on the same axis in the wrong order
                if (depth == 0)
                {
                    if (phase1Length > 0)
                    {
                        int relation = move / 3 - _currentPhase1Solution[phase1Length - 1] / 3;
                        if (relation == SameFace || relation == SameAxisInWrongOrder)
                        {
                            continue;
                        }
                    }
                }
                else
                {
                    int relation = move / 3 - _currentPhase2Solution[depth - 1] / 3;
                    if (relation == SameFace || relation == SameAxisInWrongOrder)
                    {
                        continue;
                    }
                }

                int newCp = TableController.CornerPermutationMoveTable[cp, move];
                int newEquatorPermutation = TableController.EquatorPermutationMoveTable[equatorPermutation, move];
                int newUdEdgePermutation  = TableController.UdEdgeOrderMoveTable[udEdgeOrder, MoveTables.Phase1IndexToPhase2Index[move]];

                //prune
                int cornerUdPruningIndex      = PruningTables.GetPhase2CornerUdPruningIndex(newUdEdgePermutation, newCp);
                int cornerUdPruningValue      = TableController.Phase2CornerUdPruningTable[cornerUdPruningIndex];
                int cornerEquatorPruningIndex = Coordinates.NumEquatorOrders * newCp + newEquatorPermutation;
                int cornerEquatorPruningValue = TableController.Phase2CornerEquatorPruningTable[cornerEquatorPruningIndex];
                if (Math.Max(cornerUdPruningValue, cornerEquatorPruningValue) > remainingMoves - 1)
                {
                    continue;
                }

                _currentPhase2Solution[depth] = move;
                SearchPhase2(newCp, newEquatorPermutation, newUdEdgePermutation, depth + 1, remainingMoves - 1, phase1Length);
            }
        }