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)); }
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)); }
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); } }