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")); } }
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); } } } }
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); } } } }
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; }
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); } }
/// <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); }
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); } }
public Cubicle(Cubie cubie) { Id = cubie.Id; Cubie = cubie; //BoundingBox = XNAUtils.CreateBoxFromSphere(cubie.Mesh.BoundingSphere); }
/// <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); } } }
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); } } } } }