public void PermutedCubesTest() { //make sure that every cube is unique and no cube is null for (int index = 0; index < Symmetries.NumSymmetries; index++) { Assert.IsNotNull(Symmetries.SymmetryCubes[index]); for (int prev = 0; prev < index; prev++) { Assert.AreNotEqual(Symmetries.SymmetryCubes[prev], Symmetries.SymmetryCubes[index]); } } CubieCube expected = CubieCube.CreateSolved(); expected.Mirror(Axis.x); Assert.AreEqual(expected, Symmetries.SymmetryCubes[1]); expected = CubieCube.CreateSolved(); expected.Rotate(Rotation.y1); Assert.AreEqual(expected, Symmetries.SymmetryCubes[2]); expected = CubieCube.CreateSolved(); expected.Rotate(Rotation.z2); Assert.AreEqual(expected, Symmetries.SymmetryCubes[8]); expected = CubieCube.CreateSolved(); expected.Rotate(Rotation.x1); expected.Rotate(Rotation.y1); Assert.AreEqual(expected, Symmetries.SymmetryCubes[16]); }
public static FaceCube ToFaceCube(this CubieCube cubieCube) { var faceCube = new FaceCube(); for (var i = 0; i < cubieCube.CO.Length; i++) { int perm = (int)cubieCube.CP[i]; int ori = cubieCube.CO[i]; for (int j = 0; j < 3; j++) { faceCube.Facelets[(int)Defs.CornerFacelet[i][(j + ori) % 3]] = Defs.CornerColor[perm][j]; } } for (var i = 0; i < cubieCube.EO.Length; i++) { int perm = (int)cubieCube.EP[i]; int ori = cubieCube.EO[i]; for (int j = 0; j < 2; j++) { faceCube.Facelets[(int)Defs.EdgeFacelet[i][(j + ori) % 2]] = Defs.EdgeColor[perm][j]; } } return(faceCube); }
/// <summary> /// Create a move table for U- and D-edge order. Only valid for cubes /// in the subgroup G1. /// </summary> /// <returns> /// A move table for U- and D-edge order. /// </returns> public static ushort[,] CreateUdEdgeOrderMoveTable() { ushort[,] udEdgeOrderMoveTable = new ushort[Coordinates.NumUdEdgeOrders, TwoPhaseConstants.NumMovesPhase2]; //invalidate table for (int udEdgeOrder = 0; udEdgeOrder < Coordinates.NumUdEdgeOrders; udEdgeOrder++) { for (int move = 0; move < TwoPhaseConstants.NumMovesPhase2; move++) { udEdgeOrderMoveTable[udEdgeOrder, move] = ushort.MaxValue; } } //populate table for (int udEdgeOrder = 0; udEdgeOrder < Coordinates.NumCornerPermutations; udEdgeOrder++) { for (int face = 0; face < NumFaces; face++) { CubieCube cube = CubieCube.CreateSolved(); Coordinates.SetUdEdgeOrder(cube, udEdgeOrder); for (int move = 0; move < 3; move++) { cube.MultiplyEdges(CubieCube.MovesArray[face * 3]); if (TwoPhaseConstants.Phase2Moves.Contains((Move)(face * 3 + move))) { udEdgeOrderMoveTable[udEdgeOrder, Phase1IndexToPhase2Index[face * 3 + move]] = (ushort)Coordinates.GetUdEdgeOrder(cube); } } } } return(udEdgeOrderMoveTable); }
public static void HaveEqualEquatorEdgePermutation(CubieCube expected, CubieCube actual) { CubingAssert.HasFourEquatorEdges(expected); CubingAssert.HasFourEquatorEdges(actual); IEnumerator <(Edge edge, int index)> enumerator1 = expected.EdgePermutation.Select((edge, index) => (edge, index)).GetEnumerator(); IEnumerator <(Edge edge, int index)> enumerator2 = actual.EdgePermutation.Select((edge, index) => (edge, index)).GetEnumerator(); for (int equatorEdge = 0; equatorEdge < Constants.NumEquatorEdges; equatorEdge++) { while (enumerator1.MoveNext() && enumerator1.Current.edge < Edge.FR) { ; } while (enumerator2.MoveNext() && enumerator2.Current.edge < Edge.FR) { ; } if (enumerator1.Current.edge != enumerator2.Current.edge) { throw new AssertFailedException("The two cubes do not have the same equator edge permutation: " + enumerator1.Current.edge + " at index " + enumerator1.Current.index + " of " + nameof(expected) + " is not equal to " + enumerator2.Current.edge + " at index " + enumerator2.Current.index + " of " + nameof(actual) + "."); } } }
/// <summary> /// Create a move table for corner permutation. /// </summary> /// <returns> /// A move table for corner permutation. /// </returns> public static ushort[,] CreateCornerPermutationMoveTable() { CubieCube cube = CubieCube.CreateSolved(); ushort[,] cornerPermutationMoveTable = new ushort[Coordinates.NumCornerPermutations, NumMoves]; //invalidate table for (int cornerPermutation = 0; cornerPermutation < Coordinates.NumCornerPermutations; cornerPermutation++) { for (int move = 0; move < NumMoves; move++) { cornerPermutationMoveTable[cornerPermutation, move] = ushort.MaxValue; } } //populate table for (int cornerPermutation = 0; cornerPermutation < Coordinates.NumCornerPermutations; cornerPermutation++) { for (int face = 0; face < NumFaces; face++) { Coordinates.SetCornerPermutation(cube, cornerPermutation); for (int move = 0; move < 3; move++) { cube.MultiplyCorners(CubieCube.MovesArray[face * 3]); cornerPermutationMoveTable[cornerPermutation, face * 3 + move] = (ushort)Coordinates.GetCornerPermutation(cube); } } } return(cornerPermutationMoveTable); }
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ // Generate a CoordCube from a CubieCube internal CoordCubeBuildTables(CubieCube c, bool unpackTables = false) { twist = c.getTwist(); flip = c.getFlip(); parity = c.cornerParity(); FRtoBR = c.getFRtoBR(); URFtoDLF = c.getURFtoDLF(); URtoUL = c.getURtoUL(); UBtoDF = c.getUBtoDF(); URtoDF = c.getURtoDF();// only needed in phase2 if (unpackTables) { //Generate move tables Tools.SerializeTable("twist", twistMove); Tools.SerializeTable("flip", flipMove); Tools.SerializeTable("FRtoBR", FRtoBR_Move); Tools.SerializeTable("URFtoDLF", URFtoDLF_Move); Tools.SerializeTable("URtoDF", URtoDF_Move); Tools.SerializeTable("URtoUL", URtoUL_Move); Tools.SerializeTable("UBtoDF", UBtoDF_Move); Tools.SerializeTable("MergeURtoULandUBtoDF", MergeURtoULandUBtoDF); //Generate Pruning tables Tools.SerializeSbyteArray("Slice_URFtoDLF_Parity_Prun", Slice_URFtoDLF_Parity_Prun); Tools.SerializeSbyteArray("Slice_URtoDF_Parity_Prun", Slice_URtoDF_Parity_Prun); Tools.SerializeSbyteArray("Slice_Twist_Prun", Slice_Twist_Prun); Tools.SerializeSbyteArray("Slice_Flip_Prun", Slice_Flip_Prun); } }
static FlipMoveClass() { CubieCube a = new CubieCube(); for (short i = 0; i < CoordCube.N_FLIP; i++) { a.setFlip(i); for (int j = 0; j < 6; j++) { for (int k = 0; k < 3; k++) { a.edgeMultiply(CubieCube.moveCube[j]); try { flipMove[i, (3 * j + k)] = a.getFlip(); // [2047, 17] } catch (Exception e) { Debug.Log(e); return; } } a.edgeMultiply(CubieCube.moveCube[j]); // a } } }
public void CombineUAndDEdgeCoordsTest() { Random random = new Random(7777777); int length = 50; int repetitions = 50; double[] phase2probabilities = { 0d, 1d, 0d, 1d, 1d, 1d, 0d, 1d, 0d, 0d, 1d, 0d, 1d, 1d, 1d, 0d, 1d, 0d }; for (int repetition = 0; repetition < repetitions; repetition++) { Alg alg = Alg.FromRandomMoves(length, random, phase2probabilities); CubieCube cube = CubieCube.FromAlg(alg); int uEdgeCoord = Coordinates.GetUEdgePermutation(cube); int dEdgeCoord = Coordinates.GetDEdgePermutation(cube); int result = Coordinates.CombineUEdgePermutationAndDEdgeOrder(uEdgeCoord, dEdgeCoord % Coordinates.NumDEdgeOrders); int expected = Coordinates.GetUdEdgeOrder(cube); Assert.AreEqual(expected, result); } }
public void EoCoordTest() //Tests GetEOCoord, SetEOCoord { Random random = new Random(7777777); int length = 50; //if applying GetEOCoord and SetEOCoord results in the same array as at the beginning CubieCube expected = CubieCube.FromAlg(Alg.FromRandomMoves(length, random)); CubieCube result = CubieCube.CreateSolved(); int coord = Coordinates.GetEdgeOrientation(expected); Coordinates.SetEdgeOrientation(result, coord); CollectionAssert.AreEqual(expected.EdgeOrientation, result.EdgeOrientation); //if solved orientation corresponds to the coordinate 0 expected = CubieCube.CreateSolved(); result = CubieCube.FromAlg(Alg.FromRandomMoves(length, random)); Coordinates.SetEdgeOrientation(result, 0); CollectionAssert.AreEqual(expected.EdgeOrientation, result.EdgeOrientation); result = CubieCube.CreateSolved(); Assert.AreEqual(0, Coordinates.GetEdgeOrientation(result)); //exceptions Assert.ThrowsException <ArgumentNullException>(() => Coordinates.GetEdgeOrientation(null)); Assert.ThrowsException <ArgumentNullException>(() => Coordinates.SetEdgeOrientation(null, 0)); Assert.ThrowsException <ArgumentOutOfRangeException>(() => Coordinates.SetEdgeOrientation(CubieCube.CreateSolved(), -1)); Assert.ThrowsException <ArgumentOutOfRangeException>(() => Coordinates.SetEdgeOrientation(CubieCube.CreateSolved(), Coordinates.NumEdgeOrientations)); }
public static string ToFaceCube(CubieCube cc) { char[] f = new char[54]; char[] ts = { 'U', 'R', 'F', 'D', 'L', 'B' }; for (int i = 0; i < 54; i++) { f[i] = ts[i / 9]; } for (sbyte c = 0; c < 8; c++) { int j = cc.ca[c] & 0x7; // cornercubie with index j is at // cornerposition with index c int ori = cc.ca[c] >> 3; // Orientation of this cubie for (sbyte n = 0; n < 3; n++) { f[cornerFacelet[c, (n + ori) % 3]] = ts[cornerFacelet[j, n] / 9]; } } for (sbyte e = 0; e < 12; e++) { int j = cc.ea[e] >> 1; // edgecubie with index j is at edgeposition // with index e int ori = cc.ea[e] & 1; // Orientation of this cubie for (sbyte n = 0; n < 2; n++) { f[edgeFacelet[e, (n + ori) % 2]] = ts[edgeFacelet[j, n] / 9]; } } return(new string(f)); }
public void EquatorPermutationCoordTest() //Tests GetEquatorPermutationCoord, SetEquatorPermutationCoord { Random random = new Random(7777777); int length = 50; int repetitions = 50; //if solved permutation corresponds to the coordinate 0 //SetEquatorPermutationCoord() CubieCube expected = CubieCube.CreateSolved(); CubieCube result = CubieCube.FromAlg(Alg.FromRandomMoves(length, random)); Coordinates.SetEquatorOrder(result, 0); CubingAssert.HaveEqualEquatorEdgePermutation(expected, result); expected = CubieCube.FromAlg(Alg.FromString("R2 L2")); result = CubieCube.FromAlg(Alg.FromRandomMoves(length, random)); Coordinates.SetEquatorOrder(result, Coordinates.NumEquatorOrders - 1); //GetEquatorPermutationCoord() result = CubieCube.CreateSolved(); Assert.AreEqual(0, Coordinates.GetEquatorOrder(result)); result.ApplyAlg(Alg.FromString("F' R' B' D' L2")); Assert.AreEqual(0, Coordinates.GetEquatorOrder(result)); //apply B1 int expectedCoord = 17; CubieCube cube = CubieCube.CreateSolved(); cube.ApplyMove(Move.B1); int resultCoord = Coordinates.GetEquatorOrder(cube); Assert.AreEqual(expectedCoord, resultCoord); //apply B2 expectedCoord = 6; cube = CubieCube.CreateSolved(); cube.ApplyMove(Move.B2); resultCoord = Coordinates.GetEquatorOrder(cube); Assert.AreEqual(expectedCoord, resultCoord); //if applying GetEquatorPermutationCoord() and SetEquatorPermutationCoord() results in the same array as at the beginning for (int repetition = 0; repetition < repetitions; repetition++) { expected = CubieCube.FromAlg(Alg.FromRandomMoves(length, random)); result = CubieCube.CreateSolved(); int coord = Coordinates.GetEquatorOrder(expected); Coordinates.SetEquatorOrder(result, coord); CubingAssert.HaveEqualEquatorEdgePermutation(expected, result); } //exceptions Assert.ThrowsException <ArgumentNullException>(() => Coordinates.GetEquatorOrder(null)); Assert.ThrowsException <ArgumentNullException>(() => Coordinates.SetEquatorOrder(null, 0)); Assert.ThrowsException <ArgumentOutOfRangeException>(() => Coordinates.SetEquatorOrder(CubieCube.CreateSolved(), -1)); Assert.ThrowsException <ArgumentOutOfRangeException>(() => Coordinates.SetEquatorOrder(CubieCube.CreateSolved(), Coordinates.NumEquatorOrders)); }
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ // Compute the inverse CubieCube private void invCubieCube(CubieCube c) { foreach (Edge edge in Enums.Edges) { c.ep[(int)ep[(int)edge]] = edge; } foreach (Edge edge in Enums.Edges) { c.eo[(int)edge] = eo[(int)c.ep[(int)edge]]; } foreach (Corner corn in Enums.Corners) { c.cp[(int)cp[(int)corn]] = corn; } foreach (Corner corn in Enums.Corners) { sbyte ori = co[(int)c.cp[(int)corn]]; if (ori >= 3) // Just for completeness. We do not invert mirrored // cubes in the program. { c.co[(int)corn] = ori; } else { // the standard case c.co[(int)corn] = (sbyte)-ori; if (c.co[(int)corn] < 0) { c.co[(int)corn] += 3; } } } }
/// <summary> /// Create a move table for edge orientation. /// </summary> /// <returns> /// A move table for edge orientation. /// </returns> public static short[,] CreateEdgeOrientationMoveTable() { CubieCube cube = CubieCube.CreateSolved(); short[,] edgeOrientationMoveTable = new short[Coordinates.NumEdgeOrientations, NumMoves]; //invalidate table for (int edgeOrientation = 0; edgeOrientation < Coordinates.NumEdgeOrientations; edgeOrientation++) { for (int move = 0; move < NumMoves; move++) { edgeOrientationMoveTable[edgeOrientation, move] = -1; } } //populate table for (int edgeOrientation = 0; edgeOrientation < Coordinates.NumEdgeOrientations; edgeOrientation++) { for (int face = 0; face < NumFaces; face++) { Coordinates.SetEdgeOrientation(cube, edgeOrientation); for (int move = 0; move < 3; move++) { cube.MultiplyEdges(CubieCube.MovesArray[face * 3]); edgeOrientationMoveTable[edgeOrientation, face * 3 + move] = (short)Coordinates.GetEdgeOrientation(cube); } } } return(edgeOrientationMoveTable); }
//TODO remove redundant indexes /// <summary> /// Create a move table for equator order. Only valid for cubes in the /// subgroup G1. /// </summary> /// <returns> /// A move table for equator order. /// </returns> public static sbyte[,] CreateEquatorOrderMoveTable() { sbyte[,] equatorOrderMoveTable = new sbyte[Coordinates.NumEquatorOrders, NumMoves]; //invalidate table for (int equatorOrder = 0; equatorOrder < Coordinates.NumEquatorOrders; equatorOrder++) { for (int move = 0; move < NumMoves; move++) { equatorOrderMoveTable[equatorOrder, move] = -1; } } //populate table for (int equatorOrder = 0; equatorOrder < Coordinates.NumEquatorOrders; equatorOrder++) { for (int face = 0; face < NumFaces; face++) { CubieCube cube = CubieCube.CreateSolved(); Coordinates.SetEquatorOrder(cube, equatorOrder); for (int move = 0; move < 3; move++) { cube.MultiplyEdges(CubieCube.MovesArray[face * 3]); if (TwoPhaseConstants.Phase2Moves.Contains((Move)(face * 3 + move))) { equatorOrderMoveTable[equatorOrder, face * 3 + move] = (sbyte)Coordinates.GetEquatorOrder(cube); } } } } return(equatorOrderMoveTable); }
static TwistMoveClass() { CubieCube a = new CubieCube(); for (short i = 0; i < CoordCube.N_TWIST; i++) { a.setTwist(i); for (int j = 0; j < 6; j++) { for (int k = 0; k < 3; k++) { a.cornerMultiply(CubieCube.moveCube[j]); try { twistMove[i, (3 * j) + k] = a.getTwist(); //[2187, 17] } catch (Exception e) { break; } } a.cornerMultiply(CubieCube.moveCube[j]);// 4. faceturn restores // a } } }
public void ReductionSymmetryTest() { CubieCube cube = CubieCube.CreateSolved(); for (int equator = 0; equator < NumEquatorDistributions; equator++) { SetEquatorDistribution(cube, equator); for (int eo = 0; eo < NumEdgeOrientations; eo++) { SetEdgeOrientation(cube, eo); int reducedCoord = SymmetryReduction.ReduceEoEquatorCoordinate[equator * NumEdgeOrientations + eo]; int expandedCoord = SymmetryReduction.ExpandEoEquatorCoordinate[reducedCoord]; int symmetryIndex = SymmetryReduction.EoEquatorReductionSymmetry[equator * NumEdgeOrientations + eo]; CubieCube symCube = Symmetries.SymmetryCubes[symmetryIndex].Clone(); symCube.Multiply(cube); symCube.Multiply(Symmetries.SymmetryCubes[Symmetries.InverseIndex[symmetryIndex]]); Assert.AreEqual(expandedCoord % NumEdgeOrientations, GetEdgeOrientation(symCube)); Assert.AreEqual(expandedCoord / NumEdgeOrientations, GetEquatorDistribution(symCube)); } } }
public void RandomTest() { Random random = new Random(7777777); int repetitions = 20; TimeSpan timeout = TimeSpan.FromSeconds(1); int returnLength = 18; int requiredLength = 20; for (int repetition = 0; repetition < repetitions; repetition++) { Alg scramble = Alg.FromRandomMoves(random.Next(20, 30), random); CubieCube cube = CubieCube.FromAlg(scramble); Alg solution = TwoPhaseSolver.FindSolution(cube, timeout, returnLength, requiredLength); Console.WriteLine("\nScramble: " + scramble + "\nSolution: " + solution + "\nLength: " + solution.Length); Assert.IsTrue(solution.Length <= 20); CubieCube expected = CubieCube.CreateSolved(); CubieCube result = CubieCube.CreateSolved(); result.ApplyAlg(scramble); result.ApplyAlg(solution); Assert.AreEqual(expected, result); } }
public void EoEquatorCoordinateTest() { bool found; for (int expanded = 0; expanded < NumEquatorDistributions * NumEdgeOrientations; expanded++) { found = false; int reduced = SymmetryReduction.ReduceEoEquatorCoordinate[expanded]; int expandedSym = SymmetryReduction.ExpandEoEquatorCoordinate[reduced]; CubieCube expandedCube = CubieCube.CreateSolved(); SetEdgeOrientation(expandedCube, expanded % 2048); SetEquatorDistribution(expandedCube, expanded / 2048); for (int sym = 0; sym < NumSymmetriesDh4; sym++) { CubieCube symCube = Symmetries.SymmetryCubes[sym].Clone(); symCube.MultiplyEdges(expandedCube); symCube.MultiplyEdges(Symmetries.SymmetryCubes[Symmetries.InverseIndex[sym]]); if (expandedSym % 2048 == GetEdgeOrientation(symCube) && expandedSym / 2048 == GetEquatorDistribution(symCube)) { found = true; break; } } if (!found) { Assert.Fail(); } } }
public void ReduceEoEquatorCoordinateTest() { Random random = new Random(7777777); int length = 30; int count = 100; for (int i = 0; i < count; i++) { CubieCube cube = CubieCube.FromAlg(Alg.FromRandomMoves(length, random)); for (int sym = 0; sym < NumSymmetriesDh4; sym++) { CubieCube symCube = Symmetries.SymmetryCubes[sym].Clone(); symCube.Multiply(cube); symCube.Multiply(Symmetries.SymmetryCubes[Symmetries.InverseIndex[sym]]); int cubeEoEquator = GetEoEquatorCoord(cube); int cubeReducedEoEquator = SymmetryReduction.ReduceEoEquatorCoordinate[cubeEoEquator]; int symCubeEoEquator = GetEoEquatorCoord(symCube); int symCubeReducedEoEqutor = SymmetryReduction.ReduceEoEquatorCoordinate[symCubeEoEquator]; Assert.AreEqual(cubeReducedEoEquator, symCubeReducedEoEqutor); } } }
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ // Compute the inverse CubieCube void invCubieCube(CubieCube c) { foreach (Edge edge in (Edge[])Enum.GetValues(typeof(Edge))) { c.ep[(int)ep[(int)edge]] = edge; } foreach (Edge edge in (Edge[])Enum.GetValues(typeof(Edge))) { c.eo[(int)edge] = eo[(int)c.ep[(int)edge]]; } foreach (Corner corn in (Corner[])Enum.GetValues(typeof(Corner))) { c.cp[(int)cp[(int)corn]] = corn; } foreach (Corner corn in (Corner[])Enum.GetValues(typeof(Corner))) { int ori = co[(int)c.cp[(int)corn]]; if (ori >= 3) // Just for completeness. We do not invert mirrored cubes in the program. { c.co[(int)corn] = ori; } else { // the standard case c.co[(int)corn] = -ori; if (c.co[(int)corn] < 0) { c.co[(int)corn] += 3; } } } }
public static CubieCube ToCubieCube(this FaceCube faceCube) { var facelets = faceCube.Facelets; var cubieCube = new CubieCube(); cubieCube.CP = cubieCube.CP.Select((c) => Corner.Invalid).ToArray(); cubieCube.EP = cubieCube.EP.Select((E) => Edge.Invalid).ToArray(); for (var i = 0; i < Defs.CornerFacelet.Length; i++) { Facelet[] corner = Defs.CornerFacelet[i]; int ori = -1; var color3 = Color.Invalid; var color2 = Color.Invalid; if (facelets[(int)corner[0]] == Color.U || facelets[(int)corner[0]] == Color.D) { ori = 0; color2 = facelets[(int)corner[1]]; color3 = facelets[(int)corner[2]]; } else if (facelets[(int)corner[1]] == Color.U || facelets[(int)corner[1]] == Color.D) { ori = 1; color2 = facelets[(int)corner[2]]; color3 = facelets[(int)corner[0]]; } else if (facelets[(int)corner[2]] == Color.U || facelets[(int)corner[2]] == Color.D) { ori = 2; color2 = facelets[(int)corner[0]]; color3 = facelets[(int)corner[1]]; } cubieCube.CP[i] = (Corner)Defs.CornerColor.FirstIndexWhere(cornerC => cornerC[1] == color2 && cornerC[2] == color3, (int)Corner.Invalid); cubieCube.CO[i] = ori; } for (var i = 0; i < Defs.EdgeFacelet.Length; i++) { Facelet[] edge = Defs.EdgeFacelet[i]; foreach (Color[] edgeColors in Defs.EdgeColor) { if (edgeColors[0] == facelets[(int)edge[0]] && edgeColors[1] == facelets[(int)edge[1]]) { cubieCube.EP[i] = (Edge)i; cubieCube.EO[i] = 0; } else if (edgeColors[0] == facelets[(int)edge[0]] && edgeColors[1] == facelets[(int)edge[1]]) { cubieCube.EP[i] = (Edge)i; cubieCube.EO[i] = 1; } } } return(cubieCube); }
static void Main(string[] args) { var faceCube = new FaceCube() == new FaceCube(); var cube = new CubieCube() == new CubieCube(); var cubes = new CubieCube().Equals(new CubieCube()); new CubieCube().ToFaceCube(); }
public void CpCoordTest() //Tests GetCpCoord, SetCpCoord { Random random = new Random(7777777); int length = 50; //if applying GetCpCoord and SetCpCoord results in the same array as at the beginning CubieCube expected = CubieCube.FromAlg(Alg.FromRandomMoves(length, random)); CubieCube result = CubieCube.CreateSolved(); int coord = Coordinates.GetCornerPermutation(expected); Coordinates.SetCornerPermutation(result, coord); CollectionAssert.AreEqual(expected.CornerPermutation, result.CornerPermutation); //apply R2 to a solved cube CubieCube cube = CubieCube.CreateSolved(); cube.ApplyMove(Move.R2); int expectedCoord = 36177; int resultCoord = Coordinates.GetCornerPermutation(cube); Assert.AreEqual(expectedCoord, resultCoord); expected = CubieCube.CreateSolved(); expected.ApplyMove(Move.R2); result = CubieCube.CreateSolved(); Coordinates.SetCornerPermutation(result, expectedCoord); CollectionAssert.AreEqual(expected.CornerPermutation, result.CornerPermutation); //if solved permutation corresponds to the coordinate 0 expected = CubieCube.CreateSolved(); result = CubieCube.FromAlg(Alg.FromRandomMoves(length, random)); Coordinates.SetCornerPermutation(result, 0); CollectionAssert.AreEqual(expected.CornerPermutation, result.CornerPermutation); result = CubieCube.CreateSolved(); Assert.AreEqual(0, Coordinates.GetCornerPermutation(result)); //example from http://kociemba.org/math/coordlevel Corner[] cp = new Corner[] { Corner.DFR, Corner.UFL, Corner.ULB, Corner.URF, Corner.DRB, Corner.DLF, Corner.DBL, Corner.UBR }; cube = CubieCube.Create(cp, CubieCube.SolvedCO, CubieCube.SolvedEP, CubieCube.SolvedEO, CubieCube.SolvedCenters); resultCoord = Coordinates.GetCornerPermutation(cube); expectedCoord = 21021; Assert.AreEqual(expectedCoord, resultCoord); //exceptions Assert.ThrowsException <ArgumentNullException>(() => Coordinates.GetCornerPermutation(null)); Assert.ThrowsException <ArgumentNullException>(() => Coordinates.SetCornerPermutation(null, 0)); Assert.ThrowsException <ArgumentOutOfRangeException>(() => Coordinates.SetCornerPermutation(CubieCube.CreateSolved(), -1)); Assert.ThrowsException <ArgumentOutOfRangeException>(() => Coordinates.SetCornerPermutation(CubieCube.CreateSolved(), Coordinates.NumCornerPermutations)); }
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ // Multiply this CubieCube with another cubiecube b, restricted to the corners.<br> // Because we also describe reflections of the whole cube by permutations, we get a complication with the corners. The // orientations of mirrored corners are described by the numbers 3, 4 and 5. The composition of the orientations // cannot // be computed by addition modulo three in the cyclic group C3 any more. Instead the rules below give an addition in // the dihedral group D3 with 6 elements.<br> // // NOTE: Because we do not use symmetry reductions and hence no mirrored cubes in this simple implementation of the // Two-Phase-Algorithm, some code is not necessary here. // public void cornerMultiply(CubieCube b) { Corner[] cPerm = new Corner[8]; sbyte[] cOri = new sbyte[8]; foreach (Corner corn in Enums.Corners) { cPerm[(int)corn] = cp[(int)b.cp[(int)corn]]; sbyte oriA = co[(int)b.cp[(int)corn]]; sbyte oriB = b.co[(int)corn]; sbyte ori = 0; ; if (oriA < 3 && oriB < 3) // if both cubes are regular cubes... { ori = (sbyte)(oriA + oriB); // just do an addition modulo 3 here if (ori >= 3) { ori -= 3; // the composition is a regular cube } // +++++++++++++++++++++not used in this implementation +++++++++++++++++++++++++++++++++++ } else if (oriA < 3 && oriB >= 3) // if cube b is in a mirrored // state... { ori = (sbyte)(oriA + oriB); if (ori >= 6) { ori -= 3; // the composition is a mirrored cube } } else if (oriA >= 3 && oriB < 3) // if cube a is an a mirrored // state... { ori = (sbyte)(oriA - oriB); if (ori < 3) { ori += 3; // the composition is a mirrored cube } } else if (oriA >= 3 && oriB >= 3) // if both cubes are in mirrored // states... { ori = (sbyte)(oriA - oriB); if (ori < 0) { ori += 3; // the composition is a regular cube } // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ } cOri[(int)corn] = ori; } foreach (Corner c in Enums.Corners) { int cornerIdx = (int)c; cp[cornerIdx] = cPerm[cornerIdx]; co[cornerIdx] = cOri[cornerIdx]; } }
public void SettingCoordParityCorrect() { var cubieCube = new CubieCube(); Assert.Equal(0, cubieCube.EO[11]); cubieCube.EdgeOriCoord = 1; Assert.Equal(1, cubieCube.EO[11]); }
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ // Multiply this CubieCube with another cubiecube b, restricted to the corners.<br> // Because we also describe reflections of the whole cube by permutations, we get a complication with the corners. The // orientations of mirrored corners are described by the numbers 3, 4 and 5. The composition of the orientations // cannot // be computed by addition modulo three in the cyclic group C3 any more. Instead the rules below give an addition in // the dihedral group D3 with 6 elements.<br> // // NOTE: Because we do not use symmetry reductions and hence no mirrored cubes in this simple implementation of the // Two-Phase-Algorithm, some code is not necessary here. // public void cornerMultiply(CubieCube b) { Corner[] cPerm = new Corner[8]; int[] cOri = new int[8]; foreach (Corner corn in (Corner[])Enum.GetValues(typeof(Corner))) { cPerm[(int)corn] = cp[(int)b.cp[(int)corn]]; int oriA = co[(int)b.cp[(int)corn]]; int oriB = b.co[(int)corn]; int ori = 0; ; if (oriA < 3 && oriB < 3) // if both cubes are regular cubes... { ori = (oriA + oriB); // just do an addition modulo 3 here if (ori >= 3) { ori -= 3; // the composition is a regular cube } // +++++++++++++++++++++not used in this implementation +++++++++++++++++++++++++++++++++++ } else if (oriA < 3 && oriB >= 3) // if cube b is in a mirrored // state... { ori = (oriA + oriB); if (ori >= 6) { ori -= 3; // the composition is a mirrored cube } } else if (oriA >= 3 && oriB < 3) // if cube a is an a mirrored // state... { ori = (oriA - oriB); if (ori < 3) { ori += 3; // the composition is a mirrored cube } } else if (oriA >= 3 && oriB >= 3) // if both cubes are in mirrored // states... { ori = (oriA - oriB); if (ori < 0) { ori += 3; // the composition is a regular cube } // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ } cOri[(int)corn] = ori; } foreach (Corner c in (Corner[])Enum.GetValues(typeof(Corner))) { cp[(int)c] = cPerm[(int)c]; co[(int)c] = cOri[(int)c]; } }
public static void HasFourEquatorEdges(CubieCube cube) { int count = cube.EdgePermutation.Count(edge => edge >= Edge.FR); if (count != Constants.NumEquatorEdges) { throw new AssertFailedException("Cube has " + count + " equator edges instead of 4."); } }
public static void ToCubieCube(sbyte[] f, CubieCube ccRet) { sbyte ori; for (int i = 0; i < 8; i++) { ccRet.ca[i] = 0;// invalidate corners } for (int i = 0; i < 12; i++) { ccRet.ea[i] = 0;// and edges } sbyte col1, col2; for (sbyte i = 0; i < 8; i++) { // get the colors of the cubie at corner i, starting with U/D for (ori = 0; ori < 3; ori++) { if (f[cornerFacelet[i, ori]] == U || f[cornerFacelet[i, ori]] == D) { break; } } col1 = f[cornerFacelet[i, (ori + 1) % 3]]; col2 = f[cornerFacelet[i, (ori + 2) % 3]]; for (sbyte j = 0; j < 8; j++) { if (col1 == cornerFacelet[j, 1] / 9 && col2 == cornerFacelet[j, 2] / 9) { // in cornerposition i we have cornercubie j ccRet.ca[i] = (sbyte)((sbyte)(ori % 3 << 3) | j); break; } } } for (sbyte i = 0; i < 12; i++) { for (sbyte j = 0; j < 12; j++) { if (f[edgeFacelet[i, 0]] == edgeFacelet[j, 0] / 9 && f[edgeFacelet[i, 1]] == edgeFacelet[j, 1] / 9) { ccRet.ea[i] = (sbyte)(j << 1); break; } if (f[edgeFacelet[i, 0]] == edgeFacelet[j, 1] / 9 && f[edgeFacelet[i, 1]] == edgeFacelet[j, 0] / 9) { ccRet.ea[i] = (sbyte)(j << 1 | 1); break; } } } }
public void SettingCoordReverses() { var cubieCube = new CubieCube(); for (var i = 0; i <= 2047; i++) { cubieCube.EdgeOriCoord = i; Assert.Equal(i, cubieCube.EdgeOriCoord); } }
public void SettingCoordReverses() { var cubieCube = new CubieCube(); for (var i = 0; i <= 479001599; i += 10000) { cubieCube.EdgePermCoord = i; Assert.Equal(i, cubieCube.EdgePermCoord); } }