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); } }