private void SolveCrossTopLayer() { // Step 1: Get edges with the color of the top face IEnumerable <Cube> topEdges = Rubik.Cubes.Where(c => c.IsEdge).Where(c => c.Position.HasFlag(CubeFlag.TopLayer)); // Step 2: Check if the cube is insoluble if (topEdges.Count(tE => tE.Faces.First(f => f.Position == FacePosition.Top).Color == Rubik.TopColor) % 2 != 0) { return; } var correctEdges = topEdges.Where(c => c.Faces.First(f => f.Position == FacePosition.Top).Color == Rubik.TopColor); var solveTopCrossAlgorithmI = new Algorithm("F R U R' U' F'"); var solveTopCrossAlgorithmII = new Algorithm("F S R U R' U' F' S'"); // Step 3: Solve the cross on the top layer if (Rubik.CountEdgesWithCorrectOrientation() == 0) { SolverAlgorithm(solveTopCrossAlgorithmI); correctEdges = topEdges.Where(c => c.Faces.First(f => f.Position == FacePosition.Top).Color == Rubik.TopColor); } if (Rubik.CountEdgesWithCorrectOrientation() == 2) { var firstCorrect = correctEdges.First(); var secondCorrect = correctEdges.First(f => f != firstCorrect); bool opposite = false; foreach (CubeFlag flag in firstCorrect.Position.GetFlags()) { CubeFlag pos = CubeFlagService.GetOppositeFlag(flag); if (secondCorrect.Position.HasFlag(pos) && pos != CubeFlag.None) { opposite = true; break; } } if (opposite) { while (correctEdges.Count(c => c.Position.HasFlag(CubeFlag.RightSlice)) != 1) { SolverMove(CubeFlag.TopLayer, true); } SolverAlgorithm(solveTopCrossAlgorithmI); } else { while (correctEdges.Count(c => c.Position.HasFlag(CubeFlag.RightSlice) || c.Position.HasFlag(CubeFlag.FrontSlice)) != 2) { SolverMove(CubeFlag.TopLayer, true); } SolverAlgorithm(solveTopCrossAlgorithmII); } } // Step 4: Move the edges of the cross to their target positions while (topEdges.Count(c => c.Position.Flags == GetTargetFlags(c)) < 4) { IEnumerable <Cube> correctEdges2 = topEdges.Where(c => c.Position.Flags == GetTargetFlags(c)); while (correctEdges2.Count() < 2) { SolverMove(CubeFlag.TopLayer, true); } CubeFlag rightSlice = CubeFlagService.FromFacePosition(correctEdges2.First().Faces .First(f => f.Position != FacePosition.Top && f.Color != Color.Black).Position); SolverMove(CubeFlag.TopLayer, false); if (correctEdges2.Count(c => c.Position.HasFlag(rightSlice)) == 0) { SolverMove(CubeFlag.TopLayer, true); } else { SolverMove(CubeFlag.TopLayer, true); rightSlice = CubeFlagService.FromFacePosition( correctEdges2 .First(cE => !cE.Position.HasFlag(rightSlice)) .Faces .First(f => f.Position != FacePosition.Top && f.Color != Color.Black ) .Position ); } // Algorithm: R U R' U R U U R' SolverAlgorithm( "{0} U {0}' U {0} U U {0}'", CubeFlagService.ToNotationString(rightSlice) ); while (correctEdges2.Count() < 2) { SolverMove(CubeFlag.TopLayer, true); } } }