def test_any_cube_with_just_one_move_is_solved(): for move in Cube.moves: cube = Cube() cube.twist_by_notation(move) result = Simple(cube).solve() cube.twist_by_notation(result[1]) assert cube.is_solved
def test_any_random_cube_is_solved(): for _ in range(TEST_SIZE): cube = Cube() cube.scramble() result = Simple(cube).solve() cube.twist_by_notation(result[1]) assert cube.is_solved
def test_cube_is_solved_after_reset(): cube = Cube() cube.scramble() cube.twist(2) cube.twist_by_notation("U2 B D'") cube.reset() assert cube.is_solved
def test_checkerboard_is_solved_with_6_moves(): cube = Cube() cube.twist_by_notation("U2 D2 F2 B2 L2 R2") solution = Kociemba(copy.deepcopy(cube)).solve() assert solution[0] == 6 cube.twist_by_notation(solution[1]) assert cube.is_solved
def test_a_cube_in_G1_with_4_moves_is_solved(): cube = Cube() cube.twist_by_notation("U R2 B2 D'") solution = Kociemba(copy.deepcopy(cube)).solve() assert solution[0] > 0 and len(solution[1]) > 0 cube.twist_by_notation(solution[1]) assert cube.is_solved
def test_cubes_in_G1_with_4_random_moves_are_solved(): for _ in range(5): cube = Cube() cube.scramble_g1(4) solution = Kociemba(copy.deepcopy(cube)).solve() assert solution[0] >= 0 and len(solution[1]) >= 0 cube.twist_by_notation(solution[1]) assert cube.is_solved
def test_all_cubes_with_one_move_are_solved(): for move in Cube.moves: cube = Cube() cube.twist_by_notation(move) solution = Kociemba(copy.deepcopy(cube)).solve() assert solution[0] >= 1 cube.twist_by_notation(solution[1]) assert cube.is_solved
def test_coordinate_corner_permutation_is_correct_for_CUBE_IN_THE_CUBE(): cube = Cube() cube.twist_by_notation(CUBE_IN_THE_CUBE_NOTATION) assert cube.coordinate_corner_permutation == 25980
def test_coordinate_corner_permutation_is_21021_after_R_turn(): cube = Cube() cube.twist_by_notation("R") assert cube.coordinate_corner_permutation == 21021
def test_CUBE_IN_THE_CUBE_is_not_domino(): cube = Cube() cube.twist_by_notation(CUBE_IN_THE_CUBE_NOTATION) assert not cube.is_domino
def test_CHECKERBOARD_pattern_with_notation(): cube = Cube() cube.twist_by_notation(CHECKERBOARD_NOTATION) assert cube.cube_string == CHECKERBOARD
def test_coordinate_ud_slice_phase2_is_correct_after_R2_L2(): cube = Cube() cube.twist_by_notation("R2 L2") assert cube.coordinate_ud_slice_phase2 == 23
def test_edge_pattern_second_is_correct_for_checkerboard(): cube = Cube() cube.twist_by_notation(CHECKERBOARD_NOTATION) assert Korf.edge_pattern_second(cube) == 121008
def test_edge_pattern_first_is_correct_for_checkerboard(): cube = Cube() cube.twist_by_notation(CHECKERBOARD_NOTATION) assert Korf.edge_pattern_first(cube) == 365136
class CubeSolver: """A class providing the UI of the CubeSolver application. The method check_notation can be used to check if a string of simple cube notations is valid. And the UI itself can be started by running the method start.""" def __init__(self): print("Initializing...", end="", flush=True) self.__cube = Cube() self.__simple = Simple(self.__cube) self.__kociemba = Kociemba(self.__cube) self.__korf = Korf(self.__cube) print(" Done.\n") def __choose_method(self): print("\nAvailable solving methods:") print("0 - Simple method (fast, a lot of moves)") print("1 - Kociemba's algorithm (slower, fewer moves") print("2 - Korf's algorithm (slowest, fewest moves") print("(r or q - return to the main menu)") while True: method = input("\nMethod: ") if method in ["r", "q"]: print() break start_time = time.time() solution = (-1, "") if method == "0": self.__simple.set_cube(self.__cube) solution = self.__simple.solve() elif method == "1": self.__kociemba.set_cube(self.__cube) solution = self.__kociemba.solve() elif method == "2": print() self.__korf.set_cube(self.__cube) solution = self.__korf.solve() else: print("Invalid option") return total_time = time.time() - start_time if solution[0] < 0: print(f"\nCouldn't find a solution in {total_time:.3f}" + " seconds.") else: print(f"\nFound solution: {solution[1]} with {solution[0]} " + f"turns in {total_time:.3f} seconds.") def __play(self): print("\nMoves should be given with the basic cube notation.") print("r or q will return to the main menu.\n") print(f"{self.__cube}\n") while True: notation = input("Next move(s): ").strip() if notation in ["r", "q"]: print() break if self.check_notation(notation): self.__cube.twist_by_notation(notation) else: print("Invalid notation!") print(f"\n{self.__cube}\n") @staticmethod def check_notation(notation: str) -> bool: """A function to check the validity of a string containing cube notation. For example the notation 'F2 B2 L2 R2 D2 U2' is valid but 'U3', 'U-1', 'M', 'X', 'Y', or 'Z' are not valid.""" if len(notation) == 0: return False for note in notation.split(" "): if note[0] not in ["U", "R", "F", "L", "B", "D"]: return False if len(note) > 2: return False if len(note) == 2 and note[1] not in ["'", "2"]: return False return True @staticmethod def __list_commands() -> None: print("Available commands:") print("0 - scramble (or 'g' for scramble in <U,D,L2,R2,F2,B2>") print("1 - solve") print("2 - play") print("3 - reset") print("q - quit") def start(self) -> None: """A function containing the main loop for the programs UI.""" while True: print(f"{self.__cube}\n") self.__list_commands() command = input("\nCommand: ").lower() if command == 'q': break if command == '0': scramble = self.__cube.scramble() print(f"\nScramble: {scramble}\n") elif command == 'g': scramble = self.__cube.scramble_g1() print(f"\nScramble: {scramble}\n") elif command == '1': self.__choose_method() elif command == '2': self.__play() elif command == '3': print() self.__cube.reset() else: print("\nInvalid command!\n")
def test_coordinate_edge_permutation_is_correct_after_R2_U2_R2(): cube = Cube() cube.twist_by_notation("R2 U2 R2") assert cube.coordinate_edge_permutation == 60
def test_coordinate_edge_permutation_is_correct_for_CHECKERBOARD(): cube = Cube() cube.twist_by_notation(CHECKERBOARD_NOTATION) assert cube.coordinate_edge_permutation == 35152
def test_edges_of_CUBE_IN_THE_CUBE_are_correct(): cube = Cube() cube.twist_by_notation(CUBE_IN_THE_CUBE_NOTATION) assert cube.edges == CUBE_IN_THE_CUBE_EDGES
def test_coordinate_ud_slice_phase2_of_CHECKERBOARD_is_correct(): cube = Cube() cube.twist_by_notation(CHECKERBOARD_NOTATION) assert cube.coordinate_ud_slice_phase2 == 16
def test_R2_L2_is_not_solved(): cube = Cube() cube.twist_by_notation("R2 L2") assert not cube.is_solved
def test_CUBE_IN_THE_CUBE_pattern(): cube = Cube() cube.twist_by_notation(CUBE_IN_THE_CUBE_NOTATION) assert cube.cube_string == CUBE_IN_THE_CUBE
def test_coordinate_corner_orientation_is_correct_after_R(): cube = Cube() cube.twist_by_notation("R") assert cube.coordinate_corner_orientation == 1494
def test_CHECKERBOARD_is_domino(): cube = Cube() cube.twist_by_notation(CHECKERBOARD_NOTATION) assert cube.is_domino
def test_coordinate_edge_orientation_is_not_0_after_rB_rR(): cube = Cube() cube.twist_by_notation("B' R'") assert cube.coordinate_edge_orientation != 0
def test_empty_notation_doesnt_affect_the_cube(): cube = Cube() cube.twist_by_notation("") assert cube.is_solved
def test_coordinate_ud_slice_is_correct_after_R_L_D_F2_B2(): cube = Cube() cube.twist_by_notation("R L D F2 B2") assert cube.coordinate_ud_slice == 494