/// <summary> /// for the turns, the sides are rotated to the front /// the y-axis points upwards, the x-axis to the right and the z-axis backwards /// for the left side, the cube is turned 90 degrees counterclockwise around the y-axis /// for the right side, the cube is turned 90 degrees clockwise around the y-axis /// for the top side, the cube is turned 90 degrees counterclockwise around the x-axis /// for the bottom side, the cube is turned 90 degrees clockwise around the x-axis /// for the back side, the cube is turned 180 degrees around the y-axis /// /// the notations in the method are marked according to this page: /// https://rubiks.com/uploads/general_content/Rubiks_cube_3x3_solution-en.pdf /// /// the rotations need to run in separate threads, because otherwise they would run in the UI thread /// but because the events have to await until the storyboard finished, the rotation method's execution continues /// so basically there is no way to wait until the rotation is finished in the UI for the rest of the methods to continue /// therefore they have to run in a second thread, so that the event also runs in a second thread /// the event handler can then synchronously wait for a task executed with the dispatcher to finish /// </summary> /// <summary> /// F /// </summary> public void RotateFrontCW(bool raiseEvents = true) { if (raiseEvents) { raiseBeforeFrontCWRotation(); } var tempRow = top.GetRow(2); top.SetRow(2, left.GetColumn(2).Reverse().ToArray()); left.SetColumn(2, bottom.GetRow(0)); bottom.SetRow(0, right.GetColumn(0).Reverse().ToArray()); right.SetColumn(0, tempRow); front.RotateCW(); raiseAfterFrontCWRotation(); }
/// <summary> /// L /// </summary> public void RotateLeftCW(bool raiseEvents = true) { if (raiseEvents) { raiseBeforeLeftCWRotation(); } var tempColumn = top.GetColumn(0); top.SetColumn(0, back.GetColumn(2).Reverse().ToArray()); back.SetColumn(2, bottom.GetColumn(0).Reverse().ToArray()); bottom.SetColumn(0, front.GetColumn(0)); front.SetColumn(0, tempColumn); left.RotateCW(); if (raiseEvents) { raiseAfterLeftCWRotation(); } }
public Brush GetSecondaryEdgeColor(RelativeEdgePosition edgePosition) { //these 2 (top, bottom) sides are special cases, because they change the column/row alignment with other sides if (CubeSide == Sides.Top) { switch (edgePosition) { case RelativeEdgePosition.Left: return(left.GetRow(0)[1]); case RelativeEdgePosition.Right: return(right.GetRow(0)[1]); case RelativeEdgePosition.Top: return(top.GetRow(0)[1]); case RelativeEdgePosition.Bottom: return(bottom.GetRow(0)[1]); } } if (CubeSide == Sides.Bottom) { switch (edgePosition) { case RelativeEdgePosition.Left: return(left.GetRow(2)[1]); case RelativeEdgePosition.Right: return(right.GetRow(2)[1]); case RelativeEdgePosition.Top: return(top.GetRow(2)[1]); case RelativeEdgePosition.Bottom: return(bottom.GetRow(2)[1]); } } else { if (edgePosition == RelativeEdgePosition.Left) { return(left.GetColumn(2)[1]); } if (edgePosition == RelativeEdgePosition.Right) { return(right.GetColumn(0)[1]); } if (edgePosition == RelativeEdgePosition.Top) { //only has to handle the remaining 4 cases (top and bottom are handled before) switch (CubeSide) { case Sides.Front: return(top.GetRow(2)[1]); case Sides.Left: return(top.GetColumn(0)[1]); case Sides.Back: return(top.GetRow(0)[1]); case Sides.Right: return(top.GetColumn(2)[1]); } } if (edgePosition == RelativeEdgePosition.Bottom) { //only has to handle the remaining 4 cases (top and bottom are handled before) switch (CubeSide) { case Sides.Front: return(bottom.GetRow(0)[1]); case Sides.Left: return(bottom.GetColumn(0)[1]); case Sides.Back: return(bottom.GetRow(2)[1]); case Sides.Right: return(bottom.GetColumn(2)[1]); } } } return(null); //default case to satisfy the compiler, should never occur }