public Cube3D Rotate(Point3D.RotationType type, double angle, Point3D center) { //Deep Clone List <Face3D> faces = new List <Face3D>(); foreach (Face3D f in Faces) { List <Point3D> edges = new List <Point3D>(); foreach (Point3D p in f.Edges) { edges.Add(new Point3D(p.X, p.Y, p.Z)); } Face3D f2 = new Face3D(edges, f.Color, f.Position, f.MasterPosition, f.Selection); f2.Edges.ToList().ForEach(e => { e.X -= center.X; e.Y -= center.Y; e.Z -= center.Z; }); f2.Rotate(type, angle); f2.Edges.ToList().ForEach(e => { e.X += center.X; e.Y += center.Y; e.Z += center.Z; }); faces.Add(f2); } return(new Cube3D(faces, Position)); }
public Face3D Clone() { Face3D newFace = new Face3D(new List <Point3D>(Edges.Select(e => e.Clone())), Color, Position, MasterPosition, Selection); return(newFace); }
private void Form1_MouseClick(object sender, MouseEventArgs e) { if (e.Button == System.Windows.Forms.MouseButtons.Left) { if (oldSelection.cubePos == Cube3D.RubikPosition.None || oldSelection.facePos == Face3D.FacePosition.None) { if (currentSelection.cubePos == Cube3D.RubikPosition.None || currentSelection.facePos == Face3D.FacePosition.None) { rubikManager.RubikCube.cubes.ForEach(c => c.Faces.ToList().ForEach(f => f.Selection = Face3D.SelectionMode.None)); oldSelection = new RubikManager.PositionSpec() { cubePos = Cube3D.RubikPosition.None, facePos = Face3D.FacePosition.None }; currentSelection = new RubikManager.PositionSpec() { cubePos = Cube3D.RubikPosition.None, facePos = Face3D.FacePosition.None }; } else { if (!Cube3D.isCorner(currentSelection.cubePos)) { oldSelection = currentSelection; rubikManager.RubikCube.cubes.ForEach(c => c.Faces.ToList().ForEach(f => { if (currentSelection.cubePos != c.Position && !Cube3D.isCenter(c.Position) && currentSelection.facePos == f.Position) { Cube3D.RubikPosition assocLayer = Face3D.layerAssocToFace(currentSelection.facePos); Cube3D.RubikPosition commonLayer = Cube3D.getCommonLayer(currentSelection.cubePos, c.Position, assocLayer); if (commonLayer != Cube3D.RubikPosition.None && c.Position.HasFlag(commonLayer)) { f.Selection |= Face3D.SelectionMode.Possible; } else { f.Selection |= Face3D.SelectionMode.NotPossible; } } else { f.Selection |= Face3D.SelectionMode.NotPossible; } })); toolStripStatusLabel1.Text = "First selection: [" + currentSelection.cubePos.ToString() + "] | " + currentSelection.facePos.ToString();; } else { rubikManager.RubikCube.cubes.ForEach(c => c.Faces.ToList().ForEach(f => f.Selection = Face3D.SelectionMode.None)); toolStripStatusLabel1.Text = "Error: Invalid first selection, must not be a corner"; } } } else { if (currentSelection.cubePos == Cube3D.RubikPosition.None || currentSelection.facePos == Face3D.FacePosition.None) { toolStripStatusLabel1.Text = "Ready"; } else { if (currentSelection.cubePos != oldSelection.cubePos) { if (!Cube3D.isCenter(currentSelection.cubePos)) { if (oldSelection.facePos == currentSelection.facePos) { Cube3D.RubikPosition assocLayer = Face3D.layerAssocToFace(oldSelection.facePos); Cube3D.RubikPosition commonLayer = Cube3D.getCommonLayer(oldSelection.cubePos, currentSelection.cubePos, assocLayer); Boolean direction = true; if (commonLayer == Cube3D.RubikPosition.TopLayer || commonLayer == Cube3D.RubikPosition.MiddleLayer || commonLayer == Cube3D.RubikPosition.BottomLayer) { if (((oldSelection.facePos == Face3D.FacePosition.Front) && currentSelection.cubePos.HasFlag(Cube3D.RubikPosition.LeftSlice)) || ((oldSelection.facePos == Face3D.FacePosition.Right) && currentSelection.cubePos.HasFlag(Cube3D.RubikPosition.FrontSlice)) || ((oldSelection.facePos == Face3D.FacePosition.Back) && currentSelection.cubePos.HasFlag(Cube3D.RubikPosition.RightSlice)) || ((oldSelection.facePos == Face3D.FacePosition.Left) && currentSelection.cubePos.HasFlag(Cube3D.RubikPosition.BackSlice))) { direction = false; } } if (commonLayer == Cube3D.RubikPosition.LeftSlice || commonLayer == Cube3D.RubikPosition.MiddleSlice_Sides || commonLayer == Cube3D.RubikPosition.RightSlice) { if (((oldSelection.facePos == Face3D.FacePosition.Top) && currentSelection.cubePos.HasFlag(Cube3D.RubikPosition.FrontSlice)) || ((oldSelection.facePos == Face3D.FacePosition.Front) && currentSelection.cubePos.HasFlag(Cube3D.RubikPosition.BottomLayer)) || ((oldSelection.facePos == Face3D.FacePosition.Bottom) && currentSelection.cubePos.HasFlag(Cube3D.RubikPosition.BackSlice)) || ((oldSelection.facePos == Face3D.FacePosition.Back) && currentSelection.cubePos.HasFlag(Cube3D.RubikPosition.TopLayer))) { direction = false; } } if (commonLayer == Cube3D.RubikPosition.BackSlice || commonLayer == Cube3D.RubikPosition.MiddleSlice || commonLayer == Cube3D.RubikPosition.FrontSlice) { if (((oldSelection.facePos == Face3D.FacePosition.Top) && currentSelection.cubePos.HasFlag(Cube3D.RubikPosition.RightSlice)) || ((oldSelection.facePos == Face3D.FacePosition.Right) && currentSelection.cubePos.HasFlag(Cube3D.RubikPosition.BottomLayer)) || ((oldSelection.facePos == Face3D.FacePosition.Bottom) && currentSelection.cubePos.HasFlag(Cube3D.RubikPosition.LeftSlice)) || ((oldSelection.facePos == Face3D.FacePosition.Left) && currentSelection.cubePos.HasFlag(Cube3D.RubikPosition.TopLayer))) { direction = false; } } if (commonLayer != Cube3D.RubikPosition.None) { if (groupBox1.Enabled) { groupBox1.Enabled = false; rotationTicks = 25; rubikManager.Rotate90(commonLayer, direction, rotationTicks); comboBox1.Text = commonLayer.ToString(); toolStripStatusLabel1.Text = "Rotating " + commonLayer.ToString() + " " + ((direction) ? "Clockwise" : "Counter-Clockwise"); } } else { toolStripStatusLabel1.Text = "Error: Invalid second selection, does not specify distinct layer"; } } else { toolStripStatusLabel1.Text = "Error: Invalid second selection, must match orientation of first selection"; } } else { toolStripStatusLabel1.Text = "Error: Invalid second selection, must not be a center"; } } else { toolStripStatusLabel1.Text = "Error: Invalid second selection, must not be first selection"; } } rubikManager.RubikCube.cubes.ForEach(c => c.Faces.ToList().ForEach(f => f.Selection = Face3D.SelectionMode.None)); oldSelection = new RubikManager.PositionSpec() { cubePos = Cube3D.RubikPosition.None, facePos = Face3D.FacePosition.None }; currentSelection = new RubikManager.PositionSpec() { cubePos = Cube3D.RubikPosition.None, facePos = Face3D.FacePosition.None }; } } }
private void Form1_MouseClick(object sender, MouseEventArgs e) { if (e.Button == System.Windows.Forms.MouseButtons.Left) { if ((Control.ModifierKeys & Keys.Shift) != 0) { if (currentSelection.CubePosition != Cube3D.RubikPosition.None && currentSelection.FacePosition != Face3D.FacePosition.None) { Color clr = rubikRenderer.RubikManager.getFaceColor(currentSelection.CubePosition, currentSelection.FacePosition); int ind = 0; for (int i = 0; i < contextMenuStrip1.Items.Count; i++) { if (contextMenuStrip1.Items[i].Text == clr.Name) { ind = i; } } ind++; if (ind >= colors.Length) { ind = 0; } rubikRenderer.RubikManager.setFaceColor(currentSelection.CubePosition, currentSelection.FacePosition, colors[ind]); } } else { if (!contextMenuStrip1.Visible) { if (oldSelection.CubePosition == Cube3D.RubikPosition.None || oldSelection.FacePosition == Face3D.FacePosition.None) { if (currentSelection.CubePosition == Cube3D.RubikPosition.None || currentSelection.FacePosition == Face3D.FacePosition.None) { rubikRenderer.RubikManager.RubikCube.cubes.ForEach(c => c.Faces.ToList().ForEach(f => f.Selection = Face3D.SelectionMode.None)); oldSelection = new PositionSpec() { CubePosition = Cube3D.RubikPosition.None, FacePosition = Face3D.FacePosition.None }; currentSelection = new PositionSpec() { CubePosition = Cube3D.RubikPosition.None, FacePosition = Face3D.FacePosition.None }; } else { if (!Cube3D.isCorner(currentSelection.CubePosition)) { oldSelection = currentSelection; rubikRenderer.RubikManager.RubikCube.cubes.ForEach(c => c.Faces.ToList().ForEach(f => { if (currentSelection.CubePosition != c.Position && !Cube3D.isCenter(c.Position) && currentSelection.FacePosition == f.Position) { Cube3D.RubikPosition assocLayer = Face3D.layerAssocToFace(currentSelection.FacePosition); Cube3D.RubikPosition commonLayer = Cube3D.getCommonLayer(currentSelection.CubePosition, c.Position, assocLayer); if (commonLayer != Cube3D.RubikPosition.None && c.Position.HasFlag(commonLayer)) { f.Selection |= Face3D.SelectionMode.Possible; } else { f.Selection |= Face3D.SelectionMode.NotPossible; } } else { f.Selection |= Face3D.SelectionMode.NotPossible; } })); toolStripStatusLabel1.Text = "First selection: [" + currentSelection.CubePosition.ToString() + "] | " + currentSelection.FacePosition.ToString();; } else { rubikRenderer.RubikManager.RubikCube.cubes.ForEach(c => c.Faces.ToList().ForEach(f => f.Selection = Face3D.SelectionMode.None)); toolStripStatusLabel1.Text = "Error: Invalid first selection, must not be a corner"; } } } else { if (currentSelection.CubePosition == Cube3D.RubikPosition.None || currentSelection.FacePosition == Face3D.FacePosition.None) { toolStripStatusLabel1.Text = "Ready"; } else { if (currentSelection.CubePosition != oldSelection.CubePosition) { if (!Cube3D.isCenter(currentSelection.CubePosition)) { if (oldSelection.FacePosition == currentSelection.FacePosition) { Cube3D.RubikPosition assocLayer = Face3D.layerAssocToFace(oldSelection.FacePosition); Cube3D.RubikPosition commonLayer = Cube3D.getCommonLayer(oldSelection.CubePosition, currentSelection.CubePosition, assocLayer); Boolean direction = true; if (commonLayer == Cube3D.RubikPosition.TopLayer || commonLayer == Cube3D.RubikPosition.MiddleLayer || commonLayer == Cube3D.RubikPosition.BottomLayer) { if (((oldSelection.FacePosition == Face3D.FacePosition.Back) && currentSelection.CubePosition.HasFlag(Cube3D.RubikPosition.RightSlice)) || ((oldSelection.FacePosition == Face3D.FacePosition.Left) && currentSelection.CubePosition.HasFlag(Cube3D.RubikPosition.BackSlice)) || ((oldSelection.FacePosition == Face3D.FacePosition.Front) && currentSelection.CubePosition.HasFlag(Cube3D.RubikPosition.LeftSlice)) || ((oldSelection.FacePosition == Face3D.FacePosition.Right) && currentSelection.CubePosition.HasFlag(Cube3D.RubikPosition.FrontSlice))) { direction = false; } } if (commonLayer == Cube3D.RubikPosition.LeftSlice || commonLayer == Cube3D.RubikPosition.MiddleSlice_Sides || commonLayer == Cube3D.RubikPosition.RightSlice) { if (((oldSelection.FacePosition == Face3D.FacePosition.Bottom) && currentSelection.CubePosition.HasFlag(Cube3D.RubikPosition.BackSlice)) || ((oldSelection.FacePosition == Face3D.FacePosition.Back) && currentSelection.CubePosition.HasFlag(Cube3D.RubikPosition.TopLayer)) || ((oldSelection.FacePosition == Face3D.FacePosition.Top) && currentSelection.CubePosition.HasFlag(Cube3D.RubikPosition.FrontSlice)) || ((oldSelection.FacePosition == Face3D.FacePosition.Front) && currentSelection.CubePosition.HasFlag(Cube3D.RubikPosition.BottomLayer))) { direction = false; } } if (commonLayer == Cube3D.RubikPosition.BackSlice || commonLayer == Cube3D.RubikPosition.MiddleSlice || commonLayer == Cube3D.RubikPosition.FrontSlice) { if (((oldSelection.FacePosition == Face3D.FacePosition.Top) && currentSelection.CubePosition.HasFlag(Cube3D.RubikPosition.RightSlice)) || ((oldSelection.FacePosition == Face3D.FacePosition.Right) && currentSelection.CubePosition.HasFlag(Cube3D.RubikPosition.BottomLayer)) || ((oldSelection.FacePosition == Face3D.FacePosition.Bottom) && currentSelection.CubePosition.HasFlag(Cube3D.RubikPosition.LeftSlice)) || ((oldSelection.FacePosition == Face3D.FacePosition.Left) && currentSelection.CubePosition.HasFlag(Cube3D.RubikPosition.TopLayer))) { direction = false; } } if (commonLayer != Cube3D.RubikPosition.None) { if (groupBox1.Enabled) { groupBox1.Enabled = false; //rotationTicks = 25; if (commonLayer == Cube3D.RubikPosition.TopLayer || commonLayer == Cube3D.RubikPosition.LeftSlice || commonLayer == Cube3D.RubikPosition.FrontSlice) { direction = !direction; } rubikRenderer.RubikManager.Rotate90(commonLayer, direction, rotationTime); comboBox1.Text = commonLayer.ToString(); toolStripStatusLabel1.Text = "Rotating " + commonLayer.ToString() + " " + ((direction) ? "Clockwise" : "Counter-Clockwise"); } } else { toolStripStatusLabel1.Text = "Error: Invalid second selection, does not specify distinct layer"; } } else { toolStripStatusLabel1.Text = "Error: Invalid second selection, must match orientation of first selection"; } } else { toolStripStatusLabel1.Text = "Error: Invalid second selection, must not be a center"; } } else { toolStripStatusLabel1.Text = "Error: Invalid second selection, must not be first selection"; } } rubikRenderer.RubikManager.RubikCube.cubes.ForEach(c => c.Faces.ToList().ForEach(f => f.Selection = Face3D.SelectionMode.None)); oldSelection = new PositionSpec() { CubePosition = Cube3D.RubikPosition.None, FacePosition = Face3D.FacePosition.None }; currentSelection = new PositionSpec() { CubePosition = Cube3D.RubikPosition.None, FacePosition = Face3D.FacePosition.None }; } } } } if (e.Button == System.Windows.Forms.MouseButtons.Right) { if ((Control.ModifierKeys & Keys.Shift) != 0) { if (currentSelection.CubePosition != Cube3D.RubikPosition.None && currentSelection.FacePosition != Face3D.FacePosition.None) { Color clr = rubikRenderer.RubikManager.getFaceColor(currentSelection.CubePosition, currentSelection.FacePosition); for (int i = 0; i < contextMenuStrip1.Items.Count; i++) { ((ToolStripMenuItem)contextMenuStrip1.Items[i]).Checked = (contextMenuStrip1.Items[i].Text == clr.Name); } contextMenuStrip1.Show(Cursor.Position); } } } }
private void CompleteLastLayer() { //Step 1: Get the color of the top layer to start with cross on the last layer Color topColor = RubikManager.getFaceColor(Cube3D.RubikPosition.TopLayer | Cube3D.RubikPosition.MiddleSlice_Sides | Cube3D.RubikPosition.MiddleSlice, Face3D.FacePosition.Top); //Step 2: Get edges with the color of the top face IEnumerable <Cube3D> topCorners = RubikManager.RubikCube.cubes.Where(c => Cube3D.isCorner(c.Position)).Where(c => c.Position.HasFlag(Cube3D.RubikPosition.TopLayer)); //Step 3: Bring corners to their target position while (topCorners.Where(c => c.Position == GetTargetPosition(c)).Count() < 4) { IEnumerable <Cube3D> correctCorners = topCorners.Where(c => c.Position == GetTargetPosition(c)); Cube3D.RubikPosition rightSlice; if (correctCorners.Count() != 0) { Cube3D firstCube = correctCorners.First(); Face3D rightFace = firstCube.Faces.First(f => f.Color != Color.Black && f.Position != Face3D.FacePosition.Top); rightSlice = FacePosToCubePos(rightFace.Position); RubikManager.SolutionMove(rightSlice, true); if (RefreshCube(firstCube).Position.HasFlag(Cube3D.RubikPosition.TopLayer)) { RubikManager.SolutionMove(rightSlice, false); } else { RubikManager.SolutionMove(rightSlice, false); rightSlice = FacePosToCubePos(firstCube.Faces.First(f => f.Color != rightFace.Color && f.Color != Color.Black && f.Position != Face3D.FacePosition.Top).Position); } } else { rightSlice = Cube3D.RubikPosition.RightSlice; } Cube3D.RubikPosition leftSlice = GetOppositeFace(rightSlice); RubikManager.SolutionMove(Cube3D.RubikPosition.TopLayer, true); RubikManager.SolutionMove(rightSlice, true); RubikManager.SolutionMove(Cube3D.RubikPosition.TopLayer, false); RubikManager.SolutionMove(leftSlice, false); RubikManager.SolutionMove(Cube3D.RubikPosition.TopLayer, true); RubikManager.SolutionMove(rightSlice, false); RubikManager.SolutionMove(Cube3D.RubikPosition.TopLayer, false); RubikManager.SolutionMove(leftSlice, true); topCorners = topCorners.Select(tC => RefreshCube(tC)); correctCorners = correctCorners.Select(cC => RefreshCube(cC)); } //Step 4: Orientation of the corners on the top layer topCorners = topCorners.Select(tC => RefreshCube(tC)); Face3D rightFac = RefreshCube(topCorners.First()).Faces.First(f => f.Color != Color.Black && f.Position != Face3D.FacePosition.Top); Cube3D.RubikPosition rightSlic = FacePosToCubePos(rightFac.Position); RubikManager.SolutionMove(rightSlic, true); if (RefreshCube(topCorners.First()).Position.HasFlag(Cube3D.RubikPosition.TopLayer)) { RubikManager.SolutionMove(rightSlic, false); } else { RubikManager.SolutionMove(rightSlic, false); rightSlic = FacePosToCubePos(topCorners.First().Faces.First(f => f.Color != rightFac.Color && f.Color != Color.Black && f.Position != Face3D.FacePosition.Top).Position); } foreach (Cube3D c in topCorners) { while (!RefreshCube(c).Position.HasFlag(rightSlic)) { RubikManager.SolutionMove(Cube3D.RubikPosition.TopLayer, true); } RubikManager.SolutionMove(rightSlic, true); if (RefreshCube(c).Position.HasFlag(Cube3D.RubikPosition.TopLayer)) { RubikManager.SolutionMove(rightSlic, false); } else { RubikManager.SolutionMove(rightSlic, false); RubikManager.SolutionMove(Cube3D.RubikPosition.TopLayer, true); } //Algorithm: Ri Di R D while (RefreshCube(c).Faces.First(f => f.Position == Face3D.FacePosition.Top).Color != topColor) { RubikManager.SolutionMove(rightSlic, false); RubikManager.SolutionMove(Cube3D.RubikPosition.BottomLayer, false); RubikManager.SolutionMove(rightSlic, true); RubikManager.SolutionMove(Cube3D.RubikPosition.BottomLayer, true); } } topCorners = topCorners.Select(tC => RefreshCube(tC)); while (topCorners.Count(tC => tC.Position == GetTargetPosition(tC)) != 4) { RubikManager.SolutionMove(Cube3D.RubikPosition.TopLayer, true); } }
private void CompleteMiddleLayer() { //Step 1: Get the color of the bottom and top layer Color bottomColor = RubikManager.getFaceColor(Cube3D.RubikPosition.BottomLayer | Cube3D.RubikPosition.MiddleSlice_Sides | Cube3D.RubikPosition.MiddleSlice, Face3D.FacePosition.Bottom); Color topColor = RubikManager.getFaceColor(Cube3D.RubikPosition.TopLayer | Cube3D.RubikPosition.MiddleSlice_Sides | Cube3D.RubikPosition.MiddleSlice, Face3D.FacePosition.Top); //Step 2: Get the egdes of the middle layer IEnumerable <Cube3D> middleEdges = RubikManager.RubikCube.cubes.Where(c => Cube3D.isEdge(c.Position)).Where(c => c.Colors.Count(co => co == bottomColor || co == topColor) == 0); List <Face3D> coloredFaces = new List <Face3D>(); RubikManager.RubikCube.cubes.Where(cu => Cube3D.isCenter(cu.Position)).ToList().ForEach(cu => coloredFaces.Add(cu.Faces.First(f => f.Color != Color.Black).Clone())); IEnumerable <Cube3D> solvedMiddleEdges = middleEdges.Where(mE => mE.Faces.Count(f => coloredFaces.Count(cf => cf.Color == f.Color && cf.Position == f.Position) == 1) == 2); while (solvedMiddleEdges.Count() < 4) { IEnumerable <Cube3D> unsolvedMiddleEdges = middleEdges.Except(solvedMiddleEdges); Cube3D c = (unsolvedMiddleEdges.FirstOrDefault(cu => !cu.Position.HasFlag(Cube3D.RubikPosition.MiddleLayer)) != null) ? unsolvedMiddleEdges.FirstOrDefault(cu => !cu.Position.HasFlag(Cube3D.RubikPosition.MiddleLayer)) : unsolvedMiddleEdges.First(); //Rotate to top layer if (!c.Position.HasFlag(Cube3D.RubikPosition.TopLayer)) { Face3D frontFace = c.Faces.First(f => f.Color != Color.Black); Cube3D.RubikPosition frontSlice = FacePosToCubePos(frontFace.Position); Face3D face = c.Faces.First(f => f.Color != Color.Black && f.Color != frontFace.Color); Cube3D.RubikPosition slice = FacePosToCubePos(face.Position); RubikManager.SolutionMove(slice, true); if (RefreshCube(c).Position.HasFlag(Cube3D.RubikPosition.TopLayer)) { RubikManager.SolutionMove(slice, false); //Algorithm to the right: U R Ui Ri Ui Fi U F RubikManager.SolutionMove(Cube3D.RubikPosition.TopLayer, true); RubikManager.SolutionMove(slice, true); RubikManager.SolutionMove(Cube3D.RubikPosition.TopLayer, false); RubikManager.SolutionMove(slice, false); RubikManager.SolutionMove(Cube3D.RubikPosition.TopLayer, false); RubikManager.SolutionMove(frontSlice, false); RubikManager.SolutionMove(Cube3D.RubikPosition.TopLayer, true); RubikManager.SolutionMove(frontSlice, true); } else { RubikManager.SolutionMove(slice, false); //Algorithm to the left: Ui Li U L U F Ui Fi RubikManager.SolutionMove(Cube3D.RubikPosition.TopLayer, false); RubikManager.SolutionMove(slice, false); RubikManager.SolutionMove(Cube3D.RubikPosition.TopLayer, true); RubikManager.SolutionMove(slice, true); RubikManager.SolutionMove(Cube3D.RubikPosition.TopLayer, true); RubikManager.SolutionMove(frontSlice, true); RubikManager.SolutionMove(Cube3D.RubikPosition.TopLayer, false); RubikManager.SolutionMove(frontSlice, false); } } //Rotate to start position for the algorithm IEnumerable <Cube3D> middles = RubikManager.RubikCube.cubes.Where(cu => Cube3D.isCenter(cu.Position)).Where(m => m.Colors.First(co => co != Color.Black) == RefreshCube(c).Faces.First(f => f.Color != Color.Black && f.Position != Face3D.FacePosition.Top).Color&& RemoveFlag(m.Position, Cube3D.RubikPosition.MiddleLayer) == RemoveFlag(RefreshCube(c).Position, Cube3D.RubikPosition.TopLayer)); while (middles.Count() < 1) { RubikManager.SolutionMove(Cube3D.RubikPosition.TopLayer, true); middles = RubikManager.RubikCube.cubes.Where(cu => Cube3D.isCenter(cu.Position)).Where(m => m.Colors.First(co => co != Color.Black) == RefreshCube(c).Faces.First(f => f.Color != Color.Black && f.Position != Face3D.FacePosition.Top).Color&& RemoveFlag(m.Position, Cube3D.RubikPosition.MiddleLayer) == RemoveFlag(RefreshCube(c).Position, Cube3D.RubikPosition.TopLayer)); } //Rotate to target position Face3D frontFac = RefreshCube(c).Faces.First(f => f.Color != Color.Black && f.Position != Face3D.FacePosition.Top); Cube3D.RubikPosition frontSlic = FacePosToCubePos(frontFac.Position); Cube3D.RubikPosition slic = Cube3D.RubikPosition.None; foreach (Cube3D.RubikPosition p in GetFlags(GetTargetPosition(c))) { if (p != Cube3D.RubikPosition.MiddleLayer && p != frontSlic) { slic |= p; } } RubikManager.SolutionMove(Cube3D.RubikPosition.TopLayer, true); if (!RefreshCube(c).Position.HasFlag(slic)) { RubikManager.SolutionMove(Cube3D.RubikPosition.TopLayer, false); //Algorithm to the right: U R Ui Ri Ui Fi U F RubikManager.SolutionMove(Cube3D.RubikPosition.TopLayer, true); RubikManager.SolutionMove(slic, true); RubikManager.SolutionMove(Cube3D.RubikPosition.TopLayer, false); RubikManager.SolutionMove(slic, false); RubikManager.SolutionMove(Cube3D.RubikPosition.TopLayer, false); RubikManager.SolutionMove(frontSlic, false); RubikManager.SolutionMove(Cube3D.RubikPosition.TopLayer, true); RubikManager.SolutionMove(frontSlic, true); } else { RubikManager.SolutionMove(Cube3D.RubikPosition.TopLayer, false); //Algorithm to the left: Ui Li U L U F Ui Fi RubikManager.SolutionMove(Cube3D.RubikPosition.TopLayer, false); RubikManager.SolutionMove(slic, false); RubikManager.SolutionMove(Cube3D.RubikPosition.TopLayer, true); RubikManager.SolutionMove(slic, true); RubikManager.SolutionMove(Cube3D.RubikPosition.TopLayer, true); RubikManager.SolutionMove(frontSlic, true); RubikManager.SolutionMove(Cube3D.RubikPosition.TopLayer, false); RubikManager.SolutionMove(frontSlic, false); } solvedMiddleEdges = middleEdges.Where(mE => RefreshCube(mE).Faces.Count(f => coloredFaces.Count(cf => cf.Color == f.Color && cf.Position == f.Position) == 1) == 2); } }
private void CompleteFirstLayer() { //Step 1: Get the color of the bottom layer Color bottomColor = RubikManager.getFaceColor(Cube3D.RubikPosition.BottomLayer | Cube3D.RubikPosition.MiddleSlice_Sides | Cube3D.RubikPosition.MiddleSlice, Face3D.FacePosition.Bottom); //Step 2: Get the corners with target position on bottom layer IEnumerable <Cube3D> bottomCorners = RubikManager.RubikCube.cubes.Where(c => Cube3D.isCorner(c.Position) && GetTargetPosition(c).HasFlag(Cube3D.RubikPosition.BottomLayer)); IEnumerable <Cube3D> solvedBottomCorners = bottomCorners.Where(bC => bC.Position == GetTargetPosition(bC) && bC.Faces.First(f => f.Color == bottomColor).Position == Face3D.FacePosition.Bottom); //Step 3: Solve incorrect edges while (solvedBottomCorners.Count() < 4) { IEnumerable <Cube3D> unsolvedBottomCorners = bottomCorners.Except(solvedBottomCorners); Cube3D c = (unsolvedBottomCorners.FirstOrDefault(bC => bC.Position.HasFlag(Cube3D.RubikPosition.TopLayer)) != null) ? unsolvedBottomCorners.FirstOrDefault(bC => bC.Position.HasFlag(Cube3D.RubikPosition.TopLayer)) : unsolvedBottomCorners.First(); if (c.Position != GetTargetPosition(c)) { //Rotate to top layer if (c.Position.HasFlag(Cube3D.RubikPosition.BottomLayer)) { Face3D leftFace = RefreshCube(c).Faces.First(f => f.Position != Face3D.FacePosition.Bottom && f.Color != Color.Black); Cube3D.RubikPosition leftSlice = FacePosToCubePos(leftFace.Position); RubikManager.SolutionMove(leftSlice, false); if (RefreshCube(c).Position.HasFlag(Cube3D.RubikPosition.BottomLayer)) { RubikManager.SolutionMove(leftSlice, true); leftFace = RefreshCube(c).Faces.First(f => f.Position != Face3D.FacePosition.Bottom && f.Color != leftFace.Color && f.Color != Color.Black); leftSlice = FacePosToCubePos(leftFace.Position); RubikManager.SolutionMove(leftSlice, false); } RubikManager.SolutionMove(Cube3D.RubikPosition.TopLayer, false); RubikManager.SolutionMove(leftSlice, true); RubikManager.SolutionMove(Cube3D.RubikPosition.TopLayer, true); } //Rotate over target position Cube3D.RubikPosition targetPos = Cube3D.RubikPosition.None; foreach (Cube3D.RubikPosition p in GetFlags(GetTargetPosition(c))) { if (p != Cube3D.RubikPosition.BottomLayer) { targetPos |= p; } } while (!RefreshCube(c).Position.HasFlag(targetPos)) { RubikManager.SolutionMove(Cube3D.RubikPosition.TopLayer, true); } } //Rotate to target position with the algorithm: Li Ui L U Face3D leftFac = RefreshCube(c).Faces.First(f => f.Position != Face3D.FacePosition.Top && f.Position != Face3D.FacePosition.Bottom && f.Color != Color.Black); Cube3D.RubikPosition leftSlic = FacePosToCubePos(leftFac.Position); RubikManager.SolutionMove(leftSlic, false); if (!RefreshCube(c).Position.HasFlag(Cube3D.RubikPosition.TopLayer)) { RubikManager.SolutionMove(leftSlic, true); leftFac = RefreshCube(c).Faces.First(f => f.Position != Face3D.FacePosition.Top && f.Position != Face3D.FacePosition.Bottom && f.Color != leftFac.Color && f.Color != Color.Black); leftSlic = FacePosToCubePos(leftFac.Position); } else { RubikManager.SolutionMove(leftSlic, true); } while (RefreshCube(c).Faces.First(f => f.Color == bottomColor).Position != Face3D.FacePosition.Bottom) { if (RefreshCube(c).Faces.First(f => f.Color == bottomColor).Position == Face3D.FacePosition.Top) { RubikManager.SolutionMove(leftSlic, false); RubikManager.SolutionMove(Cube3D.RubikPosition.TopLayer, true); RubikManager.SolutionMove(Cube3D.RubikPosition.TopLayer, true); RubikManager.SolutionMove(leftSlic, true); RubikManager.SolutionMove(Cube3D.RubikPosition.TopLayer, true); } else { Face3D frontFac = RefreshCube(c).Faces.First(f => f.Position != Face3D.FacePosition.Top && f.Position != Face3D.FacePosition.Bottom && f.Color != Color.Black && f.Position != CubePosToFacePos(leftSlic)); if (RefreshCube(c).Faces.First(f => f.Color == bottomColor).Position == frontFac.Position && !RefreshCube(c).Position.HasFlag(Cube3D.RubikPosition.BottomLayer)) { RubikManager.SolutionMove(Cube3D.RubikPosition.TopLayer, false); RubikManager.SolutionMove(leftSlic, false); RubikManager.SolutionMove(Cube3D.RubikPosition.TopLayer, true); RubikManager.SolutionMove(leftSlic, true); } else { RubikManager.SolutionMove(leftSlic, false); RubikManager.SolutionMove(Cube3D.RubikPosition.TopLayer, false); RubikManager.SolutionMove(leftSlic, true); RubikManager.SolutionMove(Cube3D.RubikPosition.TopLayer, true); } } } solvedBottomCorners = bottomCorners.Where(bC => RefreshCube(bC).Position == GetTargetPosition(bC) && RefreshCube(bC).Faces.First(f => f.Color == bottomColor).Position == Face3D.FacePosition.Bottom); } }