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); } }
private void SearchPhase1(int eo, int co, int equator, int depth, int remainingMoves, int previousPruningValue) { if (IsTerminated.Value) { return; } if (remainingMoves == 0) //check if solved { lock (_lockObject) //manage timeout if (_timePassed.Elapsed > _timeout && (_requiredLength < 0 || (_solutions.Count > 0 && _shortestSolutionLength.Value <= _requiredLength))) { IsTerminated.Value = true; } int cp = _cp; int uEdges = _uEdges; int dEdges = _dEdges; int equatorPermutation = equator; //TEST improvement for (int moveIndex = 0; moveIndex < depth; moveIndex++) { int move = _currentPhase1Solution[moveIndex]; cp = TableController.CornerPermutationMoveTable[cp, move]; } int cornerEquatorPruningIndex = Coordinates.NumEquatorOrders * cp + equator; int cornerEquatorPruningValue = TableController.Phase2CornerEquatorPruningTable[cornerEquatorPruningIndex]; if (cornerEquatorPruningValue > MaxPhase2Length) { return; } for (int moveIndex = 0; moveIndex < depth; moveIndex++) { int move = _currentPhase1Solution[moveIndex]; uEdges = TableController.UEdgePermutationMoveTable[uEdges, move]; dEdges = TableController.DEdgePermutationMoveTable[dEdges, move]; } int udEdgeOrder = Coordinates.CombineUEdgePermutationAndDEdgeOrder(uEdges, dEdges % Coordinates.NumDEdgeOrders); //prune int cornerUdPruningIndex = PruningTables.GetPhase2CornerUdPruningIndex(udEdgeOrder, cp); int minMoves = TableController.Phase2CornerUdPruningTable[cornerUdPruningIndex]; int maxMoves = Math.Min(_shortestSolutionLength.Value - depth - 1, MaxPhase2Length); for (int length = minMoves; length <= maxMoves; length++) { SearchPhase2(cp, equatorPermutation, udEdgeOrder, depth: 0, remainingMoves: length, phase1Length: depth); } return; } //increase depth for (int move = 0; move < NumMoves; move++) { //If the cube is already in the subgroup H and there are less //than 5 moves left it is only possible to stay in the subgroup //if exclusivly phase 2 moves are used, which means that this //solution can also be generated in phase 2. if (previousPruningValue == 0 && remainingMoves < 5 && !TwoPhaseConstants.Phase2Moves.Contains((Move)move)) { continue; } //prevent two consecutive moves on the same face or two //consecutive moves on the same axis in the wrong order if (depth > 0) { int relation = move / 3 - _currentPhase1Solution[depth - 1] / 3; if (relation == SameFace || relation == SameAxisInWrongOrder) { continue; } } int newEo = TableController.EdgeOrientationMoveTable[eo, move]; int newCo = TableController.CornerOrientationMoveTable[co, move]; int newEquator = TableController.EquatorPermutationMoveTable[equator, move]; //prune int pruningCoord = PruningTables.GetPhase1PruningIndex(newCo, newEo, newEquator / Coordinates.NumEquatorOrders); int pruningValue = TableController.Phase1PruningTable[pruningCoord]; if (pruningValue > remainingMoves - 1) { continue; } _currentPhase1Solution[depth] = move; SearchPhase1(newEo, newCo, newEquator, depth + 1, remainingMoves - 1, pruningValue); } }