Exemplo n.º 1
0
        /// <summary>
        /// Transforms the pattern item
        /// </summary>
        /// <param name="type">Transformation axis</param>
        public void Transform(CubeFlag rotationLayer)
        {
            if (CurrentPosition.HasFlag(rotationLayer))
            {
                CubeFlag oldFlags = this.CurrentPosition.Flags;
                CurrentPosition.NextFlag(rotationLayer, true);


                Orientation newOrientation = this.CurrentOrientation;
                if (CubePosition.IsCorner(CurrentPosition.Flags) && !CubeFlagService.IsYFlag(rotationLayer))
                {
                    if (new CubePosition(oldFlags).Y == new CubePosition(CurrentPosition.Flags).Y)
                    {
                        newOrientation = (Orientation)(((int)newOrientation + 2) % 3);
                    }
                    else
                    {
                        newOrientation = (Orientation)(((int)newOrientation + 1) % 3);
                    }
                }
                else if (CubePosition.IsEdge(CurrentPosition.Flags) && CubeFlagService.IsZFlag(rotationLayer))
                {
                    newOrientation = (Orientation)((int)newOrientation ^ 0x1);
                }

                this.CurrentOrientation = newOrientation;
            }
            if (TargetPosition.HasFlag(rotationLayer))
            {
                TargetPosition = CubeFlagService.NextFlags(TargetPosition, rotationLayer, true);
            }
        }
Exemplo n.º 2
0
        /// <summary>
        /// Change the position of the cube by rotating it on the given layer and the given direction
        /// </summary>
        /// <param name="layer">Defines the layer the cube is to rotate on</param>
        /// <param name="direction">Defines the direction of the rotation (true == clockwise)</param>
        public void NextPos(CubeFlag layer, bool direction)
        {
            Cube oldCube = DeepClone();

            Position.NextFlag(layer, direction);
            #region Colors
            if (this.IsCorner)
            {
                //Set colors
                Face  layerFace  = this.Faces.First(f => f.Position == CubeFlagService.ToFacePosition(layer));
                Color layerColor = layerFace.Color;

                CubeFlag newFlag    = CubeFlagService.FirstNotInvalidFlag(this.Position.Flags, oldCube.Position.Flags);
                CubeFlag commonFlag = CubeFlagService.FirstNotInvalidFlag(this.Position.Flags, newFlag | layer);
                CubeFlag oldFlag    = CubeFlagService.FirstNotInvalidFlag(oldCube.Position.Flags, commonFlag | layer);

                Color colorNewPos    = Faces.First(f => f.Position == CubeFlagService.ToFacePosition(commonFlag)).Color;
                Color colorCommonPos = Faces.First(f => f.Position == CubeFlagService.ToFacePosition(oldFlag)).Color;

                ResetColors();
                SetFaceColor(layerFace.Position, layerColor);
                SetFaceColor(CubeFlagService.ToFacePosition(newFlag), colorNewPos);
                SetFaceColor(CubeFlagService.ToFacePosition(commonFlag), colorCommonPos);
            }

            if (this.IsCenter)
            {
                CubeFlag oldFlag     = CubeFlagService.FirstNotInvalidFlag(oldCube.Position.Flags, CubeFlag.MiddleLayer | CubeFlag.MiddleSlice | CubeFlag.MiddleSliceSides);
                Color    centerColor = this.Faces.First(f => f.Position == CubeFlagService.ToFacePosition(oldFlag)).Color;
                CubeFlag newPos      = CubeFlagService.FirstNotInvalidFlag(this.Position.Flags, CubeFlag.MiddleSliceSides | CubeFlag.MiddleSlice | CubeFlag.MiddleLayer);

                ResetColors();
                SetFaceColor(CubeFlagService.ToFacePosition(newPos), centerColor);
            }

            if (this.IsEdge)
            {
                CubeFlag newFlag    = CubeFlagService.FirstNotInvalidFlag(this.Position.Flags, oldCube.Position.Flags | CubeFlag.MiddleSlice | CubeFlag.MiddleSliceSides | CubeFlag.MiddleLayer);
                CubeFlag commonFlag = CubeFlagService.FirstNotInvalidFlag(this.Position.Flags, newFlag | CubeFlag.MiddleSlice | CubeFlag.MiddleSliceSides | CubeFlag.MiddleLayer);
                CubeFlag oldFlag    = CubeFlagService.FirstNotInvalidFlag(oldCube.Position.Flags, commonFlag | CubeFlag.MiddleSlice | CubeFlag.MiddleSliceSides | CubeFlag.MiddleLayer);

                Color colorNewPos    = this.Faces.First(f => f.Position == CubeFlagService.ToFacePosition(commonFlag)).Color;
                Color colorCommonPos = this.Faces.First(f => f.Position == CubeFlagService.ToFacePosition(oldFlag)).Color;


                ResetColors();
                if (layer == CubeFlag.MiddleLayer || layer == CubeFlag.MiddleSlice || layer == CubeFlag.MiddleSliceSides)
                {
                    SetFaceColor(CubeFlagService.ToFacePosition(newFlag), colorNewPos);
                    SetFaceColor(CubeFlagService.ToFacePosition(commonFlag), colorCommonPos);
                }
                else
                {
                    SetFaceColor(CubeFlagService.ToFacePosition(commonFlag), colorNewPos);
                    SetFaceColor(CubeFlagService.ToFacePosition(newFlag), colorCommonPos);
                }
            }
            #endregion
        }
Exemplo n.º 3
0
        private void CompleteLastLayer()
        {
            // Step 1: Get edges with the color of the top face
            IEnumerable <Cube> topCorners = Rubik.Cubes.Where(c => c.IsCorner).Where(c => c.Position.HasFlag(CubeFlag.TopLayer));

            // Step 2: Bring corners to their target position
            while (topCorners.Where(c => c.Position.Flags == GetTargetFlags(c)).Count() < 4)
            {
                IEnumerable <Cube> correctCorners = topCorners.Where(c => c.Position.Flags == GetTargetFlags(c));
                CubeFlag           rightSlice;
                if (correctCorners.Count() != 0)
                {
                    Cube firstCube = correctCorners.First();
                    Face rightFace = firstCube.Faces.First(f => f.Color != Color.Black && f.Position != FacePosition.Top);
                    rightSlice = CubeFlagService.FromFacePosition(rightFace.Position);

                    if (!new TestScenario(Rubik, new LayerMove(rightSlice, true)).TestCubePosition(firstCube, CubeFlag.TopLayer))
                    {
                        rightSlice = CubeFlagService.FromFacePosition(firstCube.Faces.First(f => f.Color != rightFace.Color && f.Color != Color.Black && f.Position != FacePosition.Top).Position);
                    }
                }
                else
                {
                    rightSlice = CubeFlag.RightSlice;
                }

                SolverAlgorithm("U {0} U' {1}' U {0}' U' {1}", CubeFlagService.ToNotationString(rightSlice), CubeFlagService.ToNotationString(CubeFlagService.GetOppositeFlag(rightSlice)));
            }

            // Step 3: Orientation of the corners on the top layer
            Face     rightFac  = topCorners.First().Faces.First(f => f.Color != Color.Black && f.Position != FacePosition.Top);
            CubeFlag rightSlic = !new TestScenario(Rubik, new LayerMove(CubeFlagService.FromFacePosition(rightFac.Position), true)).TestCubePosition(topCorners.First(), CubeFlag.TopLayer)
        ? CubeFlagService.FromFacePosition(rightFac.Position)
        : CubeFlagService.FromFacePosition(topCorners.First().Faces.First(f => f.Color != rightFac.Color && f.Color != Color.Black && f.Position != FacePosition.Top).Position);;

            foreach (Cube c in topCorners)
            {
                while (!c.Position.HasFlag(rightSlic))
                {
                    SolverMove(CubeFlag.TopLayer, true);
                }

                if (!new TestScenario(Rubik, new LayerMove(rightSlic, true)).TestCubePosition(c, CubeFlag.TopLayer))
                {
                    SolverMove(CubeFlag.TopLayer, true);
                }

                // Algorithm: Ri Di R D
                while (c.Faces.First(f => f.Position == FacePosition.Top).Color != Rubik.TopColor)
                {
                    SolverAlgorithm("{0}' D' {0} D", CubeFlagService.ToNotationString(rightSlic));
                }
            }
            while (topCorners.Count(tC => tC.Position.Flags == GetTargetFlags(tC)) != 4)
            {
                SolverMove(CubeFlag.TopLayer, true);
            }
        }
Exemplo n.º 4
0
        /// <summary>
        /// Generates 3D cubes from the Rubik cubes
        /// </summary>
        /// <returns>Cubes from the Rubik converted to 3D cubes</returns>
        private List <Cube3D> GenCubes3D()
        {
            List <Cube> cubes = this.Rubik.Cubes;

            List <Cube3D> cubes3D = new List <Cube3D>();
            double        d       = 2.0 / 3.0;

            foreach (Cube c in cubes)
            {
                Cube3D cr = new Cube3D(new Point3D(d * CubeFlagService.ToInt(c.Position.X), d * CubeFlagService.ToInt(c.Position.Y), d * CubeFlagService.ToInt(c.Position.Z)), d / 2, c.Position.Flags, c.Faces);
                if (cr.Position.HasFlag(CubeFlag.TopLayer))
                {
                    cr = cr.Rotate(RotationType.Y, LayerRotation[CubeFlag.TopLayer], new Point3D(0, d, 0));
                }
                if (cr.Position.HasFlag(CubeFlag.MiddleLayer))
                {
                    cr = cr.Rotate(RotationType.Y, LayerRotation[CubeFlag.MiddleLayer], new Point3D(0, 0, 0));
                }
                if (cr.Position.HasFlag(CubeFlag.BottomLayer))
                {
                    cr = cr.Rotate(RotationType.Y, LayerRotation[CubeFlag.BottomLayer], new Point3D(0, -d, 0));
                }
                if (cr.Position.HasFlag(CubeFlag.FrontSlice))
                {
                    cr = cr.Rotate(RotationType.Z, LayerRotation[CubeFlag.FrontSlice], new Point3D(0, 0, d));
                }
                if (cr.Position.HasFlag(CubeFlag.MiddleSlice))
                {
                    cr = cr.Rotate(RotationType.Z, LayerRotation[CubeFlag.MiddleSlice], new Point3D(0, 0, 0));
                }
                if (cr.Position.HasFlag(CubeFlag.BackSlice))
                {
                    cr = cr.Rotate(RotationType.Z, LayerRotation[CubeFlag.BackSlice], new Point3D(0, 0, -d));
                }
                if (cr.Position.HasFlag(CubeFlag.LeftSlice))
                {
                    cr = cr.Rotate(RotationType.X, LayerRotation[CubeFlag.LeftSlice], new Point3D(-d, 0, 0));
                }
                if (cr.Position.HasFlag(CubeFlag.MiddleSliceSides))
                {
                    cr = cr.Rotate(RotationType.X, LayerRotation[CubeFlag.MiddleSliceSides], new Point3D(0, 0, 0));
                }
                if (cr.Position.HasFlag(CubeFlag.RightSlice))
                {
                    cr = cr.Rotate(RotationType.X, LayerRotation[CubeFlag.RightSlice], new Point3D(d, 0, 0));
                }

                cr = cr.Rotate(RotationType.Y, this.Rotation[1], new Point3D(0, 0, 0));
                cr = cr.Rotate(RotationType.Z, this.Rotation[2], new Point3D(0, 0, 0));
                cr = cr.Rotate(RotationType.X, this.Rotation[0], new Point3D(0, 0, 0));
                cubes3D.Add(cr);
            }
            return(cubes3D);
        }
Exemplo n.º 5
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));
        }
Exemplo n.º 6
0
        /// <summary>
        /// Parses a string to a pattern item
        /// </summary>
        /// <param name="s">The string to be parsed
        /// 1: "currentPos, targetPos, currentOrientation"
        /// 2: "currentPos, currentOrientation" => any target position
        /// 3: "currentPos, targetPos" => any orientation
        /// </param>
        public static PatternItem Parse(string s)
        {
            string[] split = s.Split(',');

            if (split.Length == 1)
            {
                CubeFlag currPos = CubeFlagService.Parse(split[0]);
                if (Pattern.Positions.Count(p => p.Flags == currPos) != 1)
                {
                    throw new Exception("At least one orientation or position is not possible");
                }
                return(new PatternItem(new CubePosition(currPos), 0, currPos));
            }

            else if (split.Length == 2)
            {
                CubeFlag currPos     = CubeFlagService.Parse(split[0]);
                CubeFlag pos         = CubeFlagService.Parse(split[1]);
                int      orientation = 0;
                if (Pattern.Positions.Count(p => p.Flags == currPos) != 1 || (!int.TryParse(split[1], out orientation) && Pattern.Positions.Count(p => p.Flags == pos) != 1))
                {
                    throw new Exception("At least one orientation or position is not possible");
                }
                return(new PatternItem(new CubePosition(currPos), (Orientation)orientation, pos));
            }

            else if (split.Length == 3)
            {
                // check valid cube position
                CubeFlag currPos   = CubeFlagService.Parse(split[0]);
                CubeFlag targetPos = CubeFlagService.Parse(split[1]);
                if (!Pattern.Positions.Contains(new CubePosition(currPos)) || !Pattern.Positions.Contains(new CubePosition(targetPos)))
                {
                    throw new Exception("At least one position does not exist");
                }

                // check valid orientation
                int orientation = 0;
                if (!int.TryParse(split[2], out orientation))
                {
                    throw new Exception("At least one orientation is not possible");
                }

                return(new PatternItem(new CubePosition(currPos), (Orientation)orientation, targetPos));
            }
            else
            {
                throw new Exception("Parsing error");
            }
        }
        private void Update(int bufferIndex)
        {
            _renderHandle[bufferIndex].WaitOne();

            if (this.Moves.Count > 0)
            {
                RotationInfo currentRotation = this.Moves.Peek();

                foreach (AnimatedLayerMove rotation in currentRotation.Moves)
                {
                    double step = (double)rotation.Target / (double)((double)(currentRotation.Milliseconds / 1000.0) * (double)(this.Fps));
                    this.LayerRotation[rotation.Move.Layer] += step;
                }

                if (RotationIsFinished(currentRotation.Moves))
                {
                    this.RotationFinished(this.Moves.Dequeue());
                }
            }

            if (this.DrawingMode == RubiksCubeLib.CubeModel.DrawingMode.ThreeDimensional)
            {
                _buffer[bufferIndex] = this.GenFacesProjected(this.Screen, this.zoom);
            }
            else
            {
                List <Face3D> faces = new List <Face3D>();
                foreach (Cube c in this.Rubik.Cubes)
                {
                    faces.AddRange(c.Faces.Where(f => c.Position.Flags.HasFlag(CubeFlagService.FromFacePosition(f.Position))).Select(f => new Face3D(null, f.Color, f.Position, c.Position.Flags)));
                }
                _buffer[bufferIndex] = faces;
            }


            _updateHandle[bufferIndex].Set();
        }
Exemplo n.º 8
0
        private void SolveFirstCross()
        {
            // Step 1: Get the edges with target position on the bottom layer
            IEnumerable <Cube> bottomEdges = Rubik.Cubes.Where(c => c.IsEdge && GetTargetFlags(c).HasFlag(CubeFlag.BottomLayer));

            // Step 2: Rotate a correct orientated edge of the bottom layer to target position
            IEnumerable <Cube> solvedBottomEdges = bottomEdges.Where(bE => bE.Position.Flags == GetTargetFlags(bE) && bE.Faces.First(f => f.Color == Rubik.BottomColor).Position == FacePosition.Bottom);

            if (bottomEdges.Count(bE => bE.Position.HasFlag(CubeFlag.BottomLayer) && bE.Faces.First(f => f.Color == Rubik.BottomColor).Position == FacePosition.Bottom) > 0)
            {
                while (solvedBottomEdges.Count() < 1)
                {
                    SolverMove(CubeFlag.BottomLayer, true);
                    solvedBottomEdges = bottomEdges.Where(bE => bE.Position.Flags == GetTargetFlags(bE) && bE.Faces.First(f => f.Color == Rubik.BottomColor).Position == FacePosition.Bottom);
                }
            }

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

                if (e.Position.Flags != GetTargetFlags(e))
                {
                    // Rotate to top layer
                    CubeFlag layer = CubeFlagService.FromFacePosition(e.Faces.First(f => (f.Color == Rubik.BottomColor || f.Color == secondColor) &&
                                                                                    f.Position != FacePosition.Top && f.Position != FacePosition.Bottom).Position);

                    CubeFlag targetLayer = CubeFlagService.FromFacePosition(StandardCube.Cubes.First(cu => CollectionMethods.ScrambledEquals(cu.Colors, e.Colors))
                                                                            .Faces.First(f => f.Color == secondColor).Position);

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

                    // Rotate over target position
                    while (!e.Position.HasFlag(targetLayer))
                    {
                        SolverMove(CubeFlag.TopLayer, true);
                    }

                    //Rotate to target position
                    for (int i = 0; i < 2; i++)
                    {
                        SolverMove(targetLayer, true);
                    }
                    CubeFlag targetPos = GetTargetFlags(e);
                }

                // Flip the incorrect orientated edges with the algorithm: Fi D Ri Di
                if (Solvability.GetOrientation(Rubik, e) != 0)
                {
                    CubeFlag frontSlice = CubeFlagService.FromFacePosition(e.Faces.First(f => f.Color == Rubik.BottomColor).Position);

                    SolverMove(frontSlice, false);
                    SolverMove(CubeFlag.BottomLayer, true);

                    CubeFlag rightSlice = CubeFlagService.FromFacePosition(e.Faces.First(f => f.Color == secondColor).Position);

                    SolverMove(rightSlice, false);
                    SolverMove(CubeFlag.BottomLayer, false);
                }
                List <Face> faces = e.Faces.ToList();
                solvedBottomEdges = bottomEdges.Where(bE => bE.Position.Flags == GetTargetFlags(bE) && bE.Faces.First(f => f.Color == Rubik.BottomColor).Position == FacePosition.Bottom);
            }
        }
Exemplo n.º 9
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;
                }
            }
        }
Exemplo n.º 10
0
        private void SolveCrossTopLayer()
        {
            // Step 1: Get edges with the color of the top face
            IEnumerable <Cube> topEdges = Rubik.Cubes.Where(c => c.IsEdge).Where(c => c.Position.HasFlag(CubeFlag.TopLayer));

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

            var correctEdges             = topEdges.Where(c => c.Faces.First(f => f.Position == FacePosition.Top).Color == Rubik.TopColor);
            var solveTopCrossAlgorithmI  = new Algorithm("F R U R' U' F'");
            var solveTopCrossAlgorithmII = new Algorithm("F S R U R' U' F' S'");

            // Step 3: Solve the cross on the top layer
            if (Rubik.CountEdgesWithCorrectOrientation() == 0)
            {
                SolverAlgorithm(solveTopCrossAlgorithmI);
                correctEdges = topEdges.Where(c => c.Faces.First(f => f.Position == FacePosition.Top).Color == Rubik.TopColor);
            }

            if (Rubik.CountEdgesWithCorrectOrientation() == 2)
            {
                var firstCorrect  = correctEdges.First();
                var secondCorrect = correctEdges.First(f => f != firstCorrect);

                bool opposite = false;

                foreach (CubeFlag flag in firstCorrect.Position.GetFlags())
                {
                    CubeFlag pos = CubeFlagService.GetOppositeFlag(flag);

                    if (secondCorrect.Position.HasFlag(pos) && pos != CubeFlag.None)
                    {
                        opposite = true;
                        break;
                    }
                }

                if (opposite)
                {
                    while (correctEdges.Count(c => c.Position.HasFlag(CubeFlag.RightSlice)) != 1)
                    {
                        SolverMove(CubeFlag.TopLayer, true);
                    }

                    SolverAlgorithm(solveTopCrossAlgorithmI);
                }
                else
                {
                    while (correctEdges.Count(c => c.Position.HasFlag(CubeFlag.RightSlice) || c.Position.HasFlag(CubeFlag.FrontSlice)) != 2)
                    {
                        SolverMove(CubeFlag.TopLayer, true);
                    }

                    SolverAlgorithm(solveTopCrossAlgorithmII);
                }
            }

            // Step 4: Move the edges of the cross to their target positions
            while (topEdges.Count(c => c.Position.Flags == GetTargetFlags(c)) < 4)
            {
                IEnumerable <Cube> correctEdges2 = topEdges.Where(c => c.Position.Flags == GetTargetFlags(c));
                while (correctEdges2.Count() < 2)
                {
                    SolverMove(CubeFlag.TopLayer, true);
                }

                CubeFlag rightSlice = CubeFlagService.FromFacePosition(correctEdges2.First().Faces
                                                                       .First(f => f.Position != FacePosition.Top && f.Color != Color.Black).Position);
                SolverMove(CubeFlag.TopLayer, false);

                if (correctEdges2.Count(c => c.Position.HasFlag(rightSlice)) == 0)
                {
                    SolverMove(CubeFlag.TopLayer, true);
                }
                else
                {
                    SolverMove(CubeFlag.TopLayer, true);

                    rightSlice =
                        CubeFlagService.FromFacePosition(
                            correctEdges2
                            .First(cE => !cE.Position.HasFlag(rightSlice))
                            .Faces
                            .First(f =>
                                   f.Position != FacePosition.Top &&
                                   f.Color != Color.Black
                                   )
                            .Position
                            );
                }

                // Algorithm: R U R' U R U U R'
                SolverAlgorithm(
                    "{0} U {0}' U {0} U U {0}'",
                    CubeFlagService.ToNotationString(rightSlice)
                    );

                while (correctEdges2.Count() < 2)
                {
                    SolverMove(CubeFlag.TopLayer, true);
                }
            }
        }
Exemplo n.º 11
0
        private void CompleteMiddleLayer()
        {
            // Step 1: Get the egdes of the middle layer
            List <Cube> middleEdges =
                Rubik.Cubes
                .Where(c => c.IsEdge)
                .Where(c => GetTargetFlags(c).HasFlag(CubeFlag.MiddleLayer))
                .ToList();

            List <Face> coloredFaces = new List <Face>();

            Rubik.Cubes.Where(cu => cu.IsCenter)
            .ToList()
            .ForEach(cu =>
                     coloredFaces.Add(cu.Faces.First(f => f.Color != Color.Black))
                     );

            IEnumerable <Cube> solvedMiddleEdges =
                middleEdges
                .Where(mE =>
                       mE.Position.Flags == GetTargetFlags(mE) &&
                       mE.Faces.Count(f => coloredFaces.Count(cf => cf.Color == f.Color && cf.Position == f.Position) == 1) == 2
                       );

            // Step 2: solve incorrect middle edges
            while (solvedMiddleEdges.Count() < 4)
            {
                IEnumerable <Cube> unsolvedMiddleEdges = middleEdges.Except(solvedMiddleEdges);
                Cube c =
                    (unsolvedMiddleEdges.FirstOrDefault(cu => !cu.Position.HasFlag(CubeFlag.MiddleLayer)) != null)
                        ? unsolvedMiddleEdges.First(cu => !cu.Position.HasFlag(CubeFlag.MiddleLayer))
                        : unsolvedMiddleEdges.First();

                // Rotate to top layer
                if (!c.Position.HasFlag(CubeFlag.TopLayer))
                {
                    Face     frontFace  = c.Faces.First(f => f.Color != Color.Black);
                    CubeFlag frontSlice = CubeFlagService.FromFacePosition(frontFace.Position);
                    Face     face       = c.Faces.First(f => f.Color != Color.Black && f.Color != frontFace.Color);
                    CubeFlag slice      = CubeFlagService.FromFacePosition(face.Position);

                    if (new TestScenario(Rubik, new LayerMove(slice, true, false)).TestCubePosition(c, CubeFlag.TopLayer))
                    {
                        // Algorithm to the right: U R Ui Ri Ui Fi U F
                        SolverAlgorithm(
                            "U {0} U' {0}' U' {1}' U {1}",
                            CubeFlagService.ToNotationString(slice),
                            CubeFlagService.ToNotationString(frontSlice)
                            );
                    }
                    else
                    {
                        // Algorithm to the left: Ui Li U L U F Ui Fi
                        SolverAlgorithm(
                            "U' {0}' U {0} U {1} U' {1}'",
                            CubeFlagService.ToNotationString(slice),
                            CubeFlagService.ToNotationString(frontSlice)
                            );
                    }
                }

                // Rotate to start position for the algorithm
                List <Cube> centers =
                    Rubik.Cubes
                    .Where(m => m.IsCenter)
                    .Where(m =>
                {
                    var thing2 =
                        m.Colors.First(co => co != Color.Black) ==
                        c.Faces.First(f => f.Color != Color.Black && f.Position != FacePosition.Top).Color;

                    var thing3 =
                        (m.Position.Flags & ~CubeFlag.MiddleLayer) == (c.Position.Flags & ~CubeFlag.TopLayer);

                    return(thing2 && thing3);
                })
                    .ToList();

                while (!centers.Any())
                {
                    SolverMove(CubeFlag.TopLayer, true);

                    centers =
                        Rubik.Cubes
                        .Where(cu => cu.IsCenter)
                        .Where(m =>
                               m.Colors.First(co => co != Color.Black) == c.Faces.First(f => f.Color != Color.Black && f.Position != FacePosition.Top).Color &&
                               (m.Position.Flags & ~CubeFlag.MiddleLayer) == (c.Position.Flags & ~CubeFlag.TopLayer)
                               )
                        .ToList();
                }

                // Rotate to target position
                Face     frontFac  = c.Faces.First(f => f.Color != Color.Black && f.Position != FacePosition.Top);
                CubeFlag frontSlic = CubeFlagService.FromFacePosition(frontFac.Position);

                CubeFlag slic = CubeFlagService.FirstNotInvalidFlag(GetTargetFlags(c), CubeFlag.MiddleLayer | frontSlic);

                if (!new TestScenario(Rubik, new LayerMove(CubeFlag.TopLayer, true, false)).TestCubePosition(c, slic))
                {
                    // Algorithm to the right: U R Ui Ri Ui Fi U F
                    SolverAlgorithm(
                        "U {0} U' {0}' U' {1}' U {1}",
                        CubeFlagService.ToNotationString(slic),
                        CubeFlagService.ToNotationString(frontSlic)
                        );
                }
                else
                {
                    // Algorithm to the left: Ui Li U L U F Ui Fi
                    SolverAlgorithm(
                        "U' {0}' U {0} U {1} U' {1}'",
                        CubeFlagService.ToNotationString(slic),
                        CubeFlagService.ToNotationString(frontSlic)
                        );
                }

                solvedMiddleEdges =
                    middleEdges.Where(mE =>
                                      mE.Faces.Count(f =>
                                                     coloredFaces.Count(cf => cf.Color == f.Color && cf.Position == f.Position) == 1
                                                     ) == 2
                                      );
            }
        }
Exemplo n.º 12
0
        private void SolveFirstCross()
        {
            // Step 1: Get the edges with target position on the bottom layer
            IEnumerable <Cube> bottomEdges =
                Rubik.Cubes.Where(c =>
                                  c.IsEdge

                                  // target position on bottom layer
                                  && GetTargetFlags(c).HasFlag(CubeFlag.BottomLayer)
                                  );

            // Step 2: Rotate a correct orientated edge of the bottom layer to target position
            IEnumerable <Cube> bottomEdgesInBottomLayerCorrectlyOriented =
                bottomEdges.Where(bottomEdge =>
                                  // is in bottom layer
                                  bottomEdge.Position.Flags == GetTargetFlags(bottomEdge)

                                  // is oriented correctly
                                  && bottomEdge.Faces.First(f => f.Color == Rubik.BottomColor).Position == FacePosition.Bottom
                                  );

            var anyEdgesAreSolvableWithDMoves =
                bottomEdges.Count(bE =>
                                  bE.Position.HasFlag(CubeFlag.BottomLayer) &&
                                  bE.Faces.First(f => f.Color == Rubik.BottomColor).Position == FacePosition.Bottom
                                  ) > 0;

            if (anyEdgesAreSolvableWithDMoves)
            {
                while (!bottomEdgesInBottomLayerCorrectlyOriented.Any())
                {
                    // turn the bottom layer until at least one is
                    SolverMove(CubeFlag.BottomLayer, true);

                    bottomEdgesInBottomLayerCorrectlyOriented =
                        bottomEdges.Where(bE =>
                                          bE.Position.Flags == GetTargetFlags(bE) &&
                                          bE.Faces.First(f => f.Color == Rubik.BottomColor).Position == FacePosition.Bottom
                                          );
                }
            }

            // Step 3: Solve incorrect edges of the bottom layer
            while (bottomEdgesInBottomLayerCorrectlyOriented.Count() < 4)
            {
                IEnumerable <Cube> unsolvedBottomEdges = bottomEdges.Except(bottomEdgesInBottomLayerCorrectlyOriented);

                Cube e =
                    unsolvedBottomEdges.FirstOrDefault(c => c.Position.HasFlag(CubeFlag.TopLayer))
                    ?? unsolvedBottomEdges.First();

                Color secondColor =
                    e.Colors.First(co =>
                                   co != Rubik.BottomColor &&
                                   co != Color.Black
                                   );

                if (e.Position.Flags != GetTargetFlags(e))
                {
                    // Rotate to top layer
                    CubeFlag layer =
                        CubeFlagService.FromFacePosition(
                            e.Faces.First(f =>
                                          (f.Color == Rubik.BottomColor || f.Color == secondColor) &&
                                          f.Position != FacePosition.Top && f.Position != FacePosition.Bottom
                                          ).Position
                            );

                    CubeFlag targetLayer =
                        CubeFlagService.FromFacePosition(
                            StandardCube.Cubes.First(cu =>
                                                     CollectionMethods.ScrambledEquals(cu.Colors, e.Colors)
                                                     )
                            .Faces
                            .First(f => f.Color == secondColor)
                            .Position
                            );

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

                                SolverMove(CubeFlag.TopLayer, true);
                                SolverMove(layer, true);
                            }
                        }
                    }

                    if (e.Position.HasFlag(CubeFlag.BottomLayer))
                    {
                        for (int i = 0; i < 2; i++)
                        {
                            SolverMove(layer, true);
                        }
                    }

                    // Rotate over target position
                    while (!e.Position.HasFlag(targetLayer))
                    {
                        SolverMove(CubeFlag.TopLayer, true);
                    }

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

                // Flip the incorrect orientated edges with the algorithm: F' D R' D'
                if (Solvability.GetOrientation(Rubik, e) != 0)
                {
                    CubeFlag frontSlice = CubeFlagService.FromFacePosition(e.Faces.First(f => f.Color == Rubik.BottomColor).Position);

                    SolverMove(frontSlice, false);
                    SolverMove(CubeFlag.BottomLayer, true);

                    CubeFlag rightSlice = CubeFlagService.FromFacePosition(e.Faces.First(f => f.Color == secondColor).Position);

                    SolverMove(rightSlice, false);
                    SolverMove(CubeFlag.BottomLayer, false);
                }

                bottomEdgesInBottomLayerCorrectlyOriented =
                    bottomEdges.Where(bE =>
                                      bE.Position.Flags == GetTargetFlags(bE) &&
                                      bE.Faces.First(f => f.Color == Rubik.BottomColor).Position == FacePosition.Bottom
                                      );
            }
        }
Exemplo n.º 13
0
        private void CompleteFirstLayer()
        {
            // Step 1: Get the corners with target position on bottom layer
            IEnumerable <Cube> bottomCorners =
                Rubik.Cubes.Where(c =>
                                  c.IsCorner &&
                                  GetTargetFlags(c).HasFlag(CubeFlag.BottomLayer)
                                  );

            IEnumerable <Cube> solvedBottomCorners =
                bottomCorners.Where(bC =>
                                    bC.Position.Flags == GetTargetFlags(bC) &&
                                    bC.Faces.First(f => f.Color == Rubik.BottomColor).Position == FacePosition.Bottom
                                    );

            // Step 2: Solve incorrect edges
            while (solvedBottomCorners.Count() < 4)
            {
                IEnumerable <Cube> unsolvedBottomCorners = bottomCorners.Except(solvedBottomCorners);

                // here.
                Cube c =
                    (unsolvedBottomCorners.FirstOrDefault(bC => bC.Position.HasFlag(CubeFlag.TopLayer)) != null)
                          ? unsolvedBottomCorners.First(bC => bC.Position.HasFlag(CubeFlag.TopLayer))
                          : unsolvedBottomCorners.First();

                if (c.Position.Flags != GetTargetFlags(c))
                {
                    // Rotate to top layer
                    if (c.Position.HasFlag(CubeFlag.BottomLayer))
                    {
                        Face     leftFace  = c.Faces.First(f => f.Position != FacePosition.Bottom && f.Color != Color.Black);
                        CubeFlag leftSlice = CubeFlagService.FromFacePosition(leftFace.Position);

                        SolverMove(leftSlice, false);

                        if (c.Position.HasFlag(CubeFlag.BottomLayer))
                        {
                            SolverMove(leftSlice, true);

                            leftFace =
                                c.Faces.First(f =>
                                              f.Position != FacePosition.Bottom &&
                                              f.Color != leftFace.Color &&
                                              f.Color != Color.Black
                                              );

                            leftSlice = CubeFlagService.FromFacePosition(leftFace.Position);

                            SolverMove(leftSlice, false);
                        }

                        SolverAlgorithm("U' {0} U", CubeFlagService.ToNotationString(leftSlice));
                    }

                    // Rotate over target position
                    CubeFlag targetPos = CubeFlagService.ExceptFlag(GetTargetFlags(c), CubeFlag.BottomLayer);

                    while (!c.Position.HasFlag(targetPos))
                    {
                        SolverMove(CubeFlag.TopLayer, true);
                    }
                }

                // Rotate to target position with the algorithm: Li Ui L U
                Face leftFac =
                    c.Faces.First(f =>
                                  f.Position != FacePosition.Top &&
                                  f.Position != FacePosition.Bottom &&
                                  f.Color != Color.Black
                                  );

                CubeFlag leftSlic = CubeFlagService.FromFacePosition(leftFac.Position);

                SolverMove(leftSlic, false);
                if (!c.Position.HasFlag(CubeFlag.TopLayer))
                {
                    SolverMove(leftSlic, true);

                    leftFac =
                        c.Faces.First(f =>
                                      f.Position != FacePosition.Top &&
                                      f.Position != FacePosition.Bottom &&
                                      f.Color != leftFac.Color &&
                                      f.Color != Color.Black
                                      );

                    leftSlic = CubeFlagService.FromFacePosition(leftFac.Position);
                }
                else
                {
                    SolverMove(leftSlic, true);
                }

                while (c.Faces.First(f => f.Color == Rubik.BottomColor).Position != FacePosition.Bottom)
                {
                    if (c.Faces.First(f => f.Color == Rubik.BottomColor).Position == FacePosition.Top)
                    {
                        SolverAlgorithm("{0}' U U {0} U", CubeFlagService.ToNotationString(leftSlic));
                    }
                    else
                    {
                        Face frontFac =
                            c.Faces.First(f =>
                                          f.Position != FacePosition.Top &&
                                          f.Position != FacePosition.Bottom &&
                                          f.Color != Color.Black &&
                                          f.Position != CubeFlagService.ToFacePosition(leftSlic)
                                          );

                        var thingA = c.Faces.First(f => f.Color == Rubik.BottomColor).Position == frontFac.Position;
                        var thingB = !c.Position.HasFlag(CubeFlag.BottomLayer);

                        if (thingA && thingB)
                        {
                            SolverAlgorithm("U' {0}' U {0}", CubeFlagService.ToNotationString(leftSlic));
                        }
                        else
                        {
                            SolverAlgorithm("{0}' U' {0} U", CubeFlagService.ToNotationString(leftSlic));
                        }
                    }
                }

                solvedBottomCorners =
                    bottomCorners.Where(bC =>
                                        bC.Position.Flags == GetTargetFlags(bC) &&
                                        bC.Faces.First(f => f.Color == Rubik.BottomColor).Position == FacePosition.Bottom
                                        );
            }
        }
        /// <summary>
        /// Detection and execution of mouse-controlled layer rotations
        /// </summary>
        protected override void OnMouseClick(MouseEventArgs e)
        {
            if (this.MouseHandling)
            {
                if (e.Button == System.Windows.Forms.MouseButtons.Left)
                {
                    if (_oldSelection.IsDefault)
                    {
                        if (_currentSelection.IsDefault)
                        {
                            _selections.Reset();
                            _oldSelection     = PositionSpec.Default;
                            _currentSelection = PositionSpec.Default;
                        }
                        else
                        {
                            if (!CubePosition.IsCorner(_currentSelection.CubePosition))
                            {
                                _oldSelection = _currentSelection;
                                this.Rubik.Cubes.ForEach(c => c.Faces.Where(f => f.Color != Color.Black).ToList().ForEach(f =>
                                {
                                    PositionSpec pos = new PositionSpec()
                                    {
                                        CubePosition = c.Position.Flags, FacePosition = f.Position
                                    };

                                    if (_currentSelection.CubePosition != c.Position.Flags && !CubePosition.IsCenter(c.Position.Flags) && _currentSelection.FacePosition == f.Position)
                                    {
                                        CubeFlag assocLayer  = CubeFlagService.FromFacePosition(_currentSelection.FacePosition);
                                        CubeFlag commonLayer = CubeFlagService.GetFirstNotInvalidCommonFlag(_currentSelection.CubePosition, c.Position.Flags, assocLayer);

                                        if (commonLayer != CubeFlag.None && c.Position.HasFlag(commonLayer))
                                        {
                                            _selections[pos] |= Selection.Possible;
                                        }
                                        else
                                        {
                                            _selections[pos] |= Selection.NotPossible;
                                        }
                                    }
                                    else
                                    {
                                        _selections[pos] |= Selection.NotPossible;
                                    }
                                }));
                                this.State = string.Format("First selection [{0}] | {1}", _currentSelection.CubePosition, _currentSelection.FacePosition);
                            }
                            else
                            {
                                _selections.Reset();
                                this.State = "Error: Invalid first selection, must not be a corner";
                            }
                        }
                    }
                    else
                    {
                        if (_currentSelection.IsDefault)
                        {
                            this.State = "Ready";
                        }
                        else
                        {
                            if (_currentSelection.CubePosition != _oldSelection.CubePosition)
                            {
                                if (!CubePosition.IsCenter(_currentSelection.CubePosition))
                                {
                                    if (_oldSelection.FacePosition == _currentSelection.FacePosition)
                                    {
                                        CubeFlag assocLayer  = CubeFlagService.FromFacePosition(_oldSelection.FacePosition);
                                        CubeFlag commonLayer = CubeFlagService.GetFirstNotInvalidCommonFlag(_oldSelection.CubePosition, _currentSelection.CubePosition, assocLayer);
                                        bool     direction   = true;

                                        if (commonLayer == CubeFlag.TopLayer || commonLayer == CubeFlag.MiddleLayer || commonLayer == CubeFlag.BottomLayer)
                                        {
                                            if (((_oldSelection.FacePosition == FacePosition.Back) && _currentSelection.CubePosition.HasFlag(CubeFlag.RightSlice)) ||
                                                ((_oldSelection.FacePosition == FacePosition.Left) && _currentSelection.CubePosition.HasFlag(CubeFlag.BackSlice)) ||
                                                ((_oldSelection.FacePosition == FacePosition.Front) && _currentSelection.CubePosition.HasFlag(CubeFlag.LeftSlice)) ||
                                                ((_oldSelection.FacePosition == FacePosition.Right) && _currentSelection.CubePosition.HasFlag(CubeFlag.FrontSlice)))
                                            {
                                                direction = false;
                                            }
                                            if (commonLayer == CubeFlag.TopLayer || commonLayer == CubeFlag.MiddleLayer)
                                            {
                                                direction = !direction;
                                            }
                                        }

                                        if (commonLayer == CubeFlag.LeftSlice || commonLayer == CubeFlag.MiddleSliceSides || commonLayer == CubeFlag.RightSlice)
                                        {
                                            if (((_oldSelection.FacePosition == FacePosition.Bottom) && _currentSelection.CubePosition.HasFlag(CubeFlag.BackSlice)) ||
                                                ((_oldSelection.FacePosition == FacePosition.Back) && _currentSelection.CubePosition.HasFlag(CubeFlag.TopLayer)) ||
                                                ((_oldSelection.FacePosition == FacePosition.Top) && _currentSelection.CubePosition.HasFlag(CubeFlag.FrontSlice)) ||
                                                ((_oldSelection.FacePosition == FacePosition.Front) && _currentSelection.CubePosition.HasFlag(CubeFlag.BottomLayer)))
                                            {
                                                direction = false;
                                            }
                                            if (commonLayer == CubeFlag.LeftSlice)
                                            {
                                                direction = !direction;
                                            }
                                        }

                                        if (commonLayer == CubeFlag.BackSlice || commonLayer == CubeFlag.MiddleSlice || commonLayer == CubeFlag.FrontSlice)
                                        {
                                            if (((_oldSelection.FacePosition == FacePosition.Top) && _currentSelection.CubePosition.HasFlag(CubeFlag.RightSlice)) ||
                                                ((_oldSelection.FacePosition == FacePosition.Right) && _currentSelection.CubePosition.HasFlag(CubeFlag.BottomLayer)) ||
                                                ((_oldSelection.FacePosition == FacePosition.Bottom) && _currentSelection.CubePosition.HasFlag(CubeFlag.LeftSlice)) ||
                                                ((_oldSelection.FacePosition == FacePosition.Left) && _currentSelection.CubePosition.HasFlag(CubeFlag.TopLayer)))
                                            {
                                                direction = false;
                                            }
                                            if (commonLayer == CubeFlag.FrontSlice || commonLayer == CubeFlag.MiddleSlice)
                                            {
                                                direction = !direction;
                                            }
                                        }

                                        if (commonLayer != CubeFlag.None)
                                        {
                                            RotateLayerAnimated(commonLayer, direction);
                                        }
                                        else
                                        {
                                            this.State = "Error: Invalid second selection, does not specify distinct layer";
                                        }
                                    }
                                    else
                                    {
                                        this.State = "Error: Invalid second selection, must match orientation of first selection";
                                    }
                                }
                                else
                                {
                                    this.State = "Error: Invalid second selection, must not be a center";
                                }
                            }
                            else
                            {
                                this.State = "Error: Invalid second selection, must not be first selection";
                            }
                        }
                        _selections.Reset();
                        _oldSelection     = PositionSpec.Default;
                        _currentSelection = PositionSpec.Default;
                    }
                }
            }

            base.OnMouseClick(e);
        }
Exemplo n.º 15
0
        public PositionSpec Render2D(Graphics g, IEnumerable <Face3D> frame, Point mousePos)
        {
            g.SmoothingMode = SmoothingMode.AntiAlias;
            PositionSpec pos = PositionSpec.Default;

            int square = 0, borderX = 5, borderY = 5;

            if (((double)(this.Screen.Width - 10) / (double)(this.Screen.Height - 10)) > (4.0 / 3.0))
            {
                square  = (int)(this.Screen.Height / 9.0);
                borderX = (this.Screen.Width - 12 * square) / 2;
            }
            else
            {
                square  = (int)(this.Screen.Width / 12.0);
                borderY = (this.Screen.Height - 9 * square) / 2;
            }

            List <Face3D> faces = new List <Face3D>();

            foreach (Cube c in this.Rubik.Cubes)
            {
                faces.AddRange(c.Faces.Where(f => c.Position.Flags.HasFlag(CubeFlagService.FromFacePosition(f.Position))).Select(f => new Face3D(null, f.Color, f.Position, c.Position.Flags)));
            }
            frame = faces;

            foreach (Face3D face in frame)
            {
                #region CalculatePoints

                int x = 0, y = 0;
                int xOffs = borderX, yOffs = borderY;

                if (face.Position.HasFlag(FacePosition.Front))
                {
                    xOffs += 3 * square; yOffs += 3 * square;
                    CubePosition cubePos = new CubePosition(face.MasterPosition);
                    x = xOffs + (CubeFlagService.ToInt(cubePos.X) + 1) * square;
                    y = yOffs + (CubeFlagService.ToInt(cubePos.Y) * (-1) + 1) * square;
                }

                if (face.Position.HasFlag(FacePosition.Top))
                {
                    xOffs += 3 * square;
                    CubePosition cubePos = new CubePosition(face.MasterPosition);
                    x = xOffs + (CubeFlagService.ToInt(cubePos.X) + 1) * square;
                    y = yOffs + (CubeFlagService.ToInt(cubePos.Z) + 1) * square;
                }

                if (face.Position.HasFlag(FacePosition.Bottom))
                {
                    xOffs += 3 * square; yOffs += 6 * square;
                    CubePosition cubePos = new CubePosition(face.MasterPosition);
                    x = xOffs + (CubeFlagService.ToInt(cubePos.X) + 1) * square;
                    y = yOffs + (CubeFlagService.ToInt(cubePos.Z) * (-1) + 1) * square;
                }

                if (face.Position.HasFlag(FacePosition.Left))
                {
                    yOffs += 3 * square;
                    CubePosition cubePos = new CubePosition(face.MasterPosition);
                    x = xOffs + (CubeFlagService.ToInt(cubePos.Z) + 1) * square;
                    y = yOffs + (CubeFlagService.ToInt(cubePos.Y) * (-1) + 1) * square;
                }

                if (face.Position.HasFlag(FacePosition.Right))
                {
                    xOffs += 6 * square; yOffs += 3 * square;
                    CubePosition cubePos = new CubePosition(face.MasterPosition);
                    x = xOffs + (CubeFlagService.ToInt(cubePos.Z) * (-1) + 1) * square;
                    y = yOffs + (CubeFlagService.ToInt(cubePos.Y) * (-1) + 1) * square;
                }

                if (face.Position.HasFlag(FacePosition.Back))
                {
                    xOffs += 9 * square; yOffs += 3 * square;
                    CubePosition cubePos = new CubePosition(face.MasterPosition);
                    x = xOffs + (CubeFlagService.ToInt(cubePos.X) * (-1) + 1) * square;
                    y = yOffs + (CubeFlagService.ToInt(cubePos.Y) * (-1) + 1) * square;
                }
                #endregion

                Point[] parr = new Point[] { new Point(x, y), new Point(x, y + square), new Point(x + square, y + square), new Point(x + square, y) };

                Brush        b       = new SolidBrush(face.Color);
                double       factor  = ((Math.Sin((double)Environment.TickCount / (double)200) + 1) / 4) + 0.75;
                PositionSpec facePos = new PositionSpec()
                {
                    FacePosition = face.Position, CubePosition = face.MasterPosition
                };

                if (this.MouseHandling)
                {
                    if (_selections[facePos].HasFlag(Selection.Second))
                    {
                        b = new HatchBrush(HatchStyle.Percent75, Color.Black, face.Color);
                    }
                    else if (_selections[facePos].HasFlag(Selection.NotPossible))
                    {
                        b = new SolidBrush(Color.FromArgb(face.Color.A, (int)(face.Color.R * 0.3), (int)(face.Color.G * 0.3), (int)(face.Color.B * 0.3)));
                    }
                    else if (_selections[facePos].HasFlag(Selection.First))
                    {
                        b = new HatchBrush(HatchStyle.Percent30, Color.Black, face.Color);
                    }
                    else if (_selections[facePos].HasFlag(Selection.Possible))
                    {
                        b = new SolidBrush(Color.FromArgb(face.Color.A, (int)(Math.Min(face.Color.R * factor, 255)), (int)(Math.Min(face.Color.G * factor, 255)), (int)(Math.Min(face.Color.B * factor, 255))));
                    }
                    else
                    {
                        b = new SolidBrush(face.Color);
                    }
                }
                else
                {
                    b = new SolidBrush(face.Color);
                }

                g.FillPolygon(b, parr);
                g.DrawPolygon(new Pen(Color.Black, 1), parr);


                GraphicsPath gp = new GraphicsPath();
                gp.AddPolygon(parr);
                if (gp.IsVisible(mousePos))
                {
                    pos = facePos;
                }
            }

            g.DrawRectangle(Pens.Black, 0, this.Height - 25, this.Width - 1, 24);
            //g.DrawLine(Pens.Black, 0, this.Height - 25, this.Width, this.Height - 25);
            g.DrawString(string.Format("[{0}] | {1}", _currentSelection.CubePosition, _currentSelection.FacePosition), this.Font, Brushes.Black, 5, this.Height - 20);

            g.DrawRectangle(Pens.Black, 0, this.Height - 50, this.Width - 1, 25);
            g.DrawString(this.State, this.Font, Brushes.Black, 5, this.Height - 45);

            g.DrawRectangle(Pens.Black, 0, 0, this.Width - 1, this.Height - 50);

            return(pos);
        }
Exemplo n.º 16
0
        private void InitPatterns(CubeFlag r, CubeFlag f)
        {
            CubeFlag l    = CubeFlagService.GetOppositeFlag(r);
            CubeFlag b    = CubeFlagService.GetOppositeFlag(f);
            bool     rIsX = CubeFlagService.IsXFlag(r);

            // edge orientation changes depending on the target slot
            Orientation correct = (r == CubeFlag.BackSlice && f == CubeFlag.RightSlice) || (f == CubeFlag.LeftSlice && r == CubeFlag.FrontSlice)
        ? Orientation.Correct : Orientation.Clockwise;
            Orientation clockwise = correct == Orientation.Correct ? Orientation.Clockwise : Orientation.Correct;

            patterns = new Dictionary <Pattern, Algorithm>()
            {
                #region Corner correct oriented at targetposition
                {
                    new Pattern(new List <PatternItem>()
                    {
                        new PatternItem(new CubePosition(CubeFlag.TopLayer | f | (rIsX ? CubeFlag.MiddleSliceSides : CubeFlag.MiddleSlice)), correct, EdgeTargetPos),
                        new PatternItem(new CubePosition(CornerTargetPos), Orientation.Correct, CornerTargetPos)
                    }),
                    new Algorithm("U {0} U {0}' U' {1}' U' {1}", CubeFlagService.ToNotationString(r), CubeFlagService.ToNotationString(f))
                },
                {
                    new Pattern(new List <PatternItem>()
                    {
                        new PatternItem(new CubePosition(CubeFlag.TopLayer | r | (!rIsX ? CubeFlag.MiddleSliceSides : CubeFlag.MiddleSlice)), clockwise, EdgeTargetPos),
                        new PatternItem(new CubePosition(CornerTargetPos), Orientation.Correct, CornerTargetPos)
                    }),
                    new Algorithm("U' {1}' U' {1} U {0} U {0}'", CubeFlagService.ToNotationString(r), CubeFlagService.ToNotationString(f))
                },
                {
                    new Pattern(new List <PatternItem>()
                    {
                        new PatternItem(new CubePosition(EdgeTargetPos), Orientation.Clockwise, EdgeTargetPos),
                        new PatternItem(new CubePosition(CornerTargetPos), Orientation.Correct, CornerTargetPos)
                    }),
                    new Algorithm("{0}2 U2 {1} {0}2 {1}' U2 {0}' U {0}'", CubeFlagService.ToNotationString(r), CubeFlagService.ToNotationString(f))
                },
                #endregion

                #region Corner clockwise oriented at target position
                {
                    new Pattern(new List <PatternItem>()
                    {
                        new PatternItem(new CubePosition(CubeFlag.TopLayer | f | (rIsX ? CubeFlag.MiddleSliceSides : CubeFlag.MiddleSlice)), correct, EdgeTargetPos),
                        new PatternItem(new CubePosition(CornerTargetPos), Orientation.CounterClockwise, CornerTargetPos)
                    }),
                    new Algorithm("{0}' U {0} U' {0}' U {0}", CubeFlagService.ToNotationString(f))
                },
                {
                    new Pattern(new List <PatternItem>()
                    {
                        new PatternItem(new CubePosition(CubeFlag.TopLayer | r | (!rIsX ? CubeFlag.MiddleSliceSides : CubeFlag.MiddleSlice)), clockwise, EdgeTargetPos),
                        new PatternItem(new CubePosition(CornerTargetPos), Orientation.CounterClockwise, CornerTargetPos)
                    }),
                    new Algorithm("{0} U {0}' U' {0} U {0}'", CubeFlagService.ToNotationString(r))
                },
                {
                    new Pattern(new List <PatternItem>()
                    {
                        new PatternItem(new CubePosition(EdgeTargetPos), Orientation.Correct, EdgeTargetPos),
                        new PatternItem(new CubePosition(CornerTargetPos), Orientation.CounterClockwise, CornerTargetPos)
                    }),
                    new Algorithm("{0} U2 {0} U {0}' U {0} U2 {0}2", CubeFlagService.ToNotationString(r))
                },
                {
                    new Pattern(new List <PatternItem>()
                    {
                        new PatternItem(new CubePosition(EdgeTargetPos), Orientation.Clockwise, EdgeTargetPos),
                        new PatternItem(new CubePosition(CornerTargetPos), Orientation.CounterClockwise, CornerTargetPos)
                    }),
                    new Algorithm("{0} U {0}' U' {0} U' {0}' U2 {1}' U' {1}", CubeFlagService.ToNotationString(r), CubeFlagService.ToNotationString(f))
                },
                #endregion

                #region Corner counter-clockwise oriented at target position
                {
                    new Pattern(new List <PatternItem>()
                    {
                        new PatternItem(new CubePosition(CubeFlag.TopLayer | f | (rIsX ? CubeFlag.MiddleSliceSides : CubeFlag.MiddleSlice)), correct, EdgeTargetPos),
                        new PatternItem(new CubePosition(CornerTargetPos), Orientation.Clockwise, CornerTargetPos)
                    }),
                    new Algorithm("{0}' U' {0} U {0}' U' {0}", CubeFlagService.ToNotationString(f))
                },
                {
                    new Pattern(new List <PatternItem>()
                    {
                        new PatternItem(new CubePosition(CubeFlag.TopLayer | r | (!rIsX ? CubeFlag.MiddleSliceSides : CubeFlag.MiddleSlice)), clockwise, EdgeTargetPos),
                        new PatternItem(new CubePosition(CornerTargetPos), Orientation.Clockwise, CornerTargetPos)
                    }),
                    new Algorithm("{0} U' {0}' U {0} U' {0}'", CubeFlagService.ToNotationString(r))
                },
                {
                    new Pattern(new List <PatternItem>()
                    {
                        new PatternItem(new CubePosition(EdgeTargetPos), Orientation.Correct, EdgeTargetPos),
                        new PatternItem(new CubePosition(CornerTargetPos), Orientation.Clockwise, CornerTargetPos)
                    }),
                    new Algorithm("{0}' U' {0} U2 {0}' U {0} U' {0}' U' {0}", CubeFlagService.ToNotationString(f))
                },
                {
                    new Pattern(new List <PatternItem>()
                    {
                        new PatternItem(new CubePosition(EdgeTargetPos), Orientation.Clockwise, EdgeTargetPos),
                        new PatternItem(new CubePosition(CornerTargetPos), Orientation.Clockwise, CornerTargetPos)
                    }),
                    new Algorithm("{1}' U' {1} U {1}' U {1} U2 {0} U {0}'", CubeFlagService.ToNotationString(r), CubeFlagService.ToNotationString(f))
                },
                #endregion

                #region Corner correct oriented in top layer
                {
                    new Pattern(new List <PatternItem>()
                    {
                        new PatternItem(new CubePosition(EdgeTargetPos), Orientation.Correct, EdgeTargetPos),
                        new PatternItem(new CubePosition(CornerTargetPos & ~CubeFlag.BottomLayer | CubeFlag.TopLayer), Orientation.Correct, CornerTargetPos)
                    }),
                    new Algorithm("{0} U {0}' U' {0} U {0}' U' {0} U {0}'", CubeFlagService.ToNotationString(r))
                },
                {
                    new Pattern(new List <PatternItem>()
                    {
                        new PatternItem(new CubePosition(EdgeTargetPos), Orientation.Clockwise, EdgeTargetPos),
                        new PatternItem(new CubePosition(CornerTargetPos & ~CubeFlag.BottomLayer | CubeFlag.TopLayer), Orientation.Correct, CornerTargetPos)
                    }),
                    new Algorithm("{0} U' {0}' U {1}' U {1}", CubeFlagService.ToNotationString(r), CubeFlagService.ToNotationString(f))
                },
                {
                    new Pattern(new List <PatternItem>()
                    {
                        new PatternItem(new CubePosition(CubeFlag.TopLayer | (rIsX ? CubeFlag.MiddleSliceSides : CubeFlag.MiddleSlice) | b), clockwise, EdgeTargetPos),
                        new PatternItem(new CubePosition(CornerTargetPos & ~CubeFlag.BottomLayer | CubeFlag.TopLayer), Orientation.Correct, CornerTargetPos)
                    }),
                    new Algorithm("U {0} U2 {0}' U {0} U' {0}'", CubeFlagService.ToNotationString(r))
                },
                {
                    new Pattern(new List <PatternItem>()
                    {
                        new PatternItem(new CubePosition(CubeFlag.TopLayer | (rIsX ? CubeFlag.MiddleSliceSides : CubeFlag.MiddleSlice) | b), correct, EdgeTargetPos),
                        new PatternItem(new CubePosition(CornerTargetPos & ~CubeFlag.BottomLayer | CubeFlag.TopLayer), Orientation.Correct, CornerTargetPos)
                    }),
                    new Algorithm("{0}' U {0} U2 {0}' U' {0}", CubeFlagService.ToNotationString(f))
                },
                {
                    new Pattern(new List <PatternItem>()
                    {
                        new PatternItem(new CubePosition(CubeFlag.TopLayer | (!rIsX ? CubeFlag.MiddleSliceSides : CubeFlag.MiddleSlice) | l), clockwise, EdgeTargetPos),
                        new PatternItem(new CubePosition(CornerTargetPos & ~CubeFlag.BottomLayer | CubeFlag.TopLayer), Orientation.Correct, CornerTargetPos)
                    }),
                    new Algorithm("{0} U' {0}' U2 {0} U {0}'", CubeFlagService.ToNotationString(r))
                },
                {
                    new Pattern(new List <PatternItem>()
                    {
                        new PatternItem(new CubePosition(CubeFlag.TopLayer | (!rIsX ? CubeFlag.MiddleSliceSides : CubeFlag.MiddleSlice) | l), correct, EdgeTargetPos),
                        new PatternItem(new CubePosition(CornerTargetPos & ~CubeFlag.BottomLayer | CubeFlag.TopLayer), Orientation.Correct, CornerTargetPos)
                    }),
                    new Algorithm("U' {0}' U2 {0} U' {0}' U {0}", CubeFlagService.ToNotationString(f))
                },
                {
                    new Pattern(new List <PatternItem>()
                    {
                        new PatternItem(new CubePosition(CubeFlag.TopLayer | (rIsX ? CubeFlag.MiddleSliceSides : CubeFlag.MiddleSlice) | f), correct, EdgeTargetPos),
                        new PatternItem(new CubePosition(CornerTargetPos & ~CubeFlag.BottomLayer | CubeFlag.TopLayer), Orientation.Correct, CornerTargetPos)
                    }),
                    new Algorithm("{0}' U2 {0} U {0}' U' {0}", CubeFlagService.ToNotationString(f))
                },
                {
                    new Pattern(new List <PatternItem>()
                    {
                        new PatternItem(new CubePosition(CubeFlag.TopLayer | (rIsX ? CubeFlag.MiddleSliceSides : CubeFlag.MiddleSlice) | f), clockwise, EdgeTargetPos),
                        new PatternItem(new CubePosition(CornerTargetPos & ~CubeFlag.BottomLayer | CubeFlag.TopLayer), Orientation.Correct, CornerTargetPos)
                    }),
                    new Algorithm("{0}' U' {1}' U {1} {0} {1}' U {1}", CubeFlagService.ToNotationString(r), CubeFlagService.ToNotationString(f))
                },
                {
                    new Pattern(new List <PatternItem>()
                    {
                        new PatternItem(new CubePosition(CubeFlag.TopLayer | (!rIsX ? CubeFlag.MiddleSliceSides : CubeFlag.MiddleSlice) | r), correct, EdgeTargetPos),
                        new PatternItem(new CubePosition(CornerTargetPos & ~CubeFlag.BottomLayer | CubeFlag.TopLayer), Orientation.Correct, CornerTargetPos)
                    }),
                    new Algorithm("{0} U2 {0}' U' {0} U {0}'", CubeFlagService.ToNotationString(r))
                },
                {
                    new Pattern(new List <PatternItem>()
                    {
                        new PatternItem(new CubePosition(CubeFlag.TopLayer | (!rIsX ? CubeFlag.MiddleSliceSides : CubeFlag.MiddleSlice) | r), clockwise, EdgeTargetPos),
                        new PatternItem(new CubePosition(CornerTargetPos & ~CubeFlag.BottomLayer | CubeFlag.TopLayer), Orientation.Correct, CornerTargetPos)
                    }),
                    new Algorithm("{0} U {1} U' {1}' {0}' {1} U' {1}'", CubeFlagService.ToNotationString(f), CubeFlagService.ToNotationString(r))
                },
                #endregion

                #region Corner counter-clockwise oriented in top layer
                {
                    new Pattern(new List <PatternItem>()
                    {
                        new PatternItem(new CubePosition(EdgeTargetPos), Orientation.Correct, EdgeTargetPos),
                        new PatternItem(new CubePosition(CornerTargetPos & ~CubeFlag.BottomLayer | CubeFlag.TopLayer), Orientation.CounterClockwise, CornerTargetPos)
                    }),
                    new Algorithm("U' {0} U' {0}' U2 {0} U' {0}'", CubeFlagService.ToNotationString(r))
                },
                {
                    new Pattern(new List <PatternItem>()
                    {
                        new PatternItem(new CubePosition(EdgeTargetPos), Orientation.Clockwise, EdgeTargetPos),
                        new PatternItem(new CubePosition(CornerTargetPos & ~CubeFlag.BottomLayer | CubeFlag.TopLayer), Orientation.CounterClockwise, CornerTargetPos)
                    }),
                    new Algorithm("U' {0} U {0}' U {1}' U' {1}", CubeFlagService.ToNotationString(r), CubeFlagService.ToNotationString(f))
                },
                {
                    new Pattern(new List <PatternItem>()
                    {
                        new PatternItem(new CubePosition(CubeFlag.TopLayer | (!rIsX ? CubeFlag.MiddleSliceSides : CubeFlag.MiddleSlice) | r), clockwise, EdgeTargetPos),
                        new PatternItem(new CubePosition(CornerTargetPos & ~CubeFlag.BottomLayer | CubeFlag.TopLayer), Orientation.CounterClockwise, CornerTargetPos)
                    }),
                    new Algorithm("U {0} U' {0}'", CubeFlagService.ToNotationString(r))
                },
                {
                    new Pattern(new List <PatternItem>()
                    {
                        new PatternItem(new CubePosition(CubeFlag.TopLayer | (!rIsX ? CubeFlag.MiddleSliceSides : CubeFlag.MiddleSlice) | r), correct, EdgeTargetPos),
                        new PatternItem(new CubePosition(CornerTargetPos & ~CubeFlag.BottomLayer | CubeFlag.TopLayer), Orientation.CounterClockwise, CornerTargetPos)
                    }),
                    new Algorithm("{0} U2 {0}2 U' {0}2 U' {0}'", CubeFlagService.ToNotationString(f))
                },
                {
                    new Pattern(new List <PatternItem>()
                    {
                        new PatternItem(new CubePosition(CubeFlag.TopLayer | (rIsX ? CubeFlag.MiddleSliceSides : CubeFlag.MiddleSlice) | b), clockwise, EdgeTargetPos),
                        new PatternItem(new CubePosition(CornerTargetPos & ~CubeFlag.BottomLayer | CubeFlag.TopLayer), Orientation.CounterClockwise, CornerTargetPos)
                    }),
                    new Algorithm("U' {0} U {0}' U2 {0} U' {0}'", CubeFlagService.ToNotationString(r))
                },
                {
                    new Pattern(new List <PatternItem>()
                    {
                        new PatternItem(new CubePosition(CubeFlag.TopLayer | (rIsX ? CubeFlag.MiddleSliceSides : CubeFlag.MiddleSlice) | b), correct, EdgeTargetPos),
                        new PatternItem(new CubePosition(CornerTargetPos & ~CubeFlag.BottomLayer | CubeFlag.TopLayer), Orientation.CounterClockwise, CornerTargetPos)
                    }),
                    new Algorithm("U' {0} U' {0}' U {1}' U' {1}", CubeFlagService.ToNotationString(r), CubeFlagService.ToNotationString(f))
                },
                {
                    new Pattern(new List <PatternItem>()
                    {
                        new PatternItem(new CubePosition(CubeFlag.TopLayer | (!rIsX ? CubeFlag.MiddleSliceSides : CubeFlag.MiddleSlice) | l), correct, EdgeTargetPos),
                        new PatternItem(new CubePosition(CornerTargetPos & ~CubeFlag.BottomLayer | CubeFlag.TopLayer), Orientation.CounterClockwise, CornerTargetPos)
                    }),
                    new Algorithm("{0}' U' {0}", CubeFlagService.ToNotationString(f))
                },
                {
                    new Pattern(new List <PatternItem>()
                    {
                        new PatternItem(new CubePosition(CubeFlag.TopLayer | (!rIsX ? CubeFlag.MiddleSliceSides : CubeFlag.MiddleSlice) | l), clockwise, EdgeTargetPos),
                        new PatternItem(new CubePosition(CornerTargetPos & ~CubeFlag.BottomLayer | CubeFlag.TopLayer), Orientation.CounterClockwise, CornerTargetPos)
                    }),
                    new Algorithm("U' {0} U2 {0}' U2 {0} U' {0}'", CubeFlagService.ToNotationString(r))
                },
                {
                    new Pattern(new List <PatternItem>()
                    {
                        new PatternItem(new CubePosition(CubeFlag.TopLayer | (rIsX ? CubeFlag.MiddleSliceSides : CubeFlag.MiddleSlice) | f), correct, EdgeTargetPos),
                        new PatternItem(new CubePosition(CornerTargetPos & ~CubeFlag.BottomLayer | CubeFlag.TopLayer), Orientation.CounterClockwise, CornerTargetPos)
                    }),
                    new Algorithm("d {0}' U {0} U' {0}' U' {0}", CubeFlagService.ToNotationString(r))
                },
                {
                    new Pattern(new List <PatternItem>()
                    {
                        new PatternItem(new CubePosition(CubeFlag.TopLayer | (rIsX ? CubeFlag.MiddleSliceSides : CubeFlag.MiddleSlice) | f), clockwise, EdgeTargetPos),
                        new PatternItem(new CubePosition(CornerTargetPos & ~CubeFlag.BottomLayer | CubeFlag.TopLayer), Orientation.CounterClockwise, CornerTargetPos)
                    }),
                    new Algorithm("{0}' U {0} U2 {1} U {1}'", CubeFlagService.ToNotationString(f), CubeFlagService.ToNotationString(r))
                },
                #endregion

                #region Corner clockwise oriented in top layer
                {
                    new Pattern(new List <PatternItem>()
                    {
                        new PatternItem(new CubePosition(EdgeTargetPos), Orientation.Correct, EdgeTargetPos),
                        new PatternItem(new CubePosition(CornerTargetPos & ~CubeFlag.BottomLayer | CubeFlag.TopLayer), Orientation.Clockwise, CornerTargetPos)
                    }),
                    new Algorithm("U {0} U {0}' U2 {0} U {0}'", CubeFlagService.ToNotationString(r))
                },
                {
                    new Pattern(new List <PatternItem>()
                    {
                        new PatternItem(new CubePosition(EdgeTargetPos), Orientation.Clockwise, EdgeTargetPos),
                        new PatternItem(new CubePosition(CornerTargetPos & ~CubeFlag.BottomLayer | CubeFlag.TopLayer), Orientation.Clockwise, CornerTargetPos)
                    }),
                    new Algorithm("U2 {1}' U {1} U {0} U {0}'", CubeFlagService.ToNotationString(r), CubeFlagService.ToNotationString(f))
                },
                {
                    new Pattern(new List <PatternItem>()
                    {
                        new PatternItem(new CubePosition(CubeFlag.TopLayer | (!rIsX ? CubeFlag.MiddleSliceSides : CubeFlag.MiddleSlice) | r), clockwise, EdgeTargetPos),
                        new PatternItem(new CubePosition(CornerTargetPos & ~CubeFlag.BottomLayer | CubeFlag.TopLayer), Orientation.Clockwise, CornerTargetPos)
                    }),
                    new Algorithm("U' {0} U' {0}' U {0} U {0}'", CubeFlagService.ToNotationString(r))
                },
                {
                    new Pattern(new List <PatternItem>()
                    {
                        new PatternItem(new CubePosition(CubeFlag.TopLayer | (!rIsX ? CubeFlag.MiddleSliceSides : CubeFlag.MiddleSlice) | r), correct, EdgeTargetPos),
                        new PatternItem(new CubePosition(CornerTargetPos & ~CubeFlag.BottomLayer | CubeFlag.TopLayer), Orientation.Clockwise, CornerTargetPos)
                    }),
                    new Algorithm("{1} U' {1}' U2 {0}' U' {0}", CubeFlagService.ToNotationString(f), CubeFlagService.ToNotationString(r))
                },
                {
                    new Pattern(new List <PatternItem>()
                    {
                        new PatternItem(new CubePosition(CubeFlag.TopLayer | (rIsX ? CubeFlag.MiddleSliceSides : CubeFlag.MiddleSlice) | b), correct, EdgeTargetPos),
                        new PatternItem(new CubePosition(CornerTargetPos & ~CubeFlag.BottomLayer | CubeFlag.TopLayer), Orientation.Clockwise, CornerTargetPos)
                    }),
                    new Algorithm("d {0}' U2 {0} U2 {0}' U {0}", CubeFlagService.ToNotationString(r))
                },
                {
                    new Pattern(new List <PatternItem>()
                    {
                        new PatternItem(new CubePosition(CubeFlag.TopLayer | (rIsX ? CubeFlag.MiddleSliceSides : CubeFlag.MiddleSlice) | b), clockwise, EdgeTargetPos),
                        new PatternItem(new CubePosition(CornerTargetPos & ~CubeFlag.BottomLayer | CubeFlag.TopLayer), Orientation.Clockwise, CornerTargetPos)
                    }),
                    new Algorithm("{0} U {0}'", CubeFlagService.ToNotationString(r))
                },
                {
                    new Pattern(new List <PatternItem>()
                    {
                        new PatternItem(new CubePosition(CubeFlag.TopLayer | (!rIsX ? CubeFlag.MiddleSliceSides : CubeFlag.MiddleSlice) | l), correct, EdgeTargetPos),
                        new PatternItem(new CubePosition(CornerTargetPos & ~CubeFlag.BottomLayer | CubeFlag.TopLayer), Orientation.Clockwise, CornerTargetPos)
                    }),
                    new Algorithm("d {0}' U' {0} U2 {0}' U {0}", CubeFlagService.ToNotationString(r))
                },
                {
                    new Pattern(new List <PatternItem>()
                    {
                        new PatternItem(new CubePosition(CubeFlag.TopLayer | (!rIsX ? CubeFlag.MiddleSliceSides : CubeFlag.MiddleSlice) | l), clockwise, EdgeTargetPos),
                        new PatternItem(new CubePosition(CornerTargetPos & ~CubeFlag.BottomLayer | CubeFlag.TopLayer), Orientation.Clockwise, CornerTargetPos)
                    }),
                    new Algorithm("d {0}' U {0} d' {0} U {0}'", CubeFlagService.ToNotationString(r))
                },
                {
                    new Pattern(new List <PatternItem>()
                    {
                        new PatternItem(new CubePosition(CubeFlag.TopLayer | (rIsX ? CubeFlag.MiddleSliceSides : CubeFlag.MiddleSlice) | f), clockwise, EdgeTargetPos),
                        new PatternItem(new CubePosition(CornerTargetPos & ~CubeFlag.BottomLayer | CubeFlag.TopLayer), Orientation.Clockwise, CornerTargetPos)
                    }),
                    new Algorithm("{0}' U2 {0}2 U {0}2 U {0}", CubeFlagService.ToNotationString(r))
                },
                {
                    new Pattern(new List <PatternItem>()
                    {
                        new PatternItem(new CubePosition(CubeFlag.TopLayer | (rIsX ? CubeFlag.MiddleSliceSides : CubeFlag.MiddleSlice) | f), correct, EdgeTargetPos),
                        new PatternItem(new CubePosition(CornerTargetPos & ~CubeFlag.BottomLayer | CubeFlag.TopLayer), Orientation.Clockwise, CornerTargetPos)
                    }),
                    new Algorithm("U' {0}' U {0}", CubeFlagService.ToNotationString(f))
                }
                #endregion
            };
        }
Exemplo n.º 17
0
        // **** METHODS ****

        public static Rubik FromPattern(Pattern pattern)
        {
            Rubik rubik = new Rubik();

            foreach (PatternItem item in pattern.Items)
            {
                if (CubePosition.IsCorner(item.CurrentPosition.Flags))
                {
                    bool xyzCorrect = !((item.CurrentPosition.Y == CubeFlag.TopLayer ^ (item.CurrentPosition.X == CubeFlag.RightSlice ^ item.CurrentPosition.Z == CubeFlag.FrontSlice))
                                        ^ (CubeFlagService.FirstYFlag(item.TargetPosition) == CubeFlag.TopLayer ^ (CubeFlagService.FirstXFlag(item.TargetPosition) == CubeFlag.RightSlice ^ CubeFlagService.FirstZFlag(item.TargetPosition) == CubeFlag.FrontSlice)));

                    if (item.CurrentOrientation == Orientation.Correct)
                    {
                        rubik.SetFaceColor(item.CurrentPosition.Flags, CubeFlagService.ToFacePosition(item.CurrentPosition.Y), rubik.GetSliceColor(CubeFlagService.FirstYFlag(item.TargetPosition)));

                        FacePosition x = xyzCorrect ? CubeFlagService.ToFacePosition(item.CurrentPosition.X) : CubeFlagService.ToFacePosition(item.CurrentPosition.Z);
                        FacePosition z = xyzCorrect ? CubeFlagService.ToFacePosition(item.CurrentPosition.Z) : CubeFlagService.ToFacePosition(item.CurrentPosition.X);

                        rubik.SetFaceColor(item.CurrentPosition.Flags, x, rubik.GetSliceColor(CubeFlagService.FirstXFlag(item.TargetPosition)));
                        rubik.SetFaceColor(item.CurrentPosition.Flags, z, rubik.GetSliceColor(CubeFlagService.FirstZFlag(item.TargetPosition)));
                    }
                    else
                    {
                        bool         corr = (item.CurrentPosition.X == CubeFlag.RightSlice ^ item.CurrentPosition.Z == CubeFlag.BackSlice) ^ item.CurrentPosition.Y == CubeFlag.BottomLayer;
                        FacePosition x    = (corr ^ item.CurrentOrientation == Orientation.Clockwise) ? CubeFlagService.ToFacePosition(item.CurrentPosition.X) : CubeFlagService.ToFacePosition(item.CurrentPosition.Y);
                        FacePosition y    = (corr ^ item.CurrentOrientation == Orientation.Clockwise) ? CubeFlagService.ToFacePosition(item.CurrentPosition.Z) : CubeFlagService.ToFacePosition(item.CurrentPosition.X);
                        FacePosition z    = (corr ^ item.CurrentOrientation == Orientation.Clockwise) ? CubeFlagService.ToFacePosition(item.CurrentPosition.Y) : CubeFlagService.ToFacePosition(item.CurrentPosition.Z);

                        rubik.SetFaceColor(item.CurrentPosition.Flags, x, rubik.GetSliceColor(CubeFlagService.FirstXFlag(item.TargetPosition)));
                        rubik.SetFaceColor(item.CurrentPosition.Flags, y, rubik.GetSliceColor(CubeFlagService.FirstYFlag(item.TargetPosition)));
                        rubik.SetFaceColor(item.CurrentPosition.Flags, z, rubik.GetSliceColor(CubeFlagService.FirstZFlag(item.TargetPosition)));
                    }
                }

                if (CubePosition.IsEdge(item.CurrentPosition.Flags))
                {
                    CubeFlag     flagOne = CubeFlagService.FirstNotInvalidFlag(item.CurrentPosition.Flags, CubeFlag.MiddleLayer | CubeFlag.MiddleSlice | CubeFlag.MiddleSliceSides);
                    FacePosition faceOne = CubeFlagService.ToFacePosition(flagOne);
                    FacePosition faceTwo = CubeFlagService.ToFacePosition(CubeFlagService.FirstNotInvalidFlag(item.CurrentPosition.Flags, CubeFlag.MiddleLayer | CubeFlag.MiddleSlice | CubeFlag.MiddleSliceSides | flagOne));

                    CubeFlag tFlagOne = CubeFlagService.FirstNotInvalidFlag(item.TargetPosition, CubeFlag.MiddleLayer | CubeFlag.MiddleSlice | CubeFlag.MiddleSliceSides);

                    rubik.SetFaceColor(item.CurrentPosition.Flags, faceOne, rubik.GetSliceColor(tFlagOne));
                    rubik.SetFaceColor(item.CurrentPosition.Flags, faceTwo, rubik.GetSliceColor(CubeFlagService.FirstNotInvalidFlag(item.TargetPosition, CubeFlag.MiddleLayer | CubeFlag.MiddleSlice | CubeFlag.MiddleSliceSides | tFlagOne)));

                    if (Solvability.GetOrientation(rubik, rubik.Cubes.First(c => c.Position.Flags == item.CurrentPosition.Flags)) != item.CurrentOrientation)
                    {
                        rubik.SetFaceColor(item.CurrentPosition.Flags, faceTwo, rubik.GetSliceColor(tFlagOne));
                        rubik.SetFaceColor(item.CurrentPosition.Flags, faceOne, rubik.GetSliceColor(CubeFlagService.FirstNotInvalidFlag(item.TargetPosition, CubeFlag.MiddleLayer | CubeFlag.MiddleSlice | CubeFlag.MiddleSliceSides | tFlagOne)));
                    }
                }

                if (CubePosition.IsCenter(item.CurrentPosition.Flags))
                {
                    CubeFlag flag  = CubeFlagService.FirstNotInvalidFlag(item.CurrentPosition.Flags, CubeFlag.MiddleLayer | CubeFlag.MiddleSlice | CubeFlag.MiddleSliceSides);
                    CubeFlag tFlag = CubeFlagService.FirstNotInvalidFlag(item.TargetPosition, CubeFlag.MiddleLayer | CubeFlag.MiddleSlice | CubeFlag.MiddleSliceSides);

                    rubik.SetFaceColor(item.CurrentPosition.Flags, CubeFlagService.ToFacePosition(flag), rubik.GetSliceColor(tFlag));
                }
            }
            return(rubik);
        }