private async Task FixInnerSquare(List<IRotation> solution, CubeConfiguration<FaceColour> configuration) { var upperColour = configuration.Faces[FaceType.Front].GetEdge(configuration.MinInnerLayerIndex(), Edge.Top).Centre(); var downColour = configuration.Faces[FaceType.Front].GetEdge(configuration.MinInnerLayerIndex(), Edge.Bottom).Centre(); var correctFaceForTopRow = FaceRules.GetFaceOfColour(upperColour, configuration); var correctFaceForBottomRow = FaceRules.GetFaceOfColour(downColour, configuration); await MoveRowToCorrectFace(correctFaceForTopRow, solution, configuration, true).ConfigureAwait(false); await MoveRowToCorrectFace(correctFaceForBottomRow, solution, configuration, false).ConfigureAwait(false); }
public async Task<IEnumerable<IRotation>> Solve(CubeConfiguration<FaceColour> configuration) { if (m_layer < 0) { m_layer = configuration.MinInnerLayerIndex(); } var solution = new List<IRotation>(); var rotationToBottom = await CommonActions.PositionOnFront(configuration, m_faceColour).ConfigureAwait(false); if (rotationToBottom != null) solution.Add(rotationToBottom); for (int i = 0; i <= 3; i++) { await CheckFace(configuration, FaceType.Upper, solution).ConfigureAwait(false); await CommonActions.ApplyAndAddRotation(CubeRotations.ZClockwise, solution, configuration).ConfigureAwait(false); } await CheckFace(configuration, FaceType.Back, solution, false, true).ConfigureAwait(false); return solution; }
private async Task CheckMiddleLayersOnFace(CubeConfiguration<FaceColour> configuration, List<IRotation> solution, FaceType face) { var frontFaceColour = configuration.Faces[FaceType.Front].LeftCentre(); var leftFaceColour = configuration.Faces[FaceType.Left].RightCentre(); var rightEdgeOnFace = configuration.Faces[face].GetEdge(Edge.Right); var top = rightEdgeOnFace[configuration.MinInnerLayerIndex()]; var bottom = rightEdgeOnFace[configuration.MaxInnerLayerIndex()]; var joiningFace = FaceRules.FaceAtRelativePositionTo(face, RelativePosition.Right); var leftEdgeOnJoiningFace = configuration.Faces[joiningFace].GetEdge(Edge.Left); var joiningFaceEdgeTop = leftEdgeOnJoiningFace[configuration.MinInnerLayerIndex()]; var joiningFaceEdgeBottom = leftEdgeOnJoiningFace[configuration.MaxInnerLayerIndex()]; if ((top == frontFaceColour && joiningFaceEdgeTop == leftFaceColour) || (bottom == frontFaceColour && joiningFaceEdgeBottom == leftFaceColour) || (top == leftFaceColour && joiningFaceEdgeTop == frontFaceColour) || (bottom == leftFaceColour && joiningFaceEdgeBottom == frontFaceColour)) { var rotationToBringEdgeToFront = GetRotationToPutTredgeOnFront((top == frontFaceColour && joiningFaceEdgeTop == leftFaceColour) || (top == leftFaceColour && joiningFaceEdgeTop == frontFaceColour), face, configuration.MinInnerLayerIndex()); await CommonActions.ApplyAndAddRotation(rotationToBringEdgeToFront, solution, configuration).ConfigureAwait(false); } if ((top == frontFaceColour && joiningFaceEdgeTop == leftFaceColour) || (bottom == frontFaceColour && joiningFaceEdgeBottom == leftFaceColour)) { await PerformFlip(solution, configuration).ConfigureAwait(false); } rightEdgeOnFace = configuration.Faces[face].GetEdge(Edge.Right); top = rightEdgeOnFace[configuration.MinInnerLayerIndex()]; bottom = rightEdgeOnFace[configuration.MaxInnerLayerIndex()]; leftEdgeOnJoiningFace = configuration.Faces[joiningFace].GetEdge(Edge.Left); joiningFaceEdgeTop = leftEdgeOnJoiningFace[configuration.MinInnerLayerIndex()]; joiningFaceEdgeBottom = leftEdgeOnJoiningFace[configuration.MaxInnerLayerIndex()]; if (top == leftFaceColour && joiningFaceEdgeTop == frontFaceColour) { await CommonActions.ApplyAndAddRotation(Rotations.SecondLayerUpperClockwise, solution, configuration).ConfigureAwait(false); } if (bottom == leftFaceColour && joiningFaceEdgeBottom == frontFaceColour) { await CommonActions.ApplyAndAddRotation(Rotations.SecondLayerDownAntiClockwise, solution, configuration).ConfigureAwait(false); } }
private async Task CheckFlipped(CubeConfiguration<FaceColour> configuration, List<IRotation> solution) { var frontFaceEdge = configuration.Faces[FaceType.Front].GetEdge(Edge.Left); var leftFaceEdge = configuration.Faces[FaceType.Left].GetEdge(Edge.Right); var frontColour = frontFaceEdge.Centre(); var leftColour = leftFaceEdge.Centre(); if (frontFaceEdge[configuration.MinInnerLayerIndex()] == leftColour && frontFaceEdge[configuration.MaxInnerLayerIndex()] == leftColour && leftFaceEdge[configuration.MinInnerLayerIndex()] == frontColour && leftFaceEdge[configuration.MaxInnerLayerIndex()] == frontColour) { await CommonActions.ApplyAndAddRotation(Rotations.SecondLayerUpperAntiClockwise, solution, configuration).ConfigureAwait(false); await CommonActions.ApplyAndAddRotation(Rotations.SecondLayerDownClockwise, solution, configuration).ConfigureAwait(false); await PerformFlip(solution, configuration).ConfigureAwait(false); await CommonActions.ApplyAndAddRotation(Rotations.SecondLayerUpperClockwise, solution, configuration).ConfigureAwait(false); await CommonActions.ApplyAndAddRotation(Rotations.SecondLayerDownAntiClockwise, solution, configuration).ConfigureAwait(false); } }
private async Task MoveRowToCorrectFace(FaceType faceToMoveToo, List<IRotation> solution, CubeConfiguration<FaceColour> configuration, bool upper) { // If we get an upper or down face it would imply that we do not have completed rows meaning we have probably skipped steps (some tests do this) if (faceToMoveToo == FaceType.Upper || faceToMoveToo == FaceType.Down) { return; } IRotation rotation = null; var face = upper ? FaceType.Upper : FaceType.Down; RotationDirection direction; var position = FaceRules.RelativePositionBetweenFaces(FaceType.Front, faceToMoveToo); switch (position) { case RelativePosition.Left: direction = upper ? RotationDirection.Clockwise : RotationDirection.AntiClockwise; rotation = Rotations.ByFace(face, direction, configuration.MinInnerLayerIndex()); break; case RelativePosition.Right: direction = !upper ? RotationDirection.Clockwise : RotationDirection.AntiClockwise; rotation = Rotations.ByFace(face, direction, configuration.MinInnerLayerIndex()); break; case RelativePosition.Opposite: rotation = Rotations.ByFaceTwice(face, configuration.MinInnerLayerIndex()); break; } if (rotation != null) { await CommonActions.ApplyAndAddRotation(rotation, solution, configuration).ConfigureAwait(false); } }
private static async Task CheckFrontRightEdge(CubeConfiguration<FaceColour> configuration, List<IRotation> solution) { var frontFaceColour = configuration.Faces[FaceType.Front].LeftCentre(); var leftFaceColour = configuration.Faces[FaceType.Left].RightCentre(); var rightEdgeOnFace = configuration.Faces[FaceType.Front].GetEdge(Edge.Right); var frontFaceTop = rightEdgeOnFace[configuration.MinInnerLayerIndex()]; var frontFaceBottom = rightEdgeOnFace[configuration.MaxInnerLayerIndex()]; var leftEdgeOnRightFace = configuration.Faces[FaceType.Right].GetEdge(Edge.Left); var rightFaceTop = leftEdgeOnRightFace[configuration.MinInnerLayerIndex()]; var rightFaceBottom = leftEdgeOnRightFace[configuration.MaxInnerLayerIndex()]; if (frontFaceTop == frontFaceColour && rightFaceTop == leftFaceColour) { await CommonActions.ApplyAndAddRotation(Rotations.SecondLayerDownClockwise, solution, configuration).ConfigureAwait(false); await PerformFlip(solution, configuration).ConfigureAwait(false); await CommonActions.ApplyAndAddRotation(Rotations.SecondLayerDownAntiClockwise, solution, configuration).ConfigureAwait(false); } if (frontFaceBottom == frontFaceColour && rightFaceBottom == leftFaceColour) { await CommonActions.ApplyAndAddRotation(Rotations.SecondLayerUpperAntiClockwise, solution, configuration).ConfigureAwait(false); await PerformFlip(solution, configuration).ConfigureAwait(false); await CommonActions.ApplyAndAddRotation(Rotations.SecondLayerUpperClockwise, solution, configuration).ConfigureAwait(false); } if (frontFaceTop == leftFaceColour && rightFaceTop == frontFaceColour) { await PerformFlip(solution, configuration).ConfigureAwait(false); await CommonActions.ApplyAndAddRotation(Rotations.SecondLayerUpperAntiClockwise, solution, configuration).ConfigureAwait(false); await PerformFlip(solution, configuration).ConfigureAwait(false); await CommonActions.ApplyAndAddRotation(Rotations.SecondLayerUpperClockwise, solution, configuration).ConfigureAwait(false); } if (frontFaceBottom == leftFaceColour && rightFaceBottom == frontFaceColour) { await PerformFlip(solution, configuration).ConfigureAwait(false); await CommonActions.ApplyAndAddRotation(Rotations.SecondLayerUpperAntiClockwise, solution, configuration).ConfigureAwait(false); await PerformFlip(solution, configuration).ConfigureAwait(false); await CommonActions.ApplyAndAddRotation(Rotations.SecondLayerUpperClockwise, solution, configuration).ConfigureAwait(false); } }
private static async Task CheckBackLeftEdge(CubeConfiguration<FaceColour> configuration, List<IRotation> solution) { var frontFaceColour = configuration.Faces[FaceType.Front].LeftCentre(); var leftFaceColour = configuration.Faces[FaceType.Left].RightCentre(); var rightEdgeOnFace = configuration.Faces[FaceType.Back].GetEdge(Edge.Right); var backFaceTop = rightEdgeOnFace[configuration.MinInnerLayerIndex()]; var backFaceBottom = rightEdgeOnFace[configuration.MaxInnerLayerIndex()]; var leftEdgeOnLeftFace = configuration.Faces[FaceType.Left].GetEdge(Edge.Left); var leftFaceTop = leftEdgeOnLeftFace[configuration.MinInnerLayerIndex()]; var leftFaceBottom = leftEdgeOnLeftFace[configuration.MaxInnerLayerIndex()]; if ((backFaceTop == frontFaceColour && leftFaceTop == leftFaceColour) || (backFaceBottom == frontFaceColour && leftFaceBottom == leftFaceColour) || (backFaceTop == leftFaceColour && leftFaceTop == frontFaceColour) || (backFaceBottom == leftFaceColour && leftFaceBottom == frontFaceColour)) { await CommonActions.ApplyAndAddRotation(Rotations.Back2, solution, configuration).ConfigureAwait(false); await CommonActions.ApplyAndAddRotation(Rotations.Right2, solution, configuration).ConfigureAwait(false); await CheckFrontRightEdge(configuration, solution).ConfigureAwait(false); } }
private static TredgeMatch MatchColoursOnDownFaceEdge(CubeConfiguration<FaceColour> configuration, FaceColour frontColour, FaceColour leftColour, FaceType face) { var bottomEdge = configuration.Faces[face].GetEdge(Edge.Bottom); var frontBottomLeft = bottomEdge[configuration.MinInnerLayerIndex()]; var frontBottomRight = bottomEdge[configuration.MaxInnerLayerIndex()]; Edge edge; switch (face) { case FaceType.Front: edge = Edge.Top; break; case FaceType.Back: edge = Edge.Bottom; break; case FaceType.Left: edge = Edge.Left; break; case FaceType.Right: edge = Edge.Right; break; default: throw new InvalidOperationException("Cannot get connecting edge as down layer does not connect to " + face); } var downLayerEdge = configuration.Faces[FaceType.Down].GetEdge(edge); if (face == FaceType.Back || face == FaceType.Left) { downLayerEdge = downLayerEdge.Reverse().ToArray(); } var downTopLeft = downLayerEdge[configuration.MinInnerLayerIndex()]; var downTopRight = downLayerEdge[configuration.MaxInnerLayerIndex()]; if (frontBottomLeft == frontColour && downTopLeft == leftColour) { return TredgeMatch.FrontLeftMatchesCenter; } if (frontBottomRight == frontColour && downTopRight == leftColour) { return TredgeMatch.FrontRightMatchesCenter; } if (frontBottomLeft == leftColour && downTopLeft == frontColour) { return TredgeMatch.DownLeftMatchesCenter; } if (frontBottomRight == leftColour && downTopRight == frontColour) { return TredgeMatch.DownRightMatchesCenter; } return TredgeMatch.None; }
private static async Task CheckUpperBottomLeft(CubeConfiguration<FaceColour> configuration, List<IRotation> solution, FaceColour frontFaceColour) { var bottomLeft = configuration.Faces[FaceType.Upper].GetEdge(configuration.MinInnerLayerIndex(), Edge.Bottom)[configuration.MinInnerLayerIndex()]; if (bottomLeft == frontFaceColour) { for (int i = 0; i <= 3; i++) { if (configuration.Faces[FaceType.Front].GetEdge(configuration.MinInnerLayerIndex(), Edge.Top)[configuration.MinInnerLayerIndex()] != frontFaceColour) { await CommonActions.ApplyAndAddRotation(Rotations.SecondLayerLeftAntiClockwise, solution, configuration).ConfigureAwait(false); await CommonActions.ApplyAndAddRotation(Rotations.UpperAntiClockwise, solution, configuration).ConfigureAwait(false); await CommonActions.ApplyAndAddRotation(Rotations.SecondLayerLeftClockwise, solution, configuration).ConfigureAwait(false); await CommonActions.ApplyAndAddRotation(Rotations.UpperAntiClockwise, solution, configuration).ConfigureAwait(false); await CommonActions.ApplyAndAddRotation(Rotations.SecondLayerLeftAntiClockwise, solution, configuration).ConfigureAwait(false); await CommonActions.ApplyAndAddRotation(Rotations.Upper2, solution, configuration).ConfigureAwait(false); await CommonActions.ApplyAndAddRotation(Rotations.SecondLayerLeftClockwise, solution, configuration).ConfigureAwait(false); break; } await CommonActions.ApplyAndAddRotation(Rotations.FrontClockwise, solution, configuration).ConfigureAwait(false); } } }