private Face3D.FacePosition CubePosToFacePos(Cube3D.RubikPosition position)
        {
            switch (position)
            {
            case Cube3D.RubikPosition.TopLayer:
                return(Face3D.FacePosition.Top);

            case Cube3D.RubikPosition.BottomLayer:
                return(Face3D.FacePosition.Bottom);

            case Cube3D.RubikPosition.FrontSlice:
                return(Face3D.FacePosition.Front);

            case Cube3D.RubikPosition.BackSlice:
                return(Face3D.FacePosition.Back);

            case Cube3D.RubikPosition.LeftSlice:
                return(Face3D.FacePosition.Left);

            case Cube3D.RubikPosition.RightSlice:
                return(Face3D.FacePosition.Right);

            default:
                return(Face3D.FacePosition.None);
            }
        }
示例#2
0
 public static FacePosition faceAssocToLayer(Cube3D.RubikPosition Position)
 {
     if (Position == Cube3D.RubikPosition.TopLayer)
     {
         return(FacePosition.Top);
     }
     if (Position == Cube3D.RubikPosition.BottomLayer)
     {
         return(FacePosition.Bottom);
     }
     if (Position == Cube3D.RubikPosition.LeftSlice)
     {
         return(FacePosition.Left);
     }
     if (Position == Cube3D.RubikPosition.RightSlice)
     {
         return(FacePosition.Right);
     }
     if (Position == Cube3D.RubikPosition.FrontSlice)
     {
         return(FacePosition.Front);
     }
     if (Position == Cube3D.RubikPosition.BackSlice)
     {
         return(FacePosition.Back);
     }
     return(FacePosition.None);
 }
示例#3
0
        public Cube3D.RubikPosition genSideFlags(int i, int j, int k)
        {
            Cube3D.RubikPosition rp = Cube3D.RubikPosition.None;
            switch (i)
            {
            case -1: rp |= Cube3D.RubikPosition.LeftSlice; break;

            case 0: rp |= Cube3D.RubikPosition.MiddleSlice_Sides; break;

            case 1: rp |= Cube3D.RubikPosition.RightSlice; break;
            }
            switch (j)
            {
            case -1: rp |= Cube3D.RubikPosition.TopLayer; break;

            case 0: rp |= Cube3D.RubikPosition.MiddleLayer; break;

            case 1: rp |= Cube3D.RubikPosition.BottomLayer; break;
            }
            switch (k)
            {
            case -1: rp |= Cube3D.RubikPosition.FrontSlice; break;

            case 0: rp |= Cube3D.RubikPosition.MiddleSlice; break;

            case 1: rp |= Cube3D.RubikPosition.BackSlice; break;
            }
            return(rp);
        }
        private Cube3D.RubikPosition GetOppositeFace(Cube3D.RubikPosition layer)
        {
            switch (layer)
            {
            case Cube3D.RubikPosition.TopLayer:
                return(Cube3D.RubikPosition.BottomLayer);

            case Cube3D.RubikPosition.BottomLayer:
                return(Cube3D.RubikPosition.TopLayer);

            case Cube3D.RubikPosition.FrontSlice:
                return(Cube3D.RubikPosition.BackSlice);

            case Cube3D.RubikPosition.BackSlice:
                return(Cube3D.RubikPosition.FrontSlice);

            case Cube3D.RubikPosition.LeftSlice:
                return(Cube3D.RubikPosition.RightSlice);

            case Cube3D.RubikPosition.RightSlice:
                return(Cube3D.RubikPosition.LeftSlice);

            default:
                return(Cube3D.RubikPosition.None);
            }
        }
        public void resetFlagsSync(Cube3D.RubikPosition layer, int target)
        {
            RubikCube.LayerRotation[layer] = target;
            List <Cube3D> affected = RubikCube.cubes.Where(c => c.Position.HasFlag(layer)).ToList();

            if (layer == Cube3D.RubikPosition.LeftSlice || layer == Cube3D.RubikPosition.MiddleSlice_Sides || layer == Cube3D.RubikPosition.RightSlice)
            {
                affected.ForEach(c => c.Faces.ToList().ForEach(f => f.Rotate(Point3D.RotationType.X, target)));
            }
            if (layer == Cube3D.RubikPosition.TopLayer || layer == Cube3D.RubikPosition.MiddleLayer || layer == Cube3D.RubikPosition.BottomLayer)
            {
                affected.ForEach(c => c.Faces.ToList().ForEach(f => f.Rotate(Point3D.RotationType.Y, target)));
            }
            if (layer == Cube3D.RubikPosition.BackSlice || layer == Cube3D.RubikPosition.MiddleSlice || layer == Cube3D.RubikPosition.FrontSlice)
            {
                affected.ForEach(c => c.Faces.ToList().ForEach(f => f.Rotate(Point3D.RotationType.Z, target)));
            }
            double ed = ((double)2 / (double)3);

            for (int i = -1; i <= 1; i++)
            {
                for (int j = -1; j <= 1; j++)
                {
                    for (int k = -1; k <= 1; k++)
                    {
                        //Reset Flags but keep Colors
                        Cube3D.RubikPosition flags = RubikCube.genSideFlags(i, j, k);;
                        Cube3D cube = RubikCube.cubes.First(c => (Math.Round(c.Faces.Sum(f => f.Edges.Sum(e => e.X)) / 24, 4) == Math.Round(i * ed, 4)) &&
                                                            (Math.Round(c.Faces.Sum(f => f.Edges.Sum(e => e.Y)) / 24, 4) == Math.Round(j * ed, 4)) &&
                                                            (Math.Round(c.Faces.Sum(f => f.Edges.Sum(e => e.Z)) / 24, 4) == Math.Round(k * ed, 4)));
                        cube.Position = flags;
                        cube.Faces.ToList().ForEach(f => f.MasterPosition = flags);
                        cube.Faces.First(f => (Math.Round(f.Edges.Sum(e => e.X) / 4, 4) == Math.Round(i * ed, 4)) &&
                                         (Math.Round(f.Edges.Sum(e => e.Y) / 4, 4) == Math.Round((j * ed) - (ed / 2), 4)) &&
                                         (Math.Round(f.Edges.Sum(e => e.Z) / 4, 4) == Math.Round(k * ed, 4))).Position = Face3D.FacePosition.Top;
                        cube.Faces.First(f => (Math.Round(f.Edges.Sum(e => e.X) / 4, 4) == Math.Round(i * ed, 4)) &&
                                         (Math.Round(f.Edges.Sum(e => e.Y) / 4, 4) == Math.Round((j * ed) + (ed / 2), 4)) &&
                                         (Math.Round(f.Edges.Sum(e => e.Z) / 4, 4) == Math.Round(k * ed, 4))).Position = Face3D.FacePosition.Bottom;
                        cube.Faces.First(f => (Math.Round(f.Edges.Sum(e => e.X) / 4, 4) == Math.Round((i * ed) - (ed / 2), 4)) &&
                                         (Math.Round(f.Edges.Sum(e => e.Y) / 4, 4) == Math.Round(j * ed, 4)) &&
                                         (Math.Round(f.Edges.Sum(e => e.Z) / 4, 4) == Math.Round(k * ed, 4))).Position = Face3D.FacePosition.Left;
                        cube.Faces.First(f => (Math.Round(f.Edges.Sum(e => e.X) / 4, 4) == Math.Round((i * ed) + (ed / 2), 4)) &&
                                         (Math.Round(f.Edges.Sum(e => e.Y) / 4, 4) == Math.Round(j * ed, 4)) &&
                                         (Math.Round(f.Edges.Sum(e => e.Z) / 4, 4) == Math.Round(k * ed, 4))).Position = Face3D.FacePosition.Right;
                        cube.Faces.First(f => (Math.Round(f.Edges.Sum(e => e.X) / 4, 4) == Math.Round(i * ed, 4)) &&
                                         (Math.Round(f.Edges.Sum(e => e.Y) / 4, 4) == Math.Round(j * ed, 4)) &&
                                         (Math.Round(f.Edges.Sum(e => e.Z) / 4, 4) == Math.Round((k * ed) - (ed / 2), 4))).Position = Face3D.FacePosition.Front;
                        cube.Faces.First(f => (Math.Round(f.Edges.Sum(e => e.X) / 4, 4) == Math.Round(i * ed, 4)) &&
                                         (Math.Round(f.Edges.Sum(e => e.Y) / 4, 4) == Math.Round(j * ed, 4)) &&
                                         (Math.Round(f.Edges.Sum(e => e.Z) / 4, 4) == Math.Round((k * ed) + (ed / 2), 4))).Position = Face3D.FacePosition.Back;
                    }
                }
            }
            foreach (Cube3D.RubikPosition rp in (Cube3D.RubikPosition[])Enum.GetValues(typeof(Cube3D.RubikPosition)))
            {
                RubikCube.LayerRotation[rp] = 0;
            }
            Rotating = false;
        }
示例#6
0
 public Face3D(IEnumerable <Point3D> edges, Color color, FacePosition position, Cube3D.RubikPosition masterPosition, SelectionMode selection)
 {
     Edges          = edges;
     Color          = color;
     Position       = position;
     MasterPosition = masterPosition;
     Selection      = selection;
 }
 public void SolutionMove(Cube3D.RubikPosition layer, bool direction)
 {
     Rotate90Sync(layer, direction);
     if (layer == Cube3D.RubikPosition.TopLayer || layer == Cube3D.RubikPosition.LeftSlice || layer == Cube3D.RubikPosition.FrontSlice)
     {
         direction = !direction;
     }
     Moves.Add(new LayerMove(layer, direction));
 }
示例#8
0
 public void Rotate90Sync(Cube3D.RubikPosition layer, bool direction)
 {
     if (!Rotating)
     {
         Rotate90(layer, direction, 1);
         RubikCube.LayerRotation[rotationLayer] += rotationStep;
         resetFlags(false);
     }
 }
示例#9
0
        private void button2_Click(object sender, EventArgs e)
        {
            groupBox1.Enabled = false;
            //rotationTicks = 100;
            Cube3D.RubikPosition layer = (Cube3D.RubikPosition)Enum.Parse(typeof(Cube3D.RubikPosition), comboBox1.Text);
            bool direction             = (button5.Text == "CW");

            rubikRenderer.RubikManager.Rotate90(layer, direction, rotationTime);
            toolStripStatusLabel1.Text = "Rotating " + layer.ToString() + " " + ((button5.Text == "CW") ? "Clockwise" : "Counter-Clockwise");
        }
示例#10
0
 public static IEnumerable <Face3D> genFaces(Cube3D.RubikPosition masterPosition)
 {
     return(new Face3D[] {
         new Face3D(new Point3D[] { new Point3D(-1, 1, -1), new Point3D(1, 1, -1), new Point3D(1, -1, -1), new Point3D(-1, -1, -1) }, Color.Black, Face3D.FacePosition.Front, masterPosition, Face3D.SelectionMode.None),
         new Face3D(new Point3D[] { new Point3D(-1, 1, 1), new Point3D(1, 1, 1), new Point3D(1, -1, 1), new Point3D(-1, -1, 1) }, Color.Black, Face3D.FacePosition.Back, masterPosition, Face3D.SelectionMode.None),
         new Face3D(new Point3D[] { new Point3D(-1, -1, -1), new Point3D(1, -1, -1), new Point3D(1, -1, 1), new Point3D(-1, -1, 1) }, Color.Black, Face3D.FacePosition.Top, masterPosition, Face3D.SelectionMode.None),
         new Face3D(new Point3D[] { new Point3D(-1, 1, -1), new Point3D(1, 1, -1), new Point3D(1, 1, 1), new Point3D(-1, 1, 1) }, Color.Black, Face3D.FacePosition.Bottom, masterPosition, Face3D.SelectionMode.None),
         new Face3D(new Point3D[] { new Point3D(1, 1, 1), new Point3D(1, 1, -1), new Point3D(1, -1, -1), new Point3D(1, -1, 1) }, Color.Black, Face3D.FacePosition.Right, masterPosition, Face3D.SelectionMode.None),
         new Face3D(new Point3D[] { new Point3D(-1, 1, 1), new Point3D(-1, 1, -1), new Point3D(-1, -1, -1), new Point3D(-1, -1, 1) }, Color.Black, Face3D.FacePosition.Left, masterPosition, Face3D.SelectionMode.None)
     });
 }
示例#11
0
        private Tuple <Cube3D.RubikPosition, bool> GetRubikPosition(int layer, int direction, int clockwise)
        {
            Cube3D.RubikPosition pos = Cube3D.RubikPosition.None;
            bool orientation         = false;

            if (direction == 0 && layer == 0)
            {
                pos         = Cube3D.RubikPosition.LeftSlice;
                orientation = clockwise > 0;
            }
            else if (direction == 0 && layer == 1)
            {
                pos         = Cube3D.RubikPosition.MiddleSlice_Sides;
                orientation = clockwise < 0;
            }
            else if (direction == 0 && layer == 2)
            {
                pos         = Cube3D.RubikPosition.RightSlice;
                orientation = clockwise < 0;
            }
            else if (direction == 1 && layer == 0)
            {
                pos         = Cube3D.RubikPosition.TopLayer;
                orientation = clockwise > 0;
            }
            else if (direction == 1 && layer == 1)
            {
                pos         = Cube3D.RubikPosition.MiddleLayer;
                orientation = clockwise < 0;
            }
            else if (direction == 1 && layer == 2)
            {
                pos         = Cube3D.RubikPosition.BottomLayer;
                orientation = clockwise < 0;
            }
            else if (direction == 2 && layer == 0)
            {
                pos         = Cube3D.RubikPosition.FrontSlice;
                orientation = clockwise > 0;
            }
            else if (direction == 2 && layer == 1)
            {
                pos         = Cube3D.RubikPosition.MiddleSlice;
                orientation = clockwise < 0;
            }
            else if (direction == 2 && layer == 2)
            {
                pos         = Cube3D.RubikPosition.BackSlice;
                orientation = clockwise < 0;
            }
            return(new Tuple <Cube3D.RubikPosition, bool>(pos, orientation));
        }
 public void Rotate90Sync(Cube3D.RubikPosition layer, bool direction)
 {
     if (!Rotating)
     {
         Rotating = true;
         if (layer == Cube3D.RubikPosition.TopLayer || layer == Cube3D.RubikPosition.LeftSlice || layer == Cube3D.RubikPosition.FrontSlice)
         {
             direction = !direction;
         }
         RubikCube.LayerRotation[layer] += (direction) ? -90 : 90;
         resetFlagsSync(layer, (direction) ? -90 : 90);
     }
 }
示例#13
0
        private void button2_Click(object sender, EventArgs e)
        {
            groupBox1.Enabled = false;
            rotationTicks     = 25;
            Cube3D.RubikPosition layer = (Cube3D.RubikPosition)Enum.Parse(typeof(Cube3D.RubikPosition), comboBox1.Text);
            bool direction             = (button5.Text == "CW");

            if (layer == Cube3D.RubikPosition.TopLayer || layer == Cube3D.RubikPosition.LeftSlice || layer == Cube3D.RubikPosition.FrontSlice)
            {
                direction = !direction;
            }
            rubikManager.Rotate90(layer, direction, rotationTicks);
            toolStripStatusLabel1.Text = "Rotating " + layer.ToString() + " " + ((button5.Text == "CW") ? "Clockwise" : "Counter-Clockwise");
        }
        public static LayerMove Parse(string notation)
        {
            string layer = notation[0].ToString();

            Cube3D.RubikPosition rotationLayer = Cube3D.RubikPosition.None;
            switch (layer)
            {
            case "R":
                rotationLayer = Cube3D.RubikPosition.RightSlice;
                break;

            case "L":
                rotationLayer = Cube3D.RubikPosition.LeftSlice;
                break;

            case "U":
                rotationLayer = Cube3D.RubikPosition.TopLayer;
                break;

            case "D":
                rotationLayer = Cube3D.RubikPosition.BottomLayer;
                break;

            case "F":
                rotationLayer = Cube3D.RubikPosition.FrontSlice;
                break;

            case "B":
                rotationLayer = Cube3D.RubikPosition.BackSlice;
                break;

            case "M":
                rotationLayer = Cube3D.RubikPosition.MiddleSlice_Sides;
                break;

            case "E":
                rotationLayer = Cube3D.RubikPosition.MiddleLayer;
                break;

            case "S":
                rotationLayer = Cube3D.RubikPosition.MiddleSlice;
                break;
            }
            bool direction = notation.Length == 1;

            return(new LayerMove(rotationLayer, direction));
        }
示例#15
0
 public void setFaceSelection(Cube3D.RubikPosition affected, Face3D.FacePosition face, Face3D.SelectionMode selection)
 {
     RubikCube.cubes.Where(c => c.Position.HasFlag(affected)).ToList().ForEach(c => c.Faces.Where(f => f.Position == face).ToList().ForEach(f =>
     {
         if (f.Selection.HasFlag(Face3D.SelectionMode.Possible))
         {
             f.Selection = selection | Face3D.SelectionMode.Possible;
         }
         else if (f.Selection.HasFlag(Face3D.SelectionMode.NotPossible))
         {
             f.Selection = selection | Face3D.SelectionMode.NotPossible;
         }
         else
         {
             f.Selection = selection;
         }
     }));
 }
示例#16
0
 public void Rotate90(Cube3D.RubikPosition layer, bool direction, int steps)
 {
     if (!Rotating)
     {
         Rotating      = true;
         rotationLayer = layer;
         rotationStep  = (double)90 / (double)steps;
         if (direction)
         {
             rotationStep *= (-1);
         }
         rotationTarget = 90;
         if (direction)
         {
             rotationTarget = -90;
         }
     }
 }
        private Cube3D.RubikPosition GetOppositeLayer(Cube3D.RubikPosition position)
        {
            switch (position)
            {
            case Cube3D.RubikPosition.FrontSlice:
                return(Cube3D.RubikPosition.BackSlice);

            case Cube3D.RubikPosition.BackSlice:
                return(Cube3D.RubikPosition.FrontSlice);

            case Cube3D.RubikPosition.LeftSlice:
                return(Cube3D.RubikPosition.RightSlice);

            case Cube3D.RubikPosition.RightSlice:
                return(Cube3D.RubikPosition.LeftSlice);

            default:
                return(Cube3D.RubikPosition.None);
            }
        }
示例#18
0
        private void listBox1_KeyDown(object sender, KeyEventArgs e)
        {
            if (e.KeyCode == Keys.Space)
            {
                //rotationTicks = 25;
                if (listBox1.SelectedIndex == -1 & listBox1.Items.Count > 0)
                {
                    listBox1.SelectedIndex = 0;
                }
                if (listBox1.Items.Count > 0)
                {
                    string layerString         = listBox1.SelectedItem.ToString().Split(new Char[] { Convert.ToChar(" ") })[0];
                    Cube3D.RubikPosition layer = (Cube3D.RubikPosition)Enum.Parse(typeof(Cube3D.RubikPosition), layerString);

                    string directionString = listBox1.SelectedItem.ToString().Split(new Char[] { Convert.ToChar(" ") })[1];
                    bool   direction       = (directionString == "Clockwise") ? true : false;

                    rubikRenderer.RubikManager.Rotate90(layer, direction, rotationTime);
                }
            }
        }
 public void Rotate90(Cube3D.RubikPosition layer, bool direction, int rotationTime)
 {
     if (!Rotating)
     {
         Rotating          = true;
         rotationLayer     = layer;
         this.rotationTime = rotationTime;
         if (layer == Cube3D.RubikPosition.TopLayer || layer == Cube3D.RubikPosition.LeftSlice || layer == Cube3D.RubikPosition.FrontSlice)
         {
             direction = !direction;
         }
         this.rotationDirection = direction;
         if (direction)
         {
             rotationStep *= (-1);
         }
         rotationTarget = 90;
         if (direction)
         {
             rotationTarget = -90;
         }
     }
 }
        public bool CanSolve()
        {
            RubikManager oldManager = Manager.Clone();
            //check colors
            bool correctColors = standardCube.RubikCube.cubes.Count(sc => Manager.RubikCube.cubes
                                                                    .Where(c => ScrambledEquals(c.Colors, sc.Colors)).Count() == 1) == Manager.RubikCube.cubes.Count();

            //return false, if there are invalid cube colors
            if (!correctColors)
            {
                return(false);
            }

            Solve(false);

            //check if all the cube faces are solved
            Cube3D.RubikPosition layers = Cube3D.RubikPosition.TopLayer | Cube3D.RubikPosition.BottomLayer | Cube3D.RubikPosition.RightSlice
                                          | Cube3D.RubikPosition.LeftSlice | Cube3D.RubikPosition.FrontSlice | Cube3D.RubikPosition.BackSlice;
            foreach (Cube3D.RubikPosition l in GetFlags(layers))
            {
                Face3D.FacePosition facePos = CubePosToFacePos(l);
                if (facePos != Face3D.FacePosition.None)
                {
                    Cube3D.RubikPosition centerPos = Manager.RubikCube.cubes.First(c => Cube3D.isCenter(c.Position) && c.Position.HasFlag(l)).Position;
                    Color faceColor = Manager.getFaceColor(centerPos, facePos);

                    bool faceNotSolved = Manager.RubikCube.cubes.Count(c => c.Position.HasFlag(l) && c.Faces.First(f => f.Position == facePos).Color == faceColor) != 9;
                    if (faceNotSolved)
                    {
                        return(false);
                    }
                }
            }

            Manager = oldManager;
            return(true);
        }
        private void CompleteMiddleLayer()
        {
            //Step 1: Get the color of the bottom and top layer
            Color bottomColor = Manager.getFaceColor(Cube3D.RubikPosition.BottomLayer | Cube3D.RubikPosition.MiddleSlice_Sides | Cube3D.RubikPosition.MiddleSlice, Face3D.FacePosition.Bottom);
            Color topColor    = Manager.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 = Manager.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>();

            Manager.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);

                    Manager.SolutionMove(slice, true);
                    if (RefreshCube(c).Position.HasFlag(Cube3D.RubikPosition.TopLayer))
                    {
                        Manager.SolutionMove(slice, false);
                        //Algorithm to the right: U R Ui Ri Ui Fi U F
                        Manager.SolutionMove(Cube3D.RubikPosition.TopLayer, true);
                        Manager.SolutionMove(slice, true);
                        Manager.SolutionMove(Cube3D.RubikPosition.TopLayer, false);
                        Manager.SolutionMove(slice, false);
                        Manager.SolutionMove(Cube3D.RubikPosition.TopLayer, false);
                        Manager.SolutionMove(frontSlice, false);
                        Manager.SolutionMove(Cube3D.RubikPosition.TopLayer, true);
                        Manager.SolutionMove(frontSlice, true);
                    }
                    else
                    {
                        Manager.SolutionMove(slice, false);
                        //Algorithm to the left: Ui Li U L U F Ui Fi
                        Manager.SolutionMove(Cube3D.RubikPosition.TopLayer, false);
                        Manager.SolutionMove(slice, false);
                        Manager.SolutionMove(Cube3D.RubikPosition.TopLayer, true);
                        Manager.SolutionMove(slice, true);
                        Manager.SolutionMove(Cube3D.RubikPosition.TopLayer, true);
                        Manager.SolutionMove(frontSlice, true);
                        Manager.SolutionMove(Cube3D.RubikPosition.TopLayer, false);
                        Manager.SolutionMove(frontSlice, false);
                    }
                }

                //Rotate to start position for the algorithm
                IEnumerable <Cube3D> middles = Manager.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)
                {
                    Manager.SolutionMove(Cube3D.RubikPosition.TopLayer, true);
                    middles = Manager.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;
                    }
                }

                Manager.SolutionMove(Cube3D.RubikPosition.TopLayer, true);
                if (!RefreshCube(c).Position.HasFlag(slic))
                {
                    Manager.SolutionMove(Cube3D.RubikPosition.TopLayer, false);
                    //Algorithm to the right: U R Ui Ri Ui Fi U F
                    Manager.SolutionMove(Cube3D.RubikPosition.TopLayer, true);
                    Manager.SolutionMove(slic, true);
                    Manager.SolutionMove(Cube3D.RubikPosition.TopLayer, false);
                    Manager.SolutionMove(slic, false);
                    Manager.SolutionMove(Cube3D.RubikPosition.TopLayer, false);
                    Manager.SolutionMove(frontSlic, false);
                    Manager.SolutionMove(Cube3D.RubikPosition.TopLayer, true);
                    Manager.SolutionMove(frontSlic, true);
                }
                else
                {
                    Manager.SolutionMove(Cube3D.RubikPosition.TopLayer, false);
                    //Algorithm to the left: Ui Li U L U F Ui Fi
                    Manager.SolutionMove(Cube3D.RubikPosition.TopLayer, false);
                    Manager.SolutionMove(slic, false);
                    Manager.SolutionMove(Cube3D.RubikPosition.TopLayer, true);
                    Manager.SolutionMove(slic, true);
                    Manager.SolutionMove(Cube3D.RubikPosition.TopLayer, true);
                    Manager.SolutionMove(frontSlic, true);
                    Manager.SolutionMove(Cube3D.RubikPosition.TopLayer, false);
                    Manager.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);
            }
        }
 public LayerMove(Cube3D.RubikPosition layer, Boolean direction)
 {
     Layer     = layer;
     Direction = direction;
 }
        private void SolveCrossTopLayer()
        {
            //Step 1: Get the color of the top layer to start with cross on the last layer
            Color topColor = Manager.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> topEdges = Manager.RubikCube.cubes.Where(c => Cube3D.isEdge(c.Position)).Where(c => c.Position.HasFlag(Cube3D.RubikPosition.TopLayer));

            //Check if the cube is insoluble
            if (topEdges.Where(tE => tE.Faces.First(f => f.Position == Face3D.FacePosition.Top).Color == topColor).Count() % 2 != 0)
            {
                return;
            }

            IEnumerable <Cube3D> correctEdges             = topEdges.Where(c => c.Faces.First(f => f.Position == Face3D.FacePosition.Top).Color == topColor);
            Algorithm            solveTopCrossAlgorithmI  = new Algorithm("F R U Ri Ui Fi");
            Algorithm            solveTopCrossAlgorithmII = new Algorithm("F Si R U Ri Ui Fi S");

            //Step 3: Solve the cross on the top layer
            if (CountEdgesWithCorrectOrientation(Manager) == 0)
            {
                solveTopCrossAlgorithmI.Moves.ForEach(m => Manager.SolutionMove(m.Layer, m.Direction));
                topEdges     = topEdges.Select(c => RefreshCube(c));
                correctEdges = topEdges.Where(c => c.Faces.First(f => f.Position == Face3D.FacePosition.Top).Color == topColor);
            }

            if (CountEdgesWithCorrectOrientation(Manager) == 2)
            {
                Cube3D firstCorrect = correctEdges.First(); Cube3D secondCorrect = correctEdges.First(f => f != firstCorrect);
                bool   opposite = false;
                foreach (Cube3D.RubikPosition flag in GetFlags(firstCorrect.Position))
                {
                    Cube3D.RubikPosition pos = GetOppositeLayer(flag);
                    if (secondCorrect.Position.HasFlag(pos) && pos != Cube3D.RubikPosition.None)
                    {
                        opposite = true;
                        break;
                    }
                }

                if (opposite)
                {
                    while (correctEdges.Select(c => RefreshCube(c)).Count(c => c.Position.HasFlag(Cube3D.RubikPosition.RightSlice)) != 1)
                    {
                        Manager.SolutionMove(Cube3D.RubikPosition.TopLayer, true);
                    }
                    solveTopCrossAlgorithmI.Moves.ForEach(m => Manager.SolutionMove(m.Layer, m.Direction));
                }
                else
                {
                    while (correctEdges.Select(c => RefreshCube(c)).Count(c => c.Position.HasFlag(Cube3D.RubikPosition.RightSlice) || c.Position.HasFlag(Cube3D.RubikPosition.FrontSlice)) != 2)
                    {
                        Manager.SolutionMove(Cube3D.RubikPosition.TopLayer, true);
                    }
                    solveTopCrossAlgorithmII.Moves.ForEach(m => Manager.SolutionMove(m.Layer, m.Direction));
                }
            }

            //Step 4: Move the edges of the cross to their target positions
            IEnumerable <Cube3D> CorrectEdges = topEdges.Where(c => c.Position == GetTargetPosition(c));

            while (CorrectEdges.Count() < 2)
            {
                Manager.SolutionMove(Cube3D.RubikPosition.TopLayer, true);
                CorrectEdges = CorrectEdges.Select(cE => RefreshCube(cE));
            }

            while (topEdges.Where(c => c.Position == GetTargetPosition(c)).Count() < 4)
            {
                CorrectEdges = topEdges.Where(c => c.Position == GetTargetPosition(c));
                while (CorrectEdges.Count() < 2)
                {
                    Manager.SolutionMove(Cube3D.RubikPosition.TopLayer, true);
                    CorrectEdges = CorrectEdges.Select(cE => RefreshCube(cE));
                }

                Cube3D.RubikPosition rightSlice = FacePosToCubePos(CorrectEdges.First().Faces
                                                                   .First(f => f.Color != topColor && f.Color != Color.Black).Position);
                Manager.SolutionMove(Cube3D.RubikPosition.TopLayer, false);
                CorrectEdges = CorrectEdges.Select(cE => RefreshCube(cE));

                if (CorrectEdges.Count(c => c.Position.HasFlag(rightSlice)) == 0)
                {
                    Manager.SolutionMove(Cube3D.RubikPosition.TopLayer, true);
                }
                else
                {
                    Manager.SolutionMove(Cube3D.RubikPosition.TopLayer, true);
                    CorrectEdges = CorrectEdges.Select(cE => RefreshCube(cE));
                    rightSlice   = FacePosToCubePos(CorrectEdges.First(cE => !cE.Position.HasFlag(rightSlice)).Faces
                                                    .First(f => f.Color != topColor && f.Color != Color.Black).Position);
                }
                //Algorithm: R U Ri U R U U Ri
                Manager.SolutionMove(rightSlice, true);
                Manager.SolutionMove(Cube3D.RubikPosition.TopLayer, true);
                Manager.SolutionMove(rightSlice, false);
                Manager.SolutionMove(Cube3D.RubikPosition.TopLayer, true);
                Manager.SolutionMove(rightSlice, true);
                Manager.SolutionMove(Cube3D.RubikPosition.TopLayer, true);
                Manager.SolutionMove(Cube3D.RubikPosition.TopLayer, true);
                Manager.SolutionMove(rightSlice, false);

                topEdges = topEdges.Select(tE => RefreshCube(tE));
                while (CorrectEdges.Count() < 2)
                {
                    Manager.SolutionMove(Cube3D.RubikPosition.TopLayer, true);
                    CorrectEdges = CorrectEdges.Select(cE => RefreshCube(cE));
                }
            }
        }
示例#24
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
             };
         }
     }
 }
        private void CompleteLastLayer()
        {
            //Step 1: Get the color of the top layer to start with cross on the last layer
            Color topColor = Manager.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 = Manager.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);
                    Manager.SolutionMove(rightSlice, true);
                    if (RefreshCube(firstCube).Position.HasFlag(Cube3D.RubikPosition.TopLayer))
                    {
                        Manager.SolutionMove(rightSlice, false);
                    }
                    else
                    {
                        Manager.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);
                Manager.SolutionMove(Cube3D.RubikPosition.TopLayer, true);
                Manager.SolutionMove(rightSlice, true);
                Manager.SolutionMove(Cube3D.RubikPosition.TopLayer, false);
                Manager.SolutionMove(leftSlice, false);
                Manager.SolutionMove(Cube3D.RubikPosition.TopLayer, true);
                Manager.SolutionMove(rightSlice, false);
                Manager.SolutionMove(Cube3D.RubikPosition.TopLayer, false);
                Manager.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);
            Manager.SolutionMove(rightSlic, true);
            if (RefreshCube(topCorners.First()).Position.HasFlag(Cube3D.RubikPosition.TopLayer))
            {
                Manager.SolutionMove(rightSlic, false);
            }
            else
            {
                Manager.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))
                {
                    Manager.SolutionMove(Cube3D.RubikPosition.TopLayer, true);
                }
                Manager.SolutionMove(rightSlic, true);
                if (RefreshCube(c).Position.HasFlag(Cube3D.RubikPosition.TopLayer))
                {
                    Manager.SolutionMove(rightSlic, false);
                }
                else
                {
                    Manager.SolutionMove(rightSlic, false);
                    Manager.SolutionMove(Cube3D.RubikPosition.TopLayer, true);
                }

                //Algorithm: Ri Di R D
                while (RefreshCube(c).Faces.First(f => f.Position == Face3D.FacePosition.Top).Color != topColor)
                {
                    Manager.SolutionMove(rightSlic, false);
                    Manager.SolutionMove(Cube3D.RubikPosition.BottomLayer, false);
                    Manager.SolutionMove(rightSlic, true);
                    Manager.SolutionMove(Cube3D.RubikPosition.BottomLayer, true);
                }
            }

            topCorners = topCorners.Select(tC => RefreshCube(tC));
            while (topCorners.Count(tC => tC.Position == GetTargetPosition(tC)) != 4)
            {
                Manager.SolutionMove(Cube3D.RubikPosition.TopLayer, true);
            }
        }
 private Cube3D.RubikPosition RemoveFlag(Cube3D.RubikPosition oldPosition, Cube3D.RubikPosition item)
 {
     return(oldPosition &= ~item);
 }
示例#27
0
 public void setFaceColor(Cube3D.RubikPosition affected, Face3D.FacePosition face, Color color)
 {
     RubikCube.cubes.Where(c => c.Position.HasFlag(affected)).ToList().ForEach(c => c.Faces.Where(f => f.Position == face).ToList().ForEach(f => f.Color = color));
 }
        private void CompleteFirstLayer()
        {
            //Step 1: Get the color of the bottom layer
            Color bottomColor = Manager.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       = Manager.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);
                        Manager.SolutionMove(leftSlice, false);
                        if (RefreshCube(c).Position.HasFlag(Cube3D.RubikPosition.BottomLayer))
                        {
                            Manager.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);
                            Manager.SolutionMove(leftSlice, false);
                        }
                        Manager.SolutionMove(Cube3D.RubikPosition.TopLayer, false);
                        Manager.SolutionMove(leftSlice, true);
                        Manager.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))
                    {
                        Manager.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);

                Manager.SolutionMove(leftSlic, false);
                if (!RefreshCube(c).Position.HasFlag(Cube3D.RubikPosition.TopLayer))
                {
                    Manager.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
                {
                    Manager.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)
                    {
                        Manager.SolutionMove(leftSlic, false);
                        Manager.SolutionMove(Cube3D.RubikPosition.TopLayer, true);
                        Manager.SolutionMove(Cube3D.RubikPosition.TopLayer, true);
                        Manager.SolutionMove(leftSlic, true);
                        Manager.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))
                        {
                            Manager.SolutionMove(Cube3D.RubikPosition.TopLayer, false);
                            Manager.SolutionMove(leftSlic, false);
                            Manager.SolutionMove(Cube3D.RubikPosition.TopLayer, true);
                            Manager.SolutionMove(leftSlic, true);
                        }
                        else
                        {
                            Manager.SolutionMove(leftSlic, false);
                            Manager.SolutionMove(Cube3D.RubikPosition.TopLayer, false);
                            Manager.SolutionMove(leftSlic, true);
                            Manager.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);
            }
        }
 public Color getFaceColor(Cube3D.RubikPosition position, Face3D.FacePosition face)
 {
     return(RubikCube.cubes.First(c => c.Position.HasFlag(position)).Faces.First(f => f.Position == face).Color);
 }
        //Solve the first cross on the bottom layer
        private void SolveFirstCross()
        {
            //Step 1: Get color of the bottom layer
            Color bottomColor = Manager.getFaceColor(Cube3D.RubikPosition.BottomLayer | Cube3D.RubikPosition.MiddleSlice_Sides | Cube3D.RubikPosition.MiddleSlice, Face3D.FacePosition.Bottom);

            //Step 2: Get the edges with target position on the bottom layer
            IEnumerable <Cube3D> bottomEdges = Manager.RubikCube.cubes.Where(c => Cube3D.isEdge(c.Position) && GetTargetPosition(c).HasFlag(Cube3D.RubikPosition.BottomLayer));

            //Step 3: Rotate a correct orientated edge of the bottom layer to  target position
            IEnumerable <Cube3D> solvedBottomEdges = bottomEdges.Where(bE => bE.Position == GetTargetPosition(bE) && bE.Faces.First(f => f.Color == bottomColor).Position == Face3D.FacePosition.Bottom);

            if (bottomEdges.Count(bE => bE.Position.HasFlag(Cube3D.RubikPosition.BottomLayer) && bE.Faces.First(f => f.Color == bottomColor).Position == Face3D.FacePosition.Bottom) > 0)
            {
                while (solvedBottomEdges.Count() < 1)
                {
                    Manager.SolutionMove(Cube3D.RubikPosition.BottomLayer, true);
                    solvedBottomEdges = bottomEdges.Where(bE => RefreshCube(bE).Position == GetTargetPosition(RefreshCube(bE)) && RefreshCube(bE).Faces.First(f => f.Color == bottomColor).Position == Face3D.FacePosition.Bottom);
                }
            }

            //Step 4: Solve incorrect edges of the bottom layer
            while (solvedBottomEdges.Count() < 4)
            {
                IEnumerable <Cube3D> unsolvedBottomEdges = bottomEdges.Except(solvedBottomEdges);
                Cube3D e = (unsolvedBottomEdges.FirstOrDefault(c => c.Position.HasFlag(Cube3D.RubikPosition.TopLayer)) != null)
                                                ? unsolvedBottomEdges.FirstOrDefault(c => c.Position.HasFlag(Cube3D.RubikPosition.TopLayer)) : unsolvedBottomEdges.First();
                Color secondColor = e.Colors.First(co => co != bottomColor && co != Color.Black);

                if (e.Position != GetTargetPosition(e))
                {
                    //Rotate to top layer
                    Cube3D.RubikPosition layer = FacePosToCubePos(e.Faces.First(f => (f.Color == bottomColor || f.Color == secondColor) &&
                                                                                f.Position != Face3D.FacePosition.Top && f.Position != Face3D.FacePosition.Bottom).Position);

                    Cube3D.RubikPosition targetLayer = FacePosToCubePos(standardCube.RubikCube.cubes.First(cu => ScrambledEquals(cu.Colors, e.Colors))
                                                                        .Faces.First(f => f.Color == secondColor).Position);

                    if (e.Position.HasFlag(Cube3D.RubikPosition.MiddleLayer))
                    {
                        if (layer == targetLayer)
                        {
                            while (!RefreshCube(e).Position.HasFlag(Cube3D.RubikPosition.BottomLayer))
                            {
                                Manager.SolutionMove(layer, true);
                            }
                        }
                        else
                        {
                            Manager.SolutionMove(layer, true);
                            if (RefreshCube(e).Position.HasFlag(Cube3D.RubikPosition.TopLayer))
                            {
                                Manager.SolutionMove(Cube3D.RubikPosition.TopLayer, true);
                                Manager.SolutionMove(layer, false);
                            }
                            else
                            {
                                for (int i = 0; i < 2; i++)
                                {
                                    Manager.SolutionMove(layer, true);
                                }
                                Manager.SolutionMove(Cube3D.RubikPosition.TopLayer, true);
                                Manager.SolutionMove(layer, true);
                            }
                        }
                    }
                    if (e.Position.HasFlag(Cube3D.RubikPosition.BottomLayer))
                    {
                        for (int i = 0; i < 2; i++)
                        {
                            Manager.SolutionMove(layer, true);
                        }
                    }

                    //Rotate over target position
                    while (!RefreshCube(e).Position.HasFlag(targetLayer))
                    {
                        Manager.SolutionMove(Cube3D.RubikPosition.TopLayer, true);
                    }

                    //Rotate to target position
                    for (int i = 0; i < 2; i++)
                    {
                        Manager.SolutionMove(targetLayer, true);
                    }
                }

                //Flip the incorrect orientated edges with the algorithm: Fi D Ri Di
                if (e.Faces.First(f => f.Position == Face3D.FacePosition.Bottom).Color != bottomColor)
                {
                    Cube3D.RubikPosition frontLayer = FacePosToCubePos(RefreshCube(e).Faces.First(f => f.Color == bottomColor).Position);
                    Manager.SolutionMove(frontLayer, false);
                    Manager.SolutionMove(Cube3D.RubikPosition.BottomLayer, true);

                    Cube3D.RubikPosition rightSlice = FacePosToCubePos(RefreshCube(e).Faces.First(f => f.Color == secondColor).Position);

                    Manager.SolutionMove(rightSlice, false);
                    Manager.SolutionMove(Cube3D.RubikPosition.BottomLayer, false);
                }
                solvedBottomEdges = bottomEdges.Where(bE => RefreshCube(bE).Position == GetTargetPosition(RefreshCube(bE)) && RefreshCube(bE).Faces.First(f => f.Color == bottomColor).Position == Face3D.FacePosition.Bottom);
            }
        }