/// <summary> /// Gets all the correct cubies in a list of cubies. /// </summary> /// <param name="cubies">The list.</param> /// <param name="cube">The cube.</param> /// <returns>The correct cubies.</returns> public static IEnumerable <Cubie> CorrectCubies(this IEnumerable <Cubie> cubies, Cube cube) { foreach (Cubie c in cubies) { if (cube.IsCubiePlacedCorrectly(c)) { yield return(c); } } }
/// <summary> /// Executes the PLL phase. /// </summary> private void PLL() { // ******************* CORNERS ******************* // Sets the view. ChangeView(new CubeView(SideColors[0], FINAL_COLOR)); // Gets the last layer corners and the number of how many of them is already correct. IEnumerable <Cubie> corners = _cube.GetFaceCubies(Face.Up).Corners(); int correctCornersCount = corners.CorrectCubies(_cube).Count <Cubie>(); // Rotates the last layer until only one or all of the corners are correct (max 4 times). for (int i = 0; i < 4 && correctCornersCount != 4 && correctCornersCount != 1; i++) { AddMove(Move.Up); correctCornersCount = corners.CorrectCubies(_cube).Count <Cubie>(); } // Continues with the algorithm only if any of the corners isn't already correct. if (correctCornersCount != 4) { // If more or less than one corner is correct, the program will use the algorithm to // exchange the corners and then rotate the upper layer until the corners are correct. if (correctCornersCount != 1) { AddMoveList(Algorithms.PLLCornerDoubleExchange); while (!_cube.IsCubiePlacedCorrectly(_cube.FindCubie(0, 0, 0))) { AddMove(Move.Up); } } // If one corner is correct the cube will be rotated until it is on the left in the front face, // then use the correct algorithm. else { for (int c = 0; !_cube.IsCubiePlacedCorrectly(_cube.FindCubie(0, 0, 0)); c++) { ChangeView(new CubeView(SideColors[c], FINAL_COLOR)); } if (_cube.FindCubie(2, 0, 0).FrontColor == _cube.FindCubie(2, 1, 1).RightColor) { AddMoveList(Algorithms.PLLCornerCounterClockwise); } else { AddMoveList(Algorithms.PLLCornerClockwise); } } } // ******************* EDGES ******************* // Keeps on turning the cube until the cube is solved. for (int c = 0; c < SideColors.Length && !_cube.IsSolved(); c++) { ChangeView(new CubeView(SideColors[c], FINAL_COLOR)); Cubie frontEdge = _cube.FindCubie(1, 0, 0); Cubie backEdge = _cube.FindCubie(1, 0, 2); Cubie leftEdge = _cube.FindCubie(0, 0, 1); // Depending on the situation, the program will use a different algorithm. if (_cube.IsCubiePlacedCorrectly(frontEdge)) { if ((int)leftEdge.LeftColor == -(int)frontEdge.FrontColor) { AddMoveList(Algorithms.PLLEdgeClockwise); } else { AddMoveList(Algorithms.PLLEdgeCounterClockwise); } } else if ((int)frontEdge.FrontColor == -(int)_cube.GetFaceColor(Face.Front) && (int)backEdge.BackColor == -(int)_cube.GetFaceColor(Face.Back)) { AddMoveList(Algorithms.PLLEdgeCrossExchange); } else if (leftEdge.LeftColor == _cube.GetFaceColor(Face.Front) && backEdge.BackColor == _cube.GetFaceColor(Face.Right)) { AddMoveList(Algorithms.PLLEdgeBackslashExchange); } } }