Esempio n. 1
0
        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));
        }
Esempio n. 2
0
        public Face3D Clone()
        {
            Face3D newFace = new Face3D(new List <Point3D>(Edges.Select(e => e.Clone())), Color, Position, MasterPosition, Selection);

            return(newFace);
        }
Esempio n. 3
0
 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
             };
         }
     }
 }
Esempio n. 4
0
 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);
             }
         }
     }
 }
Esempio n. 5
0
        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);
            }
        }
Esempio n. 6
0
        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);
            }
        }
Esempio n. 7
0
        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);
            }
        }