Ejemplo n.º 1
0
        public bool IsMatch(Cube cube)
        {
            for (int f = 0; f < 4; f++)
            {
                CubeFace face = CubeSolver.MiddleLayerFaces[f];

                CubeColor[] tiles =
                {
                    cube.At(face, 6),
                    cube.At(face, 7),
                    cube.At(face, 8)
                };

                int delta0 = SolvingUtility.NormalizeCount(middleLayerColors[tiles[0]] - middleLayerColors[tiles[1]]);
                int delta1 = SolvingUtility.NormalizeCount(middleLayerColors[tiles[0]] - middleLayerColors[tiles[2]]);
                int delta2 = SolvingUtility.NormalizeCount(middleLayerColors[tiles[1]] - middleLayerColors[tiles[2]]);

                if (delta0 != patternData[f][0] || delta1 != patternData[f][1] || delta2 != patternData[f][2])
                {
                    return(false);
                }
            }

            return(true);
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Gibt den Farbunterschied eines weißen Kantensteins zurück
        /// </summary>
        /// <param name="edge">Der Kantenstein, dessen Farbunterschied bestimmt werden soll</param>
        /// <returns></returns>
        protected int GetDelta(EdgeStone edge)
        {
            CubeColor edgeColor = edge.GetColors().First(c => c != WHITE);
            CubeFace  face      = edge.GetColorPosition(c => c != WHITE).Face;

            return(SolvingUtility.GetDelta(edgeColor, face, UP));
        }
Ejemplo n.º 3
0
        private static void FalsePairedDownLayer(FTLPair pair)
        {
            // move corner above right slot
            // 0-2 moves
            Position pos   = pair.Corner.GetPositions().First(p => p.Face == DOWN);
            int      delta = SolvingUtility.GetDelta(cube.At(pos), pair.CornerWhitePosition.Face, DOWN);

            DoMove(DOWN, delta);

            // do algorithm     7-10 moves
            var faceToRot = Cube.GetFace(pair.Corner.GetColor(p => p.Face != DOWN));

            FTLPair secondPair       = pairs.First(p => p.Edge.HasColor(Cube.GetFaceColor(faceToRot)) && p != pair);
            bool    secondPairSolved = secondPair.Solved;

            int direction = pair.CornerWhitePosition.Tile == 6 ? 1 : -1;

            DoMove(faceToRot, direction);
            DoMove(DOWN, 2);
            DoMove(faceToRot, 2);
            DoMove(DOWN, -direction);
            DoMove(faceToRot, -direction);

            if (secondPairSolved)
            {
                DoMove(faceToRot, -direction);
                DoMove(DOWN, -direction);
                DoMove(faceToRot, direction);
            }
        }
Ejemplo n.º 4
0
        private static void CornerDown_YellowSide_EdgeDown(FTLPair pair)
        {
            CubeColor color      = pair.Edge.GetColor(p => p.Face != DOWN);
            CubeFace  targetFace = Cube.GetFace(color);

            while (pair.Edge.GetPosition(p => p.Face != DOWN).Face != targetFace)
            {
                DoMove(DOWN);
            }

            CubeFace faceToRot = pair.Edge.GetPosition(p => p.Face != DOWN).Face;
            int      direction = SolvingUtility.GetDelta(pair.Edge.GetColor(p => p.Face != DOWN),
                                                         faceToRot, DOWN);

            // move edge in right position
            DoMove(faceToRot, direction);
            // pair the stones
            while (pair.Corner.GetColorPosition(color).Face != targetFace)
            {
                DoMove(DOWN);
            }

            DoMove(faceToRot, -direction);

            // handle as right paired
            RightPairedDownLayer(pair);
        }
Ejemplo n.º 5
0
        /// <summary>
        /// Bring einen weißen falsch orientierten Kantenstein auf der mittleren Ebene in die richtige Position relativ zum Pivotstein.
        /// </summary>
        /// <param name="edge">Der Kantenstein, der in die richtige Position gebracht werden soll</param>
        protected void HandleFalseOrientatedStone(EdgeStone edge)
        {
            if (Array.TrueForAll(MiddleLayerFaces, f => edge.GetColorPosition(WHITE).Face != f) || edge.GetColorPosition(WHITE).Tile == 3 || edge.GetColorPosition(WHITE).Tile == 5)
            {
                throw new ArgumentOutOfRangeException("Der weiße Kantenstein muss sich in der oberen oder unteren Ebene befinden und die weiße Fläche muss auf einer der seitlichen Seiten (Orange, Grün, Rot, Blau) sein", nameof(edge));
            }

#if DEBUG
            Log.LogStuff("Handle false orientated stone\r\n\t" + edge.ToString());
#endif

            // get edge information
            CubeColor secndColor = GetSecondColor(edge);
            Position  whitePos   = edge.GetColorPosition(WHITE);

            // get face of white pos
            int middleLayerFaceID = Array.IndexOf(MiddleLayerFaces, whitePos.Face);
            // face in anti clockwise rotation of white position face
            CubeFace leftFace = MiddleLayerFaces[(middleLayerFaceID + 3) % 4];
            // face in clockwise roation of white position face
            CubeFace rightFace = MiddleLayerFaces[(middleLayerFaceID + 1) % 4];

            int leftDelta  = Math.Abs(SolvingUtility.NormalizeCount(SolvingUtility.GetDelta(secndColor, leftFace, UP), -1));
            int rightDelta = Math.Abs(SolvingUtility.NormalizeCount(SolvingUtility.GetDelta(secndColor, rightFace, UP), -1));

            // on up layer
            if (whitePos.Tile == 1)
            {
                // move edge to middle layer
                if (leftDelta < rightDelta)
                {
                    DoMove(whitePos.Face, -1);
                }
                else
                {
                    DoMove(whitePos.Face);
                }
                HandleStoneMiddleLayer(edge);
            }
            else
            {
                // check if the face must rotated back after stone handling
                int[] tiles   = { 3, 7, 5, 1 };
                bool  rotBack = cube.At(UP, tiles[middleLayerFaceID]) == WHITE;

                // move edge to middle layer
                int direction = leftDelta > rightDelta ? 1 : -1;
                DoMove(whitePos.Face, direction);

                HandleStoneMiddleLayer(edge);

                if (rotBack)
                {
                    DoMove(whitePos.Face, -direction);
                }
            }
        }
Ejemplo n.º 6
0
        /// <summary>
        /// Bring einen weißen Kantenstein auf der gelben Seite in die richtige Position relativ zum Pivotstein.
        /// </summary>
        /// <param name="edge">Der Kantenstein, der in die richtige Position gebracht werden soll</param>
        protected void HandleStoneYellowFace(EdgeStone edge)
        {
            if (edge.GetColorPosition(WHITE).Face != DOWN)
            {
                throw new ArgumentException("Die weiße Fläche des Kantensteins muss sich auf der gelben Seite befinden", nameof(edge));
            }

#if DEBUG
            Log.LogStuff("Handle stone yellow face\r\n\t" + edge.ToString());
#endif

            int delta = SolvingUtility.GetDelta(GetSecondColor(edge), edge.GetColorPosition(c => c != WHITE).Face, UP);

            // rotate the white face to insert the stone right to pivot
            DoMove(UP, delta - WhiteFaceOrientation);

            CubeFace faceToRot = edge.GetColorPosition(c => c != WHITE).Face;
            DoMove(faceToRot, 2);
        }
Ejemplo n.º 7
0
        /// <summary>
        /// Bring einen weißen Kantenstein auf der mittleren Ebene in die richtige Position relativ zum Pivotstein.
        /// </summary>
        /// <param name="edge">Der Kantenstein, der in die richtige Position gebracht werden soll</param>
        protected void HandleStoneMiddleLayer(EdgeStone edge)
        {
            if (Array.TrueForAll(MiddleLayerFaces, f => edge.GetColorPosition(WHITE).Face != f) || edge.GetColorPosition(WHITE).Tile == 1 || edge.GetColorPosition(WHITE).Tile == 7)
            {
                throw new ArgumentException("Der weiße Kantenstein muss sich auf der mittleren Ebene befinden", nameof(edge));
            }

#if DEBUG
            Log.LogStuff("Handle stone middle layer\r\n\t" + edge.ToString());
#endif

            int delta = SolvingUtility.GetDelta(GetSecondColor(edge), edge.GetColorPosition(c => c != WHITE).Face, UP);

            // rotate the white face to insert the stone right to pivot
            DoMove(UP, delta - WhiteFaceOrientation);

            Position secondPos = edge.GetColorPosition(c => c != WHITE);
            DoMove(secondPos.Face, secondPos.Tile == 3 ? 1 : -1);
        }
Ejemplo n.º 8
0
        /// <summary>
        /// Gibt die Anzahl der Züge zurück, die benötigt wird, um den Kantenstein in die richtige Position zu bringen.
        /// </summary>
        /// <param name="edge">Der Kantenstein, der in die richtige Position gebracht werden soll</param>
        /// <returns></returns>
        protected int GetStoneRating(EdgeStone edge)
        {
            // on white face and same delta as pivot stone
            if (IsEdgeRight(edge))
            {
                return(0);
            }

            Position whitePosition = edge.GetColorPosition(WHITE);
            int      edgeDelta;

            // on white face and not same delta as pivot stone or on yellow face
            if (whitePosition.Face == UP || whitePosition.Face == DOWN)
            {
                // get delta of edge
                if (whitePosition.Face == DOWN)
                {
                    edgeDelta = SolvingUtility.GetDelta(
                        GetSecondColor(edge),                        // second color
                        edge.GetColorPosition(c => c != WHITE).Face, // second color face color
                        UP);                                         // face to rotate
                }
                else
                {
                    edgeDelta = GetDelta(edge);
                }

                // return 2 + moves white face count
                int sortingMoves = Math.Abs(SolvingUtility.NormalizeCount(edgeDelta - WhiteFaceOrientation, -1));
                return(2 + sortingMoves);
            }
            // on middle layer
            else
            {
                switch (whitePosition.Tile)
                {
                // false orientated on white face
                case 1:
                    edgeDelta = SolvingUtility.GetDelta(
                        GetSecondColor(edge),              //second color
                        edge.GetColorPosition(WHITE).Face, // middle layer face with white side of edge
                        UP);                               //face to rotate
                    int edgePivotDelta = SolvingUtility.NormalizeCount(edgeDelta - WhiteFaceOrientation);

                    // return number of moves
                    return((edgePivotDelta % 2) * -1 + 3);

                // false orientated on yellow face
                case 7:
                    // this position can always solved in 3 moves
                    return(3);

                // on middle layer
                default:
                    edgeDelta = SolvingUtility.GetDelta(
                        edge.GetColors().First(c => c != WHITE),     // second color
                        edge.GetColorPosition(c => c != WHITE).Face, // second color face color
                        UP);                                         // face to rotate
                    int sortingMoves = Math.Abs(SolvingUtility.NormalizeCount(edgeDelta - WhiteFaceOrientation, -1));
                    return(1 + sortingMoves);
                }
            }
        }