Пример #1
0
        private CoordCube ToCoordCube(Rubik rubik)
        {
            // get corner perm and orientation
            string[] corners = new string[N_CORNER] {
                "UFR", "UFL", "UBL", "URB", "DFR", "DFL", "DBL", "DRB"
            };
            byte[] cornerPermutation = new byte[N_CORNER];
            byte[] cornerOrientation = new byte[N_CORNER];
            for (int i = 0; i < N_CORNER; i++)
            {
                CubeFlag pos          = CubeFlagService.Parse(corners[i]);
                Cube     matchingCube = rubik.Cubes.First(c => c.Position.Flags == pos);
                CubeFlag targetPos    = rubik.GetTargetFlags(matchingCube);
                cornerOrientation[i] = (byte)Solvability.GetOrientation(rubik, matchingCube);

                for (int j = 0; j < N_CORNER; j++)
                {
                    if (corners[j] == CubeFlagService.ToNotationString(targetPos))
                    {
                        cornerPermutation[i] = (byte)(j + 1);
                    }
                }
            }

            // get edge perm and orientation
            string[] edges = new string[N_EDGE] {
                "UR", "UF", "UL", "UB", "DR", "DF", "DL", "DB", "FR", "FL", "BL", "RB"
            };
            byte[] edgePermutation = new byte[N_EDGE];
            byte[] edgeOrientation = new byte[N_EDGE];
            for (int i = 0; i < N_EDGE; i++)
            {
                CubeFlag pos          = CubeFlagService.Parse(edges[i]);
                Cube     matchingCube = rubik.Cubes.Where(c => c.IsEdge).First(c => c.Position.Flags.HasFlag(pos));
                CubeFlag targetPos    = rubik.GetTargetFlags(matchingCube);
                edgeOrientation[i] = (byte)Solvability.GetOrientation(rubik, matchingCube);

                for (int j = 0; j < N_EDGE; j++)
                {
                    if (CubeFlagService.ToNotationString(targetPos).Contains(edges[j]))
                    {
                        edgePermutation[i] = (byte)(j + 1);
                    }
                }
            }

            byte[] cornerInv = CoordCube.ToInversions(cornerPermutation);
            byte[] edgeInv   = CoordCube.ToInversions(edgePermutation);

            return(new CoordCube(cornerPermutation, edgePermutation, cornerOrientation, edgeOrientation));
        }
Пример #2
0
        public static int GetOrientation(Rubik rubik, Cube c)
        {
            int orientation = 0;

            if (c.IsEdge)
            {
                CubeFlag targetFlags = rubik.GetTargetFlags(c);
                Rubik    clone       = rubik.DeepClone();

                if (!targetFlags.HasFlag(CubeFlag.MiddleLayer))
                {
                    while (RefreshCube(clone, c).Position.HasFlag(CubeFlag.MiddleLayer))
                    {
                        clone.RotateLayer(c.Position.X, true);
                    }

                    Cube clonedCube = RefreshCube(clone, c);
                    Face yFace      = clonedCube.Faces.First(f => f.Color == rubik.TopColor || f.Color == rubik.BottomColor);
                    if (!FacePosition.YPos.HasFlag(yFace.Position))
                    {
                        orientation = 1;
                    }
                }
                else
                {
                    Face zFace = c.Faces.First(f => f.Color == rubik.FrontColor || f.Color == rubik.BackColor);
                    if (c.Position.HasFlag(CubeFlag.MiddleLayer))
                    {
                        if (!FacePosition.ZPos.HasFlag(zFace.Position))
                        {
                            orientation = 1;
                        }
                    }
                    else
                    {
                        if (!FacePosition.YPos.HasFlag(zFace.Position))
                        {
                            orientation = 1;
                        }
                    }
                }
            }
            else if (c.IsCorner)
            {
                Face face = c.Faces.First(f => f.Color == rubik.TopColor || f.Color == rubik.BottomColor);
                if (!FacePosition.YPos.HasFlag(face.Position))
                {
                    if (FacePosition.XPos.HasFlag(face.Position) ^ !((c.Position.HasFlag(CubeFlag.BottomLayer) ^ (c.Position.HasFlag(CubeFlag.FrontSlice) ^ c.Position.HasFlag(CubeFlag.RightSlice)))))
                    {
                        orientation = 1;
                    }
                    else
                    {
                        orientation = 2;
                    }
                }
            }

            return(orientation);
        }
Пример #3
0
        private static IEnumerable <Tuple <Cube, Cube> > GetPairs(Rubik rubik)
        {
            foreach (Cube edge in rubik.Cubes.Where(c => c.IsEdge && rubik.GetTargetFlags(c).HasFlag(CubeFlag.MiddleLayer)))
            {
                Cube corner =
                    rubik.Cubes
                    .First(c =>
                {
                    return(c.IsCorner &&
                           (rubik.GetTargetFlags(c) & ~CubeFlag.BottomLayer) ==
                           (rubik.GetTargetFlags(edge) & ~CubeFlag.MiddleLayer));
                });

                if (!rubik.IsCorrect(corner) || !rubik.IsCorrect(edge))
                {
                    yield return(new Tuple <Cube, Cube>(edge, corner));
                }
            }
        }
Пример #4
0
        /// <summary>
        /// Converts a rubik to a pattern
        /// </summary>
        /// <param name="r">Rubik </param>
        /// <returns>The pattern of the given rubik</returns>
        public static Pattern FromRubik(Rubik r)
        {
            Pattern            p        = new Pattern();
            List <PatternItem> newItems = new List <PatternItem>();

            foreach (CubePosition pos in Positions)
            {
                Cube cube = r.Cubes.First(c => r.GetTargetFlags(c) == pos.Flags);
                newItems.Add(new PatternItem(cube.Position, Solvability.GetOrientation(r, cube), pos.Flags));
            }
            p.Items = newItems;
            return(p);
        }
Пример #5
0
        private void CompleteF2L()
        {
            List <Tuple <Cube, Cube> > unsolvedPairs = GetPairs(this.Rubik).ToList();

            while (unsolvedPairs.Count > 0) // 4 pairs
            {
                Tuple <Cube, Cube> currentPair = unsolvedPairs.First();

                Cube edge   = currentPair.Item1;
                Cube corner = currentPair.Item2;

                CubePosition target = new CubePosition(Rubik.GetTargetFlags(corner));

                if (!corner.Position.HasFlag(CubeFlag.TopLayer) && Rubik.GetTargetFlags(corner) != corner.Position.Flags)
                {
                    CubeFlag rotationLayer = CubeFlagService.FirstNotInvalidFlag(corner.Position.Flags, CubeFlag.BottomLayer);
                    bool     direction     = new TestScenario(Rubik, new LayerMove(rotationLayer)).TestCubePosition(corner, CubeFlag.TopLayer);
                    SolverMove(rotationLayer, direction);
                    SolverMove(CubeFlag.TopLayer, true);
                    SolverMove(rotationLayer, !direction);
                }
                // move edge to top position if necessary
                if (!edge.Position.HasFlag(CubeFlag.TopLayer) && Rubik.GetTargetFlags(edge) != edge.Position.Flags)
                {
                    CubeFlag rotationLayer = CubeFlagService.FirstNotInvalidFlag(edge.Position.Flags, CubeFlag.MiddleLayer);
                    bool     direction     = new TestScenario(Rubik, new LayerMove(rotationLayer)).TestCubePosition(edge, CubeFlag.TopLayer);
                    SolverMove(rotationLayer, direction);
                    while ((corner.Position.HasFlag(rotationLayer) && !corner.Position.HasFlag(CubeFlag.BottomLayer)) || edge.Position.HasFlag(rotationLayer))
                    {
                        SolverMove(CubeFlag.TopLayer, true);
                    }
                    SolverMove(rotationLayer, !direction);
                }

                // detect right and front slice
                CubeFlag rightSlice = CubeFlagService.ToInt(target.X) == CubeFlagService.ToInt(target.Z) ? target.Z : target.X;
                CubeFlag frontSlice = CubeFlagService.FirstNotInvalidFlag(target.Flags, CubeFlag.YFlags | rightSlice);

                while (!corner.Position.HasFlag(target.Flags & ~CubeFlag.BottomLayer))
                {
                    SolverMove(CubeFlag.TopLayer, true);
                }

                PatternFilter filter = new PatternFilter(new Func <Pattern, Pattern, bool>(delegate(Pattern p1, Pattern p2)
                {
                    PatternItem item = new PatternItem(corner.Position, Solvability.GetOrientation(this.Rubik, corner), target.Flags);
                    return(p2.Items.Any(i => i.Equals(item)));
                }), true);

                Algorithm algo = null;
                for (int i = 0; i < 4; i++)
                {
                    F2LPattern pattern = new F2LPattern(Rubik.GetTargetFlags(edge), Rubik.GetTargetFlags(corner), rightSlice, frontSlice);
                    algo = pattern.FindBestMatch(Pattern.FromRubik(Rubik), CubeFlag.None, filter);
                    if (algo != null)
                    {
                        SolverAlgorithm(algo); break;
                    }
                    SolverMove(CubeFlag.TopLayer, true);
                }

                int count = unsolvedPairs.Count;
                unsolvedPairs = GetPairs(this.Rubik).ToList();
                if (unsolvedPairs.Count == count)
                {
                    this.BroadcastOnSolutionError("Complete first two layers", "Wrong algorithm");
                    return;
                }
            }
        }