/** * Returns a Block type that represnts an orientation of a the axis with * the given argument as the face of the * * Used in the rotation function. */ public static Orientor GetOrientation(Color face) { Orientor orientor; switch (face) { case Color.White: orientor = new Orientor(Color.Red, Color.Orange, Color.White, Color.Yellow, Color.Blue, Color.Green); break; case Color.Yellow: orientor = new Orientor(Color.Red, Color.Orange, Color.Yellow, Color.White, Color.Green, Color.Blue); break; case Color.Red: orientor = new Orientor(Color.White, Color.Yellow, Color.Red, Color.Orange, Color.Green, Color.Blue); break; case Color.Orange: orientor = new Orientor(Color.White, Color.Yellow, Color.Orange, Color.Red, Color.Blue, Color.Green); break; case Color.Green: orientor = new Orientor(Color.White, Color.Yellow, Color.Green, Color.Blue, Color.Orange, Color.Red); break; case Color.Blue: orientor = new Orientor(Color.White, Color.Yellow, Color.Blue, Color.Green, Color.Red, Color.Orange); break; default: throw new Exception("Invalid face"); } return(orientor); }
/// <summary> /// this function moves the corner to the bottom layer /// </summary> /// <param name="front_face_color">this parameter is a color from a face</param> private void PutCornerInBottomLayer(Color front_face_color) { Orientor front_face = Cube.GetOrientation(front_face_color); cube.Rotate(front_face.right, Direction.CounterClockwise); cube.Rotate(front_face.bottom, Direction.CounterClockwise); cube.Rotate(front_face.right, Direction.Clockwise); }
/// <summary> /// this functions does the corner algorithm that moves the corners around /// </summary> /// <param name="front_face_color">this parameter is a color that will make a block</param> private void CornersRotation(Color front_face_color) { Orientor front_face = Cube.GetOrientation(front_face_color); //Ri Di R D cube.Rotate(front_face.right, Direction.CounterClockwise); cube.Rotate(front_face.bottom, Direction.CounterClockwise); cube.Rotate(front_face.right, Direction.Clockwise); cube.Rotate(front_face.bottom, Direction.Clockwise); }
/// <summary> /// this function does the final turns to complete the cube /// </summary> private void CornersRotationFinal() { Orientor front_face = Cube.GetOrientation(Color.Green); //Ri Di R D cube.Rotate(front_face.left, Direction.CounterClockwise); cube.Rotate(front_face.top, Direction.CounterClockwise); cube.Rotate(front_face.left, Direction.Clockwise); cube.Rotate(front_face.top, Direction.Clockwise); }
/// <summary> /// this functuion hold the algorithm for changing middle edges. /// </summary> /// <param name="oriented">this parameter is how the cube should look if it was solved as a block</param> private void MiddleLayerEdgeLeftRotation(Orientor oriented) { // Ui Fi U F U R Ui Ri :: // Di Fi D F D L Di Li cube.Rotate(oriented.bottom, Direction.CounterClockwise); cube.Rotate(oriented.front, Direction.CounterClockwise); cube.Rotate(oriented.bottom, Direction.Clockwise); cube.Rotate(oriented.front, Direction.Clockwise); cube.Rotate(oriented.bottom, Direction.Clockwise); cube.Rotate(oriented.left, Direction.Clockwise); cube.Rotate(oriented.bottom, Direction.CounterClockwise); cube.Rotate(oriented.left, Direction.CounterClockwise); }
/** * Used for when this is an orientation, will return the block in the * position specified given a face. */ public Block GetBlock(int x, int y, Color face) { Orientor orientation = GetOrientation(face); List <Block> slice = GetSlice(face); var block = from Block b in slice select b; /* These are intended to fall through. */ switch (x) { case 0: slice = GetSlice(orientation.left, slice); break; case 2: slice = GetSlice(orientation.right, slice); break; } switch (y) { case 0: slice = GetSlice(orientation.bottom, slice); break; case 2: slice = GetSlice(orientation.top, slice); break; } if (slice.Count == 1) //only have one, then we good! { return(slice[0]); // TODO: cast this to block type? } /* if we get here, we had a non-corner piece, so get rid of the corners. */ var non_corners = from Block wantedBlock in slice where (wantedBlock.top == Color.Hidden && wantedBlock.bottom == Color.Hidden) || (wantedBlock.left == Color.Hidden && wantedBlock.right == Color.Hidden) || (wantedBlock.back == Color.Hidden && wantedBlock.front == Color.Hidden) select wantedBlock; List <Block> toReturn = new List <Block>(); foreach (Block c in non_corners) { toReturn.Add(c); } if (toReturn.Count != 1) { throw new Exception("Error with 2d Orientation"); } return(toReturn[0]); // TODO: cast to block type? }
/// <summary> /// this function is the algorithm used in solving the bottom face /// </summary> /// <param name="front_face_color">this parameter is the front facing face</param> private void SolveBottomEdgesRotation(Color front_face_color) { Orientor front_face = Cube.GetOrientation(front_face_color); // R U R' U R U U R' // L B L' B L B B L' cube.Rotate(front_face.left, Direction.Clockwise); cube.Rotate(front_face.bottom, Direction.Clockwise); cube.Rotate(front_face.left, Direction.CounterClockwise); cube.Rotate(front_face.bottom, Direction.Clockwise); cube.Rotate(front_face.left, Direction.Clockwise); cube.Rotate(front_face.bottom, Direction.Clockwise); cube.Rotate(front_face.bottom, Direction.Clockwise); cube.Rotate(front_face.left, Direction.CounterClockwise); }
/// <summary> /// this function will solve the middle layer /// </summary> /// <param name="front">this parameter is used to find a front face</param> public void SolveMiddleLayer(Color front) { Edge gr_edge_corr_orient = new Edge(Color.Hidden, Color.Hidden, Color.Green, Color.Hidden, Color.Hidden, Color.Red); Edge rb_edge_corr_orient = new Edge(Color.Hidden, Color.Hidden, Color.Hidden, Color.Blue, Color.Hidden, Color.Red); Edge bo_edge_corr_orient = new Edge(Color.Hidden, Color.Hidden, Color.Hidden, Color.Blue, Color.Purple, Color.Hidden); Edge go_edge_corr_orient = new Edge(Color.Hidden, Color.Hidden, Color.Green, Color.Hidden, Color.Purple, Color.Hidden); /* BASE CASE */ if (front > Color.Blue) // All sides have been solved { return; } Orientor orientation = Cube.GetOrientation(front); Edge target_edge = (Edge)cube.GetBlock(orientation.left, true, cube.GetBlock(orientation.front, true))[0]; if (target_edge.Equals(gr_edge_corr_orient) || target_edge.Equals(rb_edge_corr_orient) || target_edge.Equals(bo_edge_corr_orient) || target_edge.Equals(go_edge_corr_orient)) { front++; } else if (target_edge.bottom == orientation.left || target_edge.bottom == orientation.front) // Edge is on bottom { Color side_where_found = RotateBottomEdgeIntoPlace(orientation, target_edge); if (side_where_found == orientation.front) { MiddleLayerEdgeFrontRotation(orientation); } else { MiddleLayerEdgeLeftRotation(orientation); } front++; } else // Edge is in middle layer { // Find our edge piece by rotating the cube and looking for it on the right Orientor target_orient = FindBlockInMiddleLayer(target_edge); MiddleLayerEdgeLeftRotation(target_orient); } //gui.Refresh(); SolveMiddleLayer(front); }
/// <summary> /// this function is the algorithm for the bottom corners /// </summary> /// <param name="front_face_color">this parameter is the face at the front</param> private void SolveBottomCornersRotation(Color front_face_color) { Orientor front_face = Cube.GetOrientation(front_face_color); //U R U' L' U R' U' L :: //D L D' R' D L' D' R cube.Rotate(front_face.bottom, Direction.Clockwise); cube.Rotate(front_face.left, Direction.Clockwise); cube.Rotate(front_face.bottom, Direction.CounterClockwise); cube.Rotate(front_face.right, Direction.CounterClockwise); cube.Rotate(front_face.bottom, Direction.Clockwise); cube.Rotate(front_face.left, Direction.CounterClockwise); cube.Rotate(front_face.bottom, Direction.CounterClockwise); cube.Rotate(front_face.right, Direction.Clockwise); }
/// <summary> /// this function rotates a face of the cube.(fully commented) /// </summary> /// <param name="color">this parameter is the face that will be rotated</param> /// <param name="direction">this parameter is the the direction that is rotated</param> public void Rotate(Color color, Direction direction) { List<Block> slice = GetSlice(color);//takes a slice of the cube depending on the color Orientor orientation = GetOrientation(color);//takes a orientor of the cube Edge leftmid = (Edge)GetBlock(0, 1, color);//makes copys of an edge block Edge topmid = (Edge)GetBlock(1, 2, color);//makes copys of an edge block Edge rightmid = (Edge)GetBlock(2, 1, color);//makes copys of an edge block Edge botmid = (Edge)GetBlock(1, 0, color);//makes copys of an edge block Corner topleft = (Corner)GetBlock(0, 2, color);//makes copys of an corner block Corner topright = (Corner)GetBlock(2, 2, color);//makes copys of an corner block Corner botleft = (Corner)GetBlock(0, 0, color);//makes copys of an corner block Corner botright = (Corner)GetBlock(2, 0, color);//makes copys of an corner block if (direction == Direction.Clockwise)//checks if direction is clockwise { Edge edge_bucket = leftmid;//makes a temp variable to be used in rotaing leftmid = (Edge)botmid.Rotate(direction, color);//moves a block to another posision botmid = (Edge)rightmid.Rotate(direction, color);//moves a block to another posision rightmid = (Edge)topmid.Rotate(direction, color);//moves a block to another posision topmid = (Edge)edge_bucket.Rotate(direction, color);//puts temp to a position Corner corner_bucket = topleft;//makes a temp variable to be used in rotaing topleft = (Corner)botleft.Rotate(direction, color);//moves a block to another posision botleft = (Corner)botright.Rotate(direction, color);//moves a block to another posision botright = (Corner)topright.Rotate(direction, color);//moves a block to another posision topright = (Corner)corner_bucket.Rotate(direction, color);//puts temp to a position } else//if it is direction is anti-clockwise { Edge edge_bucket = leftmid;//makes a temp variable to be used in rotaing leftmid = (Edge)topmid.Rotate(direction, color);//moves a block to another posision topmid = (Edge)rightmid.Rotate(direction, color);//moves a block to another posision rightmid = (Edge)botmid.Rotate(direction, color);//moves a block to another posision botmid = (Edge)edge_bucket.Rotate(direction, color);//puts temp to a position Corner corner_bucket = topleft;//makes a temp variable to be used in rotaing topleft = (Corner)topright.Rotate(direction, color);//moves a block to another posision topright = (Corner)botright.Rotate(direction, color);//moves a block to another posision botright = (Corner)botleft.Rotate(direction, color);//moves a block to another posision botleft = (Corner)corner_bucket.Rotate(direction, color);//puts temp to a position } Console.WriteLine("Rotated " + color + " to " + direction); }
/** * Moves all of the blocks in the specified color slice * the direction specified. */ public void Rotate(Color color, Direction direction) { List <Block> slice = GetSlice(color); Orientor orientation = GetOrientation(color); Edge leftmid = (Edge)GetBlock(0, 1, color); Edge topmid = (Edge)GetBlock(1, 2, color); Edge rightmid = (Edge)GetBlock(2, 1, color); Edge botmid = (Edge)GetBlock(1, 0, color); Corner topleft = (Corner)GetBlock(0, 2, color); Corner topright = (Corner)GetBlock(2, 2, color); Corner botleft = (Corner)GetBlock(0, 0, color); Corner botright = (Corner)GetBlock(2, 0, color); if (direction == Direction.Clockwise) { Edge edge_bucket = leftmid; leftmid = (Edge)botmid.Rotate(direction, color); botmid = (Edge)rightmid.Rotate(direction, color); rightmid = (Edge)topmid.Rotate(direction, color); topmid = (Edge)edge_bucket.Rotate(direction, color); Corner corner_bucket = topleft; topleft = (Corner)botleft.Rotate(direction, color); botleft = (Corner)botright.Rotate(direction, color); botright = (Corner)topright.Rotate(direction, color); topright = (Corner)corner_bucket.Rotate(direction, color); } else { Edge edge_bucket = leftmid; leftmid = (Edge)topmid.Rotate(direction, color); topmid = (Edge)rightmid.Rotate(direction, color); rightmid = (Edge)botmid.Rotate(direction, color); botmid = (Edge)edge_bucket.Rotate(direction, color); Corner corner_bucket = topleft; topleft = (Corner)topright.Rotate(direction, color); topright = (Corner)botright.Rotate(direction, color); botright = (Corner)botleft.Rotate(direction, color); botleft = (Corner)corner_bucket.Rotate(direction, color); } //Console.WriteLine("Rotated " + color + " to " + direction); }
/// <summary> /// this function moves the edge to a cross /// </summary> /// <param name="edge_piece">this parameter checks if it is facing the top and if so will move it around then</param> /// <param name="front_face">this parameter is the face that is moved around</param> private void PlaceBottomEdgePieceInCross(Edge edge_piece, Orientor front_face) { //if the edge piece has white facing bottom, //cube.Rotate face twice to put it in the correct position for the cross. if (edge_piece.bottom == Color.White) { cube.Rotate(front_face.front, Direction.Clockwise); cube.Rotate(front_face.front, Direction.Clockwise); } //else the other color (not white) is facing down, apply this algorithm //to put the piece in the correct position. else { cube.Rotate(front_face.bottom, Direction.Clockwise); cube.Rotate(front_face.right, Direction.Clockwise); cube.Rotate(front_face.front, Direction.CounterClockwise); cube.Rotate(front_face.right, Direction.CounterClockwise); } }
/// <summary> /// this function is rotates the cube until the bottom edges are in the right place /// </summary> /// <param name="oriented">this parameter is how the cube should look if it was solved as a block</param> /// <param name="edge">this parameter makes a edge piece to be used</param> /// <returns></returns> private Color RotateBottomEdgeIntoPlace(Orientor oriented, Block edge) { /******** if edge supposed to be under oriented.front *******/ if (edge.back == oriented.front || edge.front == oriented.front || edge.left == oriented.front || edge.right == oriented.front) { if (oriented.front == Color.Green) { while (!edge.Equals(cube.GetBlock(1, 0, 0))) { cube.Rotate(oriented.bottom, Direction.Clockwise); } } else if (oriented.front == Color.Red) { while (!edge.Equals(cube.GetBlock(2, 0, 1))) { cube.Rotate(oriented.bottom, Direction.Clockwise); } } else if (oriented.front == Color.Blue) { while (!edge.Equals(cube.GetBlock(1, 0, 2))) { cube.Rotate(oriented.bottom, Direction.Clockwise); } } else if (oriented.front == Color.Purple) { while (!edge.Equals(cube.GetBlock(0, 0, 1))) { cube.Rotate(oriented.bottom, Direction.Clockwise); } } return(oriented.front); } //if edge supposed to be under oriented.left else if (edge.back == oriented.left || edge.front == oriented.left || edge.left == oriented.left || edge.right == oriented.left) { if (oriented.left == Color.Green) { while (!edge.Equals(cube.GetBlock(1, 0, 0))) { cube.Rotate(oriented.bottom, Direction.Clockwise); } } else if (oriented.left == Color.Red) { while (!edge.Equals(cube.GetBlock(2, 0, 1))) { cube.Rotate(oriented.bottom, Direction.Clockwise); } } else if (oriented.left == Color.Blue) { while (!edge.Equals(cube.GetBlock(1, 0, 2))) { cube.Rotate(oriented.bottom, Direction.Clockwise); } } else if (oriented.left == Color.Purple) { while (!edge.Equals(cube.GetBlock(0, 0, 1))) { cube.Rotate(oriented.bottom, Direction.Clockwise); } } return(oriented.left); /************************************************************/ } return(Color.Hidden); }