Exemplo n.º 1
0
        //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);
            }
        }
Exemplo n.º 2
0
 private int CountTopEdgesAtTargetPosition(RubikManager manager)
 {
     return(manager.RubikCube.cubes.Count(c => Cube3D.isEdge(c.Position) && c.Position.HasFlag(Cube3D.RubikPosition.TopLayer) && c.Position == GetTargetPosition(c)));
 }
Exemplo n.º 3
0
        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));
                }
            }
        }
Exemplo n.º 4
0
        private int CountEdgesWithCorrectOrientation(RubikManager manager)
        {
            Color topColor = manager.getFaceColor(Cube3D.RubikPosition.TopLayer | Cube3D.RubikPosition.MiddleSlice_Sides | Cube3D.RubikPosition.MiddleSlice, Face3D.FacePosition.Top);

            return(manager.RubikCube.cubes.Count(c => Cube3D.isEdge(c.Position) && c.Faces.First(f => f.Position == Face3D.FacePosition.Top).Color == topColor));
        }
Exemplo n.º 5
0
        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);
            }
        }