/// <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 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 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)); }
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 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)); } } }
/// <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); }
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 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)); }
//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); }
/// <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); }
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)); }
public void CreateTest() { Assert.AreEqual( CubieCube.CreateSolved(), CubieCube.Create( CubieCube.SolvedCP, CubieCube.SolvedCO, CubieCube.SolvedEP, CubieCube.SolvedEO, CubieCube.SolvedCenters)); #region test exceptions Assert.ThrowsException <ArgumentNullException>(() => CubieCube.Create(null, CubieCube.SolvedCO, CubieCube.SolvedEP, CubieCube.SolvedEO, CubieCube.SolvedCenters)); Assert.ThrowsException <ArgumentNullException>(() => CubieCube.Create(CubieCube.SolvedCP, null, CubieCube.SolvedEP, CubieCube.SolvedEO, CubieCube.SolvedCenters)); Assert.ThrowsException <ArgumentNullException>(() => CubieCube.Create(CubieCube.SolvedCP, CubieCube.SolvedCO, null, CubieCube.SolvedEO, CubieCube.SolvedCenters)); Assert.ThrowsException <ArgumentNullException>(() => CubieCube.Create(CubieCube.SolvedCP, CubieCube.SolvedCO, CubieCube.SolvedEP, null, CubieCube.SolvedCenters)); Assert.ThrowsException <ArgumentNullException>(() => CubieCube.Create(CubieCube.SolvedCP, CubieCube.SolvedCO, CubieCube.SolvedEP, CubieCube.SolvedEO, null)); Assert.ThrowsException <ArgumentException>(() => CubieCube.Create(new Corner[NumCorners + 1], CubieCube.SolvedCO, CubieCube.SolvedEP, CubieCube.SolvedEO, CubieCube.SolvedCenters)); Assert.ThrowsException <ArgumentException>(() => CubieCube.Create(CubieCube.SolvedCP, new int[NumCorners + 1], CubieCube.SolvedEP, CubieCube.SolvedEO, CubieCube.SolvedCenters)); Assert.ThrowsException <ArgumentException>(() => CubieCube.Create(CubieCube.SolvedCP, CubieCube.SolvedCO, new Edge[NumEdges + 1], CubieCube.SolvedEO, CubieCube.SolvedCenters)); Assert.ThrowsException <ArgumentException>(() => CubieCube.Create(CubieCube.SolvedCP, CubieCube.SolvedCO, CubieCube.SolvedEP, new int[NumEdges + 1], CubieCube.SolvedCenters)); Assert.ThrowsException <ArgumentException>(() => CubieCube.Create(CubieCube.SolvedCP, CubieCube.SolvedCO, CubieCube.SolvedEP, CubieCube.SolvedEO, new Face[NumFaces + 1])); #endregion test exceptions }
public void SexyMoveTest(Action <CubieCube, CubieCube> test) { Alg sexyMove = Alg.FromString("R U R' U'"); foreach (Rotation rotation in Enum.GetValues(typeof(Rotation))) { CubieCube expected = CubieCube.CreateSolved(); CubieCube result = CubieCube.CreateSolved(); result.ApplyAlg(sexyMove.Rotate(rotation) * 6); test(expected, result); } }
public void EpCoordTest() //Tests GetCpCoord, SetCpCoord { Random random = new Random(7777777); int length = 50; //if applying GetEpCoord and SetEpCoord results in the same array as at the beginning CubieCube expected = CubieCube.FromAlg(Alg.FromRandomMoves(length, random)); CubieCube result = CubieCube.CreateSolved(); int coord = Coordinates.GetEdgePermutation(expected); Coordinates.SetEdgePermutation(result, coord); CollectionAssert.AreEqual(expected.EdgePermutation, result.EdgePermutation); //apply R2 to a solved cube CubieCube cube = CubieCube.CreateSolved(); cube.ApplyMove(Move.R2); int expectedCoord = 123763104; int resultCoord = Coordinates.GetEdgePermutation(cube); Assert.AreEqual(expectedCoord, resultCoord); expected = CubieCube.CreateSolved(); expected.ApplyMove(Move.R2); result = CubieCube.CreateSolved(); Coordinates.SetEdgePermutation(result, expectedCoord); CollectionAssert.AreEqual(expected.EdgePermutation, result.EdgePermutation); //if solved permutation corresponds to the coordinate 0 expected = CubieCube.CreateSolved(); result = CubieCube.FromAlg(Alg.FromRandomMoves(length, random)); Coordinates.SetEdgePermutation(result, 0); CollectionAssert.AreEqual(expected.EdgePermutation, result.EdgePermutation); result = CubieCube.CreateSolved(); Assert.AreEqual(0, Coordinates.GetEdgePermutation(result)); //exceptions Assert.ThrowsException <ArgumentNullException>(() => Coordinates.GetEdgePermutation(null)); Assert.ThrowsException <ArgumentNullException>(() => Coordinates.SetEdgePermutation(null, 0)); Assert.ThrowsException <ArgumentOutOfRangeException>(() => Coordinates.SetEdgePermutation(CubieCube.CreateSolved(), -1)); Assert.ThrowsException <ArgumentOutOfRangeException>(() => Coordinates.SetEdgePermutation(CubieCube.CreateSolved(), Coordinates.NumEdgePermutations)); }
public void EquatorDistributionCoordTest() //Tests GetEquatorDistributionCoord, SetEquatorDistributionCoord { Random random = new Random(7777777); int length = 50; int repetitions = 50; CubieCube expected; CubieCube result; int expectedCoord; int resultCoord; Move[] phase2Moves = { Move.R2, Move.L2, Move.F2, Move.B2, Move.U1, Move.U2, Move.U3, Move.D1, Move.D2, Move.D3 }; IEnumerable <Move> randomPhase2Moves() { yield return(phase2Moves[random.Next(0, phase2Moves.Length)]); } //solved tests Assert.AreEqual(0, Coordinates.GetEquatorDistribution(CubieCube.CreateSolved())); expected = CubieCube.CreateSolved(); for (int i = 0; i < repetitions; i++) { result = CubieCube.FromAlg(randomPhase2Moves().Take(length)); expectedCoord = Coordinates.GetEquatorDistribution(expected); resultCoord = Coordinates.GetEquatorDistribution(result); Assert.AreEqual(expectedCoord, resultCoord); } //scrambled tests for (int i = 0; i < repetitions; i++) { result = CubieCube.CreateSolved(); expected = CubieCube.FromAlg(Alg.FromRandomMoves(length, random)); expectedCoord = Coordinates.GetEquatorDistribution(expected); Coordinates.SetEquatorDistribution(result, expectedCoord); resultCoord = Coordinates.GetEquatorDistribution(result); Assert.AreEqual(expectedCoord, resultCoord); } //exceptions Assert.ThrowsException <ArgumentNullException>(() => Coordinates.GetEquatorDistribution(null)); Assert.ThrowsException <ArgumentNullException>(() => Coordinates.SetEquatorDistribution(null, 0)); Assert.ThrowsException <ArgumentOutOfRangeException>(() => Coordinates.SetEquatorDistribution(CubieCube.CreateSolved(), -1)); Assert.ThrowsException <ArgumentOutOfRangeException>(() => Coordinates.SetEquatorDistribution(CubieCube.CreateSolved(), Coordinates.NumEquatorDistributions)); }
private void StartSearch() { #region rotate cube CubieCube rotatedCube = CubieCube.CreateSolved(); for (int i = 0; i < _rotation; i++) { rotatedCube.Rotate(Rotation.y3); rotatedCube.Rotate(Rotation.x3); } rotatedCube.Multiply(_notRotatedCube); for (int i = 0; i < _rotation; i++) { rotatedCube.Rotate(Rotation.x1); rotatedCube.Rotate(Rotation.y1); } if (_inversed) { rotatedCube.Inverse(); } #endregion rotate cube //calculate coordinates int co = Coordinates.GetCornerOrientation(rotatedCube); int cp = Coordinates.GetCornerPermutation(rotatedCube); int eo = Coordinates.GetEdgeOrientation(rotatedCube); int equator = Coordinates.GetEquatorPermutation(rotatedCube); int uEdges = Coordinates.GetUEdgePermutation(rotatedCube); int dEdges = Coordinates.GetDEdgePermutation(rotatedCube); //store coordinates used in phase 2 _cp = cp; _uEdges = uEdges; _dEdges = dEdges; int pruningIndex = PruningTables.GetPhase1PruningIndex(co, eo, equator / Coordinates.NumEquatorOrders); int minPhase1Length = TableController.Phase1PruningTable[pruningIndex]; int maxPhase1Length = (_requiredLength > 0 && _requiredLength < GodsNumber) ? _requiredLength : GodsNumber; _currentPhase1Solution = new int[maxPhase1Length]; _currentPhase2Solution = new int[MaxPhase2Length]; for (int phase1Length = minPhase1Length; phase1Length < maxPhase1Length; phase1Length++) { SearchPhase1(eo, co, equator, depth: 0, remainingMoves: phase1Length, minPhase1Length); } }
public void StaticTest(string algString) { Alg scramble = Alg.FromString(algString); CubieCube cube = CubieCube.FromAlg(scramble); TimeSpan timeout = TimeSpan.FromSeconds(1); float returnValue = 4000; float requiredValue = 5000; float[] weights = { 169.658122242946f, 253.796705882179f, 211.084512473536f, 206.193406852305f, 299.809258427086f, 155.496912851115f, 158.690899467791f, 281.70422762001f, 346.448146439892f, 274.885031555195f, 311.019164835258f, 258.486161100002f, 196.885474673572f, 275.657440421246f, 214.624405800259f, 322.649818802591f, 354.012863621357f, 321.02200029978f }; float[] weightedPhase2PruningTable = WeightedPruningTables.CreateWeightedPhase2CornerEquatorTable(weights); Alg solution = WeightedTwoPhaseSolver.FindSolution(cube, timeout, returnValue, requiredValue, weights, weightedPhase2PruningTable); Console.WriteLine("Scramble: " + scramble + "\nSolution: " + solution + "\nLength: " + solution.Length); Assert.IsTrue(solution.Select(move => weights[(int)move]).Sum() <= requiredValue); CubieCube expected = CubieCube.CreateSolved(); CubieCube result = CubieCube.CreateSolved(); result.ApplyAlg(scramble); result.ApplyAlg(solution); Assert.AreEqual(expected, result); }
public void InverseIndexTest() { for (int index = 0; index < Symmetries.NumSymmetries; index++) { CubieCube permCube = Symmetries.SymmetryCubes[index]; CubieCube invCube = Symmetries.SymmetryCubes[Symmetries.InverseIndex[index]]; CubieCube solved = CubieCube.CreateSolved(); CubieCube test1 = permCube.Clone(); test1.Multiply(invCube); Assert.AreEqual(solved, test1); CubieCube test2 = invCube.Clone(); test2.Multiply(permCube); Assert.AreEqual(solved, test2); } }
public void Inverse() { CubieCube expected = CubieCube.CreateSolved(); Random random = new Random(7777777); int length = 50; int repetitions = 50; for (int repetition = 0; repetition < repetitions; repetition++) { Alg alg = Alg.FromRandomMoves(length, random); CubieCube result = CubieCube.FromAlg(alg); result.Inverse(); result.ApplyAlg(alg); Assert.AreEqual(expected, result); } }
public void UEdgeCoordTest() { Random random = new Random(7777777); int length = 50; int repetitions = 50; CubieCube expected; CubieCube result; int expectedCoord; int resultCoord; double[] phase2probabilities = { 0d, 1d, 0d, 1d, 1d, 1d, 0d, 1d, 0d, 0d, 1d, 0d, 1d, 1d, 1d, 0d, 1d, 0d }; //solved tests Assert.AreEqual(0, Coordinates.GetUEdgeDistribution(CubieCube.CreateSolved())); //scrambled tests for (int i = 0; i < repetitions; i++) { result = CubieCube.CreateSolved(); expected = CubieCube.FromAlg(Alg.FromRandomMoves(length, random)); expectedCoord = Coordinates.GetUEdgePermutation(expected); Coordinates.SetUEdgePermutation(result, expectedCoord); resultCoord = Coordinates.GetUEdgePermutation(result); int expectedDistribution = expectedCoord / Coordinates.NumUEdgePermutations; int expectedPermutation = expectedCoord % Coordinates.NumUEdgePermutations; int resultDistribution = resultCoord / Coordinates.NumUEdgePermutations; int resultPermutation = resultCoord % Coordinates.NumUEdgePermutations; Assert.AreEqual(expectedDistribution, resultDistribution); Assert.AreEqual(expectedPermutation, resultPermutation); } //exceptions Assert.ThrowsException <ArgumentNullException>(() => Coordinates.GetUEdgePermutation(null)); Assert.ThrowsException <ArgumentNullException>(() => Coordinates.SetUEdgePermutation(null, 0)); Assert.ThrowsException <ArgumentOutOfRangeException>(() => Coordinates.SetUEdgePermutation(CubieCube.CreateSolved(), -1)); Assert.ThrowsException <ArgumentOutOfRangeException>(() => Coordinates.SetUEdgePermutation(CubieCube.CreateSolved(), Coordinates.NumUEdgePermutations)); }
public void TestAllPhase1() { Random random = new Random(7777777); int length = 50; int repetitions = 50; TableController.InitializeCornerOrientationMoveTable(); TableController.InitializeCornerPermutationMoveTable(); TableController.InitializeEdgeOrientationMoveTable(); TableController.InitializeEquatorDistributionMoveTable(); for (int repetition = 0; repetition < repetitions; repetition++) { Alg randomMoves = Alg.FromRandomMoves(length, random); int resultCo = 0; int resultCp = 0; int resultEo = 0; int resultEquatorDistribution = 0; CubieCube cube = CubieCube.CreateSolved(); for (int moveIndex = 0; moveIndex < length; moveIndex++) { resultCo = TableController.CornerOrientationMoveTable[resultCo, (int)randomMoves[moveIndex]]; resultCp = TableController.CornerPermutationMoveTable[resultCp, (int)randomMoves[moveIndex]]; resultEo = TableController.EdgeOrientationMoveTable[resultEo, (int)randomMoves[moveIndex]]; resultEquatorDistribution = TableController.EquatorDistributionMoveTable[resultEquatorDistribution, (int)randomMoves[moveIndex]]; cube.ApplyMove(randomMoves[moveIndex]); } int expectedCo = Coordinates.GetCornerOrientation(cube); Assert.AreEqual(expectedCo, resultCo); int expectedCp = Coordinates.GetCornerPermutation(cube); Assert.AreEqual(expectedCp, resultCp); int expectedEo = Coordinates.GetEdgeOrientation(cube); Assert.AreEqual(expectedEo, resultEo); int expectedEquatorDistribution = Coordinates.GetEquatorDistribution(cube); Assert.AreEqual(expectedEquatorDistribution, resultEquatorDistribution); } }
public void UdEdgeOrderCoordTest() //Tests GetUdEdgePermutationCoord, SetUdEdgePermutationCoord { Random random = new Random(7777777); int length = 50; double[] phase2probabilities = { 0d, 1d, 0d, 1d, 1d, 1d, 0d, 1d, 0d, 0d, 1d, 0d, 1d, 1d, 1d, 0d, 1d, 0d }; //if solved permutation corresponds to the coordinate 0 CubieCube expected = CubieCube.CreateSolved(); CubieCube result = CubieCube.FromAlg(Alg.FromRandomMoves(length, random, phase2probabilities)); Coordinates.SetUdEdgeOrder(result, 0); CollectionAssert.AreEqual(expected.EdgePermutation.Take(8).ToArray(), result.EdgePermutation.Take(8).ToArray()); result = CubieCube.CreateSolved(); Assert.AreEqual(0, Coordinates.GetUdEdgeOrder(result)); //if applying GetUdEdgePermutationCoord and //SetUdEdgePermutationCoord results in the same array as at the //beginning Alg randomAlg = Alg.FromRandomMoves(length, random, phase2probabilities); expected = CubieCube.FromAlg(randomAlg); result = CubieCube.CreateSolved(); int coord = Coordinates.GetUdEdgeOrder(expected); Coordinates.SetUdEdgeOrder(result, coord); CollectionAssert.AreEqual(expected.EdgePermutation.Take(8).ToArray(), result.EdgePermutation.Take(8).ToArray()); //exceptions Assert.ThrowsException <ArgumentNullException>(() => Coordinates.GetUdEdgeOrder(null)); Assert.ThrowsException <ArgumentNullException>(() => Coordinates.SetUdEdgeOrder(null, 0)); Assert.ThrowsException <ArgumentOutOfRangeException>(() => Coordinates.SetUdEdgeOrder(CubieCube.CreateSolved(), -1)); Assert.ThrowsException <ArgumentOutOfRangeException>(() => Coordinates.SetUdEdgeOrder(CubieCube.CreateSolved(), Coordinates.NumUdEdgeOrders)); }
public void TestAllPhase2() { Random random = new Random(7777777); int length = 50; int repetitions = 50; TableController.InitializeUdEdgeOrderMoveTable(); TableController.InitializeEquatorOrderMoveTable(); double[] moveProbabilities = { 0d, 1d, 0d, 1d, 1d, 1d, 0d, 1d, 0d, 0d, 1d, 0d, 1d, 1d, 1d, 0d, 1d, 0d }; int expectedEquatorPermutation; for (int repetition = 0; repetition < repetitions; repetition++) { Alg randomMoves = Alg.FromRandomMoves(length, random, moveProbabilities); int resultUdEdgeOrder = 0; int resultEquatorPermutation = 0; CubieCube cube = CubieCube.CreateSolved(); for (int moveIndex = 0; moveIndex < length; moveIndex++) { resultUdEdgeOrder = TableController.UdEdgeOrderMoveTable[resultUdEdgeOrder, MoveTables.Phase1IndexToPhase2Index[(int)randomMoves[moveIndex]]]; resultEquatorPermutation = TableController.EquatorOrderMoveTable[resultEquatorPermutation, (int)randomMoves[moveIndex]]; cube.ApplyMove(randomMoves[moveIndex]); expectedEquatorPermutation = Coordinates.GetEquatorOrder(cube); Assert.AreEqual(expectedEquatorPermutation, resultEquatorPermutation); } int expectedUdEdgeOrder = Coordinates.GetUdEdgeOrder(cube); Assert.AreEqual(expectedUdEdgeOrder, resultUdEdgeOrder); expectedEquatorPermutation = Coordinates.GetEquatorOrder(cube); Assert.AreEqual(expectedEquatorPermutation, resultEquatorPermutation); } }
public void CloneTest() { CubieCube cube = CubieCube.CreateSolved(); CubieCube clone = cube.Clone(); Assert.IsTrue(cube == clone); CollectionAssert.AreEqual(cube.CornerPermutation, clone.CornerPermutation); CollectionAssert.AreEqual(cube.CornerOrientation, clone.CornerOrientation); CollectionAssert.AreEqual(cube.EdgeOrientation, clone.EdgeOrientation); CollectionAssert.AreEqual(cube.EdgePermutation, clone.EdgePermutation); Assert.IsFalse(ReferenceEquals(cube, clone)); Assert.IsFalse(ReferenceEquals(cube.CornerPermutation, clone.CornerPermutation)); Assert.IsFalse(ReferenceEquals(cube.CornerOrientation, clone.CornerOrientation)); Assert.IsFalse(ReferenceEquals(cube.EdgeOrientation, clone.EdgeOrientation)); Assert.IsFalse(ReferenceEquals(cube.EdgePermutation, clone.EdgePermutation)); }
public void MoveReplacementTest(Action <CubieCube, CubieCube> test) { Alg uReplacementAlg = Alg.FromString("R L' F2 B2 R L' D L R' B2 F2 L R'"); foreach (Move move in Enum.GetValues(typeof(Move))) { foreach (Rotation rotation in Enum.GetValues(typeof(Rotation))) { if (Face.U.Rotate(rotation) == move.Face()) { CubieCube result = CubieCube.CreateSolved(); result.ApplyMove(move); CubieCube expected = CubieCube.CreateSolved(); expected.ApplyAlg(uReplacementAlg.Rotate(rotation) * move.QuarterTurns()); test(expected, result); } } } }
public void MultiplyTest() { Random random = new Random(7777777); int length = 50; Alg alg = Alg.FromRandomMoves(length, random); CubieCube expected = CubieCube.CreateSolved(); CubieCube result = CubieCube.CreateSolved(); foreach (Move move in alg) { expected.ApplyMove(move); CubieCube moveCube = CubieCube.CreateSolved(); moveCube.ApplyMove(move); result.Multiply(moveCube); } Assert.AreEqual(expected, result); Assert.ThrowsException <ArgumentNullException>(() => CubieCube.CreateSolved().Multiply(null)); }
public void StaticTest(string algString) { Alg scramble = Alg.FromString(algString); CubieCube cube = CubieCube.FromAlg(scramble); TimeSpan timeout = TimeSpan.FromSeconds(1); int returnLength = 0; int requiredLength = 20; Alg solution = TwoPhaseSolver.FindSolution(cube, timeout, returnLength, requiredLength); Console.WriteLine("Scramble: " + 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 ConjugateCoCoordinateTest() { Assert.AreEqual(2187, SymmetryReduction.ConjugateCornerOrientationCoordinate.GetLength(0)); Assert.AreEqual(16, SymmetryReduction.ConjugateCornerOrientationCoordinate.GetLength(1)); CubieCube coordCube = CubieCube.CreateSolved(); for (int co = 0; co < NumCornerOrientations; co++) { SetCornerOrientation(coordCube, co); for (int sym = 0; sym < NumSymmetriesDh4; sym++) { CubieCube symCube = Symmetries.SymmetryCubes[sym].Clone(); symCube.Multiply(coordCube); symCube.Multiply(Symmetries.SymmetryCubes[Symmetries.InverseIndex[sym]]); CubieCube result = CubieCube.CreateSolved(); SetCornerOrientation(result, SymmetryReduction.ConjugateCornerOrientationCoordinate[co, sym]); CollectionAssert.AreEqual(symCube.CornerOrientation, result.CornerOrientation); } } }
static SymmetryReduction() { //avoid naming conflicts CubieCube cube; int reducedEoEquator, reducedCornerPermutation; #region initialize ConjugateCoCoordinate ConjugateCornerOrientationCoordinate = new int[NumCornerOrientations, NumSymmetriesDh4]; //invalidate for (int cornerOrientation = 0; cornerOrientation < NumCornerOrientations; cornerOrientation++) { for (int symmetryIndex = 0; symmetryIndex < NumSymmetriesDh4; symmetryIndex++) { ConjugateCornerOrientationCoordinate[cornerOrientation, symmetryIndex] = -1; } } //populate cube = CubieCube.CreateSolved(); for (int cornerOrientation = 0; cornerOrientation < NumCornerOrientations; cornerOrientation++) { cube.IsMirrored = false; //TEST if necessary SetCornerOrientation(cube, cornerOrientation); for (int symmetryIndex = 0; symmetryIndex < NumSymmetriesDh4; symmetryIndex++) { //conjugate cube CubieCube symmetryCube = SymmetryCubes[symmetryIndex].Clone(); symmetryCube.MultiplyCorners(cube); symmetryCube.MultiplyCorners(SymmetryCubes[InverseIndex[symmetryIndex]]); //store result ConjugateCornerOrientationCoordinate[cornerOrientation, symmetryIndex] = GetCornerOrientation(symmetryCube); } } #endregion initialize ConjugateCoCoordinate //TODO simplify #region initialize ReduceEoEquatorCoordinate, ExpandEoEquatorCoordinate and EoEquatorReductionSymmetry //initialize and invalidate ReduceEoEquatorCoordinate = Enumerable.Repeat(-1, NumEquatorDistributions * NumEdgeOrientations) .ToArray(); ExpandEoEquatorCoordinate = Enumerable.Repeat(-1, NumEoEquatorSymmetryClasses) .ToArray(); EoEquatorReductionSymmetry = Enumerable.Repeat(-1, NumEquatorDistributions * NumEdgeOrientations) .ToArray(); //populate cube = CubieCube.CreateSolved(); reducedEoEquator = 0; for (int equatorDistribution = 0; equatorDistribution < NumEquatorDistributions; equatorDistribution++) { SetEquatorDistribution(cube, equatorDistribution); for (int edgeOrientation = 0; edgeOrientation < NumEdgeOrientations; edgeOrientation++) { int eoEquator = NumEdgeOrientations * equatorDistribution + edgeOrientation; if (ReduceEoEquatorCoordinate[eoEquator] == -1) { SetEdgeOrientation(cube, edgeOrientation); //store representative ReduceEoEquatorCoordinate[eoEquator] = reducedEoEquator; EoEquatorReductionSymmetry[eoEquator] = 0; ExpandEoEquatorCoordinate[reducedEoEquator] = eoEquator; //go through all symmetries of the current cube and set //their reduced index to the same full index for (int symmetryIndex = 0; symmetryIndex < NumSymmetriesDh4; symmetryIndex++) { //symmetry ^ -1 * cube * symmetry CubieCube symCube = SymmetryCubes[InverseIndex[symmetryIndex]].Clone(); symCube.MultiplyEdges(cube); symCube.MultiplyEdges(SymmetryCubes[symmetryIndex]); //store int newEdgeOrientation = GetEdgeOrientation(symCube); int newEquatorDistribution = GetEquatorDistribution(symCube); int newEoEquator = NumEdgeOrientations * newEquatorDistribution + newEdgeOrientation; //TODO test if necessary if (ReduceEoEquatorCoordinate[newEoEquator] == -1) { ReduceEoEquatorCoordinate[newEoEquator] = reducedEoEquator; EoEquatorReductionSymmetry[newEoEquator] = symmetryIndex; } } reducedEoEquator++; } } } #endregion initialize ReduceEoEquatorCoordinate, ExpandEoEquatorCoordinate and EoEquatorReductionSymmetry #region initialize EoEquatorSymmetries //initialize and invalidate EoEquatorSymmetries = Enumerable.Repeat(0, NumEoEquatorSymmetryClasses) .ToArray(); //populate cube = CubieCube.CreateSolved(); for (reducedEoEquator = 0; reducedEoEquator < NumEoEquatorSymmetryClasses; reducedEoEquator++) { //set cube to the representative of the reduced index int eoEquator = ExpandEoEquatorCoordinate[reducedEoEquator]; SetEoEquatorCoord(cube, eoEquator); //find all symmetries of the cube for (int symmetryIndex = 0; symmetryIndex < NumSymmetriesDh4; symmetryIndex++) { //symmetry * cube * symmetry ^ -1 CubieCube symmetryCube = SymmetryCubes[symmetryIndex].Clone(); symmetryCube.MultiplyEdges(cube); symmetryCube.MultiplyEdges(SymmetryCubes[InverseIndex[symmetryIndex]]); //set flag if symmetrical int newEoEquator = GetEoEquatorCoord(symmetryCube); if (eoEquator == newEoEquator) { EoEquatorSymmetries[reducedEoEquator] |= 1 << symmetryIndex; } } } #endregion initialize EoEoquatorSymmetries #region initialize ConjugateUdEdgeOrderCoordinate ConjugateUdEdgeOrderCoordinate = new int[NumUdEdgeOrders, NumSymmetriesDh4]; //invalidate for (int udEdgeOrders = 0; udEdgeOrders < NumUdEdgeOrders; udEdgeOrders++) { for (int symmetryIndex = 0; symmetryIndex < NumSymmetriesDh4; symmetryIndex++) { ConjugateUdEdgeOrderCoordinate[udEdgeOrders, symmetryIndex] = -1; } } //populate cube = CubieCube.CreateSolved(); for (int udEdgePermutation = 0; udEdgePermutation < NumUdEdgeOrders; udEdgePermutation++) { SetUdEdgeOrder(cube, udEdgePermutation); for (int symmetryIndex = 0; symmetryIndex < NumSymmetriesDh4; symmetryIndex++) { //conjugate cube CubieCube symmetryCube = SymmetryCubes[symmetryIndex].Clone(); symmetryCube.MultiplyEdges(cube); symmetryCube.MultiplyEdges(SymmetryCubes[InverseIndex[symmetryIndex]]); //store result ConjugateUdEdgeOrderCoordinate[udEdgePermutation, symmetryIndex] = GetUdEdgeOrder(symmetryCube); } } #endregion initialize ConjugateUdEdgeOrderCoordinate #region initialize ReduceCpCoordinate, ExpandCpCoordinate and CpReductionSymmetry //initialize and invalidate ReduceCornerPermutationCoordinate = Enumerable.Repeat(-1, NumCornerPermutations) .ToArray(); ExpandCornerPermutationCoordinate = Enumerable.Repeat(-1, NumCornerPermutationSymmetryClasses) .ToArray(); CornerPermutationReductionSymmetry = Enumerable.Repeat(-1, NumCornerPermutations) .ToArray(); //populate cube = CubieCube.CreateSolved(); reducedCornerPermutation = 0; for (int cornerPermutation = 0; cornerPermutation < NumCornerPermutations; cornerPermutation++) { if (ReduceCornerPermutationCoordinate[cornerPermutation] == -1) { cube.IsMirrored = false; //TEST if necessary SetCornerPermutation(cube, cornerPermutation); //store representative ReduceCornerPermutationCoordinate[cornerPermutation] = reducedCornerPermutation; CornerPermutationReductionSymmetry[cornerPermutation] = 0; ExpandCornerPermutationCoordinate[reducedCornerPermutation] = cornerPermutation; //go through all symmetries of the current cube and set //their reduced index to the same full index for (int symmetryIndex = 0; symmetryIndex < NumSymmetriesDh4; symmetryIndex++) { //symmetry ^ -1 * cube * symmetry CubieCube symmetryCube = SymmetryCubes[InverseIndex[symmetryIndex]].Clone(); symmetryCube.MultiplyCorners(cube); symmetryCube.MultiplyCorners(SymmetryCubes[symmetryIndex]); //store int newCornerPermutation = GetCornerPermutation(symmetryCube); //TODO test if necessary if (ReduceCornerPermutationCoordinate[newCornerPermutation] == -1) { ReduceCornerPermutationCoordinate[newCornerPermutation] = reducedCornerPermutation; CornerPermutationReductionSymmetry[newCornerPermutation] = symmetryIndex; } } reducedCornerPermutation++; } } #endregion initialize ReduceCpCoordinate, ExpandCpCoordinate and CpReductionSymmetry #region initialize CpSymmetries CornerPermutationSymmetries = Enumerable.Repeat(0, NumCornerPermutationSymmetryClasses) .ToArray(); cube = CubieCube.CreateSolved(); for (reducedCornerPermutation = 0; reducedCornerPermutation < NumCornerPermutationSymmetryClasses; reducedCornerPermutation++) { //set cube to the representative of the reduced index int cornerPermutation = ExpandCornerPermutationCoordinate[reducedCornerPermutation]; SetCornerPermutation(cube, cornerPermutation); //find all symmetries of the cube for (int symmetryIndex = 0; symmetryIndex < NumSymmetriesDh4; symmetryIndex++) { //symmetry * cube * symmetry ^ -1 CubieCube symmetryCube = SymmetryCubes[symmetryIndex].Clone(); symmetryCube.MultiplyCorners(cube); symmetryCube.MultiplyCorners(SymmetryCubes[InverseIndex[symmetryIndex]]); //set flag if symmetrical int newCornerPermutation = GetCornerPermutation(symmetryCube); if (cornerPermutation == newCornerPermutation) { CornerPermutationSymmetries[reducedCornerPermutation] |= 1 << symmetryIndex; } } } #endregion initialize CpSymmetries }
public void GetHashCodeTest() { Assert.ThrowsException <NotImplementedException>(() => CubieCube.CreateSolved().GetHashCode()); }