예제 #1
0
        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);
        }
예제 #2
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);
            }
        }