예제 #1
0
        public CubieColor this[sbyte a1, sbyte a2, sbyte a3]
        {
            get
            {
                CubiePosition position = new CubiePosition(a1, a2, a3);

                foreach (Cubie cubie in cubies)
                {
                    if (cubie.Position.CompareTo(position) == 0)
                    {
                        return(cubie.Color);
                    }
                }
                throw new ApplicationException(String.Format($"Position {position} not found"));
            }

            set
            {
                CubiePosition position = new CubiePosition(a1, a2, a3);

                for (int i = 0; i < cubies.Count; i++)
                {
                    Cubie cubie = cubies[i];
                    if (cubie.Position.CompareTo(position) == 0)
                    {
                        cubie.Color = value;
                        return;
                    }
                }
                throw new ApplicationException(String.Format($"position {position} not found in set"));
            }
        }
예제 #2
0
        private void FirstLayer()
        {
            for (int c = 0; c < SideColors.Length; c++)
            {
                // Sets the view with the current color in the front face and the white on the top.
                ChangeView(new CubeView(SideColors[c], STARTING_COLOR));

                // Gets the corner that needs to be moved.
                Cubie corner = _cube.FindCorner(STARTING_COLOR, SideColors[c], SideColors[(c + 1) % 4]);

                if (!_cube.IsCubiePlacedCorrectly(corner))
                {
                    // If the corner is in the top layer, the program will rotate it until the corner is on
                    // the top-right of the front face, then use the separate algorithm and rotate the layer back.
                    if (corner.Y == 0)
                    {
                        int rotations;
                        for (rotations = 0; corner.Z != 0 || corner.X != 2; rotations++)
                        {
                            AddMove(Move.Up);
                        }

                        if (corner.FrontColor == STARTING_COLOR || corner.UpColor == STARTING_COLOR)
                        {
                            AddMoveList(Algorithms.SeparateCorner1);
                        }
                        else if (corner.RightColor == STARTING_COLOR)
                        {
                            AddMoveList(Algorithms.SeparateCorner2);
                        }

                        for (int i = 0; i < rotations; i++)
                        {
                            AddMove(Move.UpPrime);
                        }
                    }

                    // Rotates the lower layer until the corner is in the bottom-right of the front face.
                    while (corner.X != 2 || corner.Z != 0)
                    {
                        AddMove(Move.Down);
                    }

                    // Uses the correct algorithm to place the corner in its position.
                    if (corner.FrontColor == STARTING_COLOR)
                    {
                        AddMoveList(Algorithms.WhiteFront);
                    }
                    else if (corner.DownColor == STARTING_COLOR)
                    {
                        AddMoveList(Algorithms.WhiteDown);
                    }
                    else
                    {
                        AddMoveList(Algorithms.WhiteRight);
                    }
                }
            }
        }
예제 #3
0
        private void SecondLayer()
        {
            for (int c = 0; c < SideColors.Length; c++)
            {
                // Gets the edge that needs to be moved.
                Cubie edge = _cube.FindEdge(SideColors[c], SideColors[(c + 1) % 4]);
                if (!_cube.IsCubiePlacedCorrectly(edge))
                {
                    ChangeView(new CubeView(SideColors[c], FINAL_COLOR));

                    // If the edge is in the middle layer and it is located in the back face,
                    // the view will be set to the back face. Then the program will use the algorithm to switch
                    // the edges.
                    if (edge.Y == 1)
                    {
                        if (edge.Z == 2)
                        {
                            ChangeView(new CubeView(SideColors[(c + 2) % 4], FINAL_COLOR));
                        }

                        if (edge.X == 0)
                        {
                            AddMoveList(Algorithms.SecondLayerLeft);
                        }
                        else
                        {
                            AddMoveList(Algorithms.SecondLayerRight);
                        }
                    }

                    // Sets the view.
                    if (edge.UpColor == SideColors[c])
                    {
                        ChangeView(new CubeView(SideColors[(c + 1) % 4], FINAL_COLOR));
                    }
                    else
                    {
                        ChangeView(new CubeView(SideColors[c], FINAL_COLOR));
                    }

                    // Rotates the upper layer until the edge is in the front face.
                    while (edge.Z != 0)
                    {
                        AddMove(Move.Up);
                    }

                    // Use the algorithm to place the edge in the correct position.
                    if (_cube.FindCenter((RubiksColor)edge.UpColor).LeftColor == edge.UpColor)
                    {
                        AddMoveList(Algorithms.SecondLayerLeft);
                    }
                    else
                    {
                        AddMoveList(Algorithms.SecondLayerRight);
                    }
                }
            }
        }
예제 #4
0
        public void Reset()
        {
            Dictionary <CubicleKey, Cubicle> cubeConfiguration = new Dictionary <CubicleKey, Cubicle>();

            foreach (Cubicle cubicle in _cubeConfiguration.Values)
            {
                Cubie cubie = cubicle.Cubie;//.Clone();
                cubie.Reset();
                cubeConfiguration.Add(cubie.Id, new Cubicle(cubie));
            }
            _cubeConfiguration = cubeConfiguration;
        }
예제 #5
0
        private void AddMesh(Dictionary <CubicleKey, Cubicle> cubeConfiguration, string cubieName, ModelMesh mesh)
        {
            Cubie cubie = null;

            if (!cubeConfiguration.ContainsKey(cubieName))
            {
                cubeConfiguration.Add(cubieName, new Cubicle(new Cubie(cubieName, mesh)));
            }
            else
            {
                cubie = cubeConfiguration[cubieName].Cubie;
                cubie.AddMesh(mesh);
            }
        }
예제 #6
0
        /// <summary>
        /// Creates a copy of this cubie.
        /// </summary>
        /// <returns>The copy.</returns>
        public Cubie Clone()
        {
            Cubie clone = new Cubie(this.X, this.Y, this.Z);

            clone.Colors = new RubiksColor?[6];
            for (int i = 0; i < Colors.Length; i++)
            {
                clone.Colors[i] = this.Colors[i];
            }

            clone.CubieType = this.CubieType;

            return(clone);
        }
예제 #7
0
        private void AfterTransform(Transform transform, float rotation)
        {
            foreach (Cubicle cubicle in transform.AffectedCubicles)
            {
                Cubie cubie = cubicle.Cubie;
                cubie.RotateUnit(transform.BasicOp.Axis, rotation);
                //Debug.WriteLine(string.Format("{0}", bone.Name));
            }

            foreach (string[] change in transform.BasicOp.CubicleGroupCycles)
            {
                Group.Cycle <string, Cubie>(transform.IsReversedBasicOp ? change.Reverse().ToArray() : change, k => _cubeConfiguration[k].Cubie, (k, v) => { _cubeConfiguration[k].Cubie = v; return(true); });
            }

            IsSolved = _cubeConfiguration.IsSolved();
            if (!transform.Silent && OneOpDone != null)
            {
                OneOpDone(transform.Op);
            }
        }
예제 #8
0
 public Cubicle(Cubie cubie)
 {
     Id    = cubie.Id;
     Cubie = cubie;
     //BoundingBox = XNAUtils.CreateBoxFromSphere(cubie.Mesh.BoundingSphere);
 }
예제 #9
0
        /// <summary>
        /// Executes the PLL phase.
        /// </summary>
        private void PLL()
        {
            // ******************* CORNERS *******************

            // Sets the view.
            ChangeView(new CubeView(SideColors[0], FINAL_COLOR));

            // Gets the last layer corners and the number of how many of them is already correct.
            IEnumerable <Cubie> corners = _cube.GetFaceCubies(Face.Up).Corners();
            int correctCornersCount     = corners.CorrectCubies(_cube).Count <Cubie>();

            // Rotates the last layer until only one or all of the corners are correct (max 4 times).
            for (int i = 0; i < 4 && correctCornersCount != 4 && correctCornersCount != 1; i++)
            {
                AddMove(Move.Up);
                correctCornersCount = corners.CorrectCubies(_cube).Count <Cubie>();
            }

            // Continues with the algorithm only if any of the corners isn't already correct.
            if (correctCornersCount != 4)
            {
                // If more or less than one corner is correct, the program will use the algorithm to
                // exchange the corners and then rotate the upper layer until the corners are correct.
                if (correctCornersCount != 1)
                {
                    AddMoveList(Algorithms.PLLCornerDoubleExchange);

                    while (!_cube.IsCubiePlacedCorrectly(_cube.FindCubie(0, 0, 0)))
                    {
                        AddMove(Move.Up);
                    }
                }

                // If one corner is correct the cube will be rotated until it is on the left in the front face,
                // then use the correct algorithm.
                else
                {
                    for (int c = 0; !_cube.IsCubiePlacedCorrectly(_cube.FindCubie(0, 0, 0)); c++)
                    {
                        ChangeView(new CubeView(SideColors[c], FINAL_COLOR));
                    }

                    if (_cube.FindCubie(2, 0, 0).FrontColor == _cube.FindCubie(2, 1, 1).RightColor)
                    {
                        AddMoveList(Algorithms.PLLCornerCounterClockwise);
                    }
                    else
                    {
                        AddMoveList(Algorithms.PLLCornerClockwise);
                    }
                }
            }

            // ******************* EDGES *******************

            // Keeps on turning the cube until the cube is solved.
            for (int c = 0; c < SideColors.Length && !_cube.IsSolved(); c++)
            {
                ChangeView(new CubeView(SideColors[c], FINAL_COLOR));

                Cubie frontEdge = _cube.FindCubie(1, 0, 0);
                Cubie backEdge  = _cube.FindCubie(1, 0, 2);
                Cubie leftEdge  = _cube.FindCubie(0, 0, 1);

                // Depending on the situation, the program will use a different algorithm.
                if (_cube.IsCubiePlacedCorrectly(frontEdge))
                {
                    if ((int)leftEdge.LeftColor == -(int)frontEdge.FrontColor)
                    {
                        AddMoveList(Algorithms.PLLEdgeClockwise);
                    }
                    else
                    {
                        AddMoveList(Algorithms.PLLEdgeCounterClockwise);
                    }
                }
                else if ((int)frontEdge.FrontColor == -(int)_cube.GetFaceColor(Face.Front) && (int)backEdge.BackColor == -(int)_cube.GetFaceColor(Face.Back))
                {
                    AddMoveList(Algorithms.PLLEdgeCrossExchange);
                }
                else if (leftEdge.LeftColor == _cube.GetFaceColor(Face.Front) && backEdge.BackColor == _cube.GetFaceColor(Face.Right))
                {
                    AddMoveList(Algorithms.PLLEdgeBackslashExchange);
                }
            }
        }
예제 #10
0
        private void CrossPhase()
        {
            foreach (RubiksColor col in SideColors)
            {
                // Sets the view with the current color in the front face and the white on the top.
                ChangeView(new CubeView(col, STARTING_COLOR));

                // Gets the edge that needs to be moved.
                Cubie edge = _cube.FindEdge(col, STARTING_COLOR);

                if (!_cube.IsCubiePlacedCorrectly(edge))
                {
                    // If the edge is in the lower horizontal layer, the program will
                    // rotate the lower layer until it reaches the front face.
                    if (edge.Y == 2)
                    {
                        while (edge.Z != 0)
                        {
                            AddMove(Move.Down);
                        }
                    }

                    // If the edge is in the upper horizonal layer, the program will
                    // rotate the upper layer until it reaches the front face, protect the edge with a front move
                    // and in the end rotate the upper layer back to its original position.
                    else if (edge.Y == 0)
                    {
                        int rotations;
                        for (rotations = 0; edge.Z != 0; rotations++)
                        {
                            AddMove(Move.Up);
                        }

                        AddMove(Move.Front);

                        for (int i = 0; i < rotations; i++)
                        {
                            AddMove(Move.UpPrime);
                        }
                    }

                    // If the edge is in the middle horizontal layer, but not in the front face the program will
                    // rotate the left/right face until the edge reaches the front face,
                    // protect it with a front/front prime move and in the end move the left/right
                    // face back.
                    else if (edge.Z != 0)
                    {
                        if (edge.X == 0)
                        {
                            AddMoveList(new Move[] { Move.Left, Move.Left, Move.Front, Move.Left, Move.Left });
                        }
                        else
                        {
                            AddMoveList(new Move[] { Move.Right, Move.Right, Move.FrontPrime, Move.Right, Move.Right });
                        }
                    }

                    // Now we are sure that the edge is in the front face.
                    // Two different cases may occur:

                    // 1. the white face of the edge is on the front face of the cube.
                    //    the program will first rotate the front face to bring the edge on the right or
                    //    on the left (if needed), then use the algorithm to place the edge on the top.
                    if (edge.FrontColor == STARTING_COLOR)
                    {
                        if (edge.X == 1)
                        {
                            AddMove(Move.Front);
                        }

                        if (edge.X == 0)
                        {
                            AddMoveList(Algorithms.CrossEdgeLeftWhiteFront);
                        }
                        else
                        {
                            AddMoveList(Algorithms.CrossEdgeRightWhiteFront);
                        }
                    }
                    // 2. the white face of the edge is on one of the sides.
                    //    the program will rotate the front face until the edge is on the top.
                    else
                    {
                        while (edge.Y != 0)
                        {
                            AddMove(Move.Front);
                        }
                    }
                }
            }
        }