Beispiel #1
0
    def make_cube():
        from solve import simplify_algorithm
        from cube import Rotation

        scramble = [
            Rotation(step) for step in "R2 U R U' B U' L F' L' D2".split()
        ]
        cross_solve = [Rotation(step) for step in "D' B2 D' F B".split()]
        setup = simplify_algorithm(scramble + cross_solve)

        print('Scrambling:', ' '.join(map(str, setup)))
        return Cube(setup)
Beispiel #2
0
 def solve(self):
     u_cubies = set(
         filter(
             lambda cubie: Side.U in cubie.faces and len(cubie.faces) > 1,
             self.cube.cubies))
     positions = {
         _positions[_cubie_set(cubie.faces)]:
         _positions[_cubie_set(cubie.faces.values())]
         for cubie in u_cubies
     }
     positions = tuple(positions[i] for i in range(len(positions)))
     prefix = ''
     while positions not in cases:
         prefix += 'U '
         positions = tuple(positions[-2:] + positions[:-2])
         if not simplify_algorithm([Rotation(s) for s in prefix.split()]):
             raise NotImplementedError(f"Case not handled: {positions}")
     return simplify_algorithm(
         [Rotation(step) for step in (prefix + cases[positions]).split()])
Beispiel #3
0
 def solve(self):
     solved_cube = Cube()
     goals = {self.cross_state(solved_cube): []}
     for i in range(3):
         for state, path in tuple(filter(lambda kv: len(kv[1]) == i, goals.items())):
             successors = self.successors(path, solved_cube)
             goals.update({s: p for s, p in successors.items() if s not in goals})
     # Reverse algorithms in goals
     goals = {k: [Rotation(r).reverse().name for r in v[::-1]] for k, v in goals.items()}
     goals_set = set(goals)
     start_state = self.cross_state(self.cube)
     paths = new_paths = {start_state: []}
     while not (goals_set & set(new_paths)):
         next_paths = {}
         for state, path in new_paths.items():
             successors = self.successors(path)
             next_paths.update({s: p for s, p in successors.items() if s not in paths})
         paths.update(next_paths)
         new_paths = next_paths
     state = (goals_set & set(paths)).pop()
     return [Rotation(step) for step in paths[state] + goals[state]]
Beispiel #4
0
    def solve(self):
        # Get list of how many clockwise twists/flips each cubie needs, starting with LUB and working clockwise
        u_cycle = Rotation('U').seq
        cubies = [
            self.cube['U' + loc]
            for loc in ('LB', 'B', 'RB', 'R', 'RF', 'F', 'LF', 'L')
        ]

        def count_rotations(cubie):
            u_loc = {v: k for k, v in cubie.faces.items()}[Side.U]
            if u_loc == Side.U:
                return 0
            elif u_cycle[u_loc] in cubie.faces:
                return 2
            else:
                return 1

        states = tuple(count_rotations(c) for c in cubies)
        prefix = ''
        while states not in cases:
            prefix += 'U '
            states = tuple(states[-2:] + states[:-2])
        return simplify_algorithm(
            [Rotation(step) for step in (prefix + cases[states]).split()])
Beispiel #5
0
def _combine_rotations(r1, r2):
    if isinstance(r1, str):
        r1 = Rotation(r1)
    if isinstance(r2, str):
        r2 = Rotation(r2)
    if r1.face != r2.face:
        raise ValueError("Cannot combine rotations from different faces")
    base_seq = Rotation(r1.face.name).seq
    seq = {k: r2.seq[v] for k, v in r1.seq.items()}
    count_seq = {k: k for k in seq}
    quarter_turns = 0
    while count_seq != seq:
        count_seq = {k: base_seq[v] for k, v in count_seq.items()}
        quarter_turns += 1
    if quarter_turns == 0:
        return Rotation(None)
    modifier = {1: '', 2: '2', 3: "'"}[quarter_turns]
    rot = Rotation(r1)
    rot.seq = seq
    rot.name = rot.name[0] + modifier
    return rot
Beispiel #6
0
def get_case_solution(pair):
    permuter = Rotation('U')
    permuter.seq[Side.U] = Side.U
    permuter.seq[Side.D] = Side.D
    edge, corner = pair.edge.copy(), pair.corner.copy()
    if all(k == v for k, v in edge.faces.items()) and all(
            k == v for k, v in corner.faces.items()):
        return []
    algorithm = []

    if Side.U not in edge.faces and set(edge.faces) != set(
            edge.faces.values()):
        # The edge is not in the U layer, but it's also not in its own slot. Come back to this pair.
        return None
    if Side.D in corner.faces and set(corner.faces) != set(
            corner.faces.values()):
        # The corner is in the D layer, but it's also not in its own slot. Come back to this pair.
        return None

    # There are two types of transformation to be used. The transform rotation is the number of y turns to do in order
    # to simplify the case down to the RF edge pair, which simplifies algorithm lookup. The alignment rotation is the
    # number of U turns to prepend to the algorithm.
    transform_rotations = 0
    while not set(edge.faces.values()) == {Side.R, Side.F}:
        edge.faces = {
            permuter.seq[k]: permuter.seq[v]
            for k, v in edge.faces.items()
        }
        corner.faces = {
            permuter.seq[k]: permuter.seq[v]
            for k, v in corner.faces.items()
        }
        transform_rotations -= 1
    transform_rotations %= 4
    # How many U turns are needed to align? If the corner is in the U face, then in needs to be in the RUF position.
    # Otherwise, the edge needs to be lined up so that the side lines up (UF->RF or RU->RF)
    if Side.U in corner.faces:
        while not set(edge.faces.values()) <= set(corner.faces):
            edge.faces = {permuter.seq[k]: v for k, v in edge.faces.items()}
            corner.faces = {
                permuter.seq[k]: v
                for k, v in corner.faces.items()
            }
            algorithm.append(Rotation('U'))
    elif Side.U in edge.faces:
        while not any(k == v for k, v in edge.faces.items()):
            edge.faces = {
                permuter.seq[k2]: v2
                for k2, v2 in edge.faces.items()
            }
            algorithm.append(Rotation('U'))

    # List the cases! 42 total. Case numbers are according to https://www.speedsolving.com/wiki/index.php/F2L
    base = ''
    if Side.D in corner.faces:  # Corner in place
        if Side.U in edge.faces:  # Edge in U layer
            if corner.D == Side.D:  # Corner oriented
                if edge.U == Side.F:
                    # Case 25
                    base = "U' R' F R F' R U R'"
                else:
                    # Case 26
                    base = "U R U' R' U' F' U F"
            elif corner.F == Side.D:  # D color on F face
                if edge.U == Side.F:
                    # Case 27
                    base = "R U' R' U R U' R'"
                else:
                    # Case 29
                    base = "F' U' F U F' U' F"
            elif corner.R == Side.D:  # D color on R face
                if edge.U == Side.F:
                    # Case 30
                    base = "R U R' U' R U R'"
                else:
                    # Case 28
                    base = "R U R' U' F R' F' R"
        else:  # Edge in place
            if all(k == v for k, v in edge.faces.items()):  # Edge solved
                if corner.D == Side.D:  # Corner is in place and oriented
                    # Case 37 (solved)
                    pass
                elif corner.F == Side.D:
                    # Case 39
                    base = "R U' R' U' R U R' U2 R U' R'"
                else:
                    # Case 40
                    base = "R U' R' U R U2 R' U R U' R'"
            else:  # Edge twisted
                if corner.D == Side.D:  # Corner in place and oriented
                    # Case 38
                    base = "R' F R F' R U' R' U R U' R' U2 R U' R'"
                elif corner.F == Side.D:
                    # Case 41
                    base = "R U' R' U F' U' F U' F' U' F"
                else:
                    # Case 42
                    base = "R U' R' U2 F' U' F U' F' U F"
    else:  # Corner in U face
        if Side.U in edge.faces:  # Edge in U layer
            if corner.F == Side.D:  # D color on F face
                if edge.U == Side.F:
                    if Side.L in edge.faces:
                        # Case 7
                        base = "U' R U2 R' U2 R U' R'"
                    elif Side.R in edge.faces:
                        # Case 1
                        base = "U R U' R'"
                    elif Side.F in edge.faces:
                        # Case 15
                        base = "R B L U' L' B' R'"
                    elif Side.B in edge.faces:
                        # Case 5
                        base = "U' R U R' U2 R U' R'"
                else:  # Edge's R color on U face
                    if Side.L in edge.faces:
                        # Case 3
                        base = "F' U' F"
                    elif Side.R in edge.faces:
                        # Case 11
                        base = "U' R U2 R' U F' U' F"
                    elif Side.F in edge.faces:
                        # Case 13
                        base = "U F' U F U' F' U' F"
                    elif Side.B in edge.faces:
                        # Case 9
                        base = "U' R U' R' U F' U' F"
            elif corner.R == Side.D:  # D color on R face
                if edge.U == Side.F:
                    if Side.L in edge.faces:
                        # Case 10
                        base = "U' R U R' U R U R'"
                    elif Side.R in edge.faces:
                        # Case 14
                        base = "U' R U' R' U R U R'"
                    elif Side.F in edge.faces:
                        # Case 12
                        base = "R U' R' U R U' R' U2 R U' R'"
                    elif Side.B in edge.faces:
                        # Case 4
                        base = "R U R'"
                else:  # Edge's R color on U face
                    if Side.L in edge.faces:
                        # Case 6
                        base = "U F' U' F U2 F' U F"
                    elif Side.R in edge.faces:
                        # Case 16
                        base = "R U' R' U2 F' U' F"
                    elif Side.F in edge.faces:
                        # Case 2
                        base = "U' F' U F"
                    else:  # Side.B
                        # Case 8
                        base = "U F' U2 F U2 F' U F"
            else:  # D color on U face
                if edge.U == Side.F:
                    if Side.L in edge.faces:
                        # Case 21
                        base = "R U' R' U2 R U R'"
                    elif Side.R in edge.faces:
                        # Case 17
                        base = "R U2 R' U' R U R'"
                    elif Side.F in edge.faces:
                        # Case 23
                        base = "U2 R2 U2 R' U' R U' R2"
                    else:  # Side.B
                        # Case 19
                        base = "U R U2 R2 F R F'"
                else:  # Edge's R color on U face
                    if Side.L in edge.faces:
                        # Case 20
                        base = "U' F' U2 F2 R' F' R"
                    elif Side.R in edge.faces:
                        # Case 24
                        base = "U F' L' U L F R U R'"
                    elif Side.F in edge.faces:
                        # Case 18
                        base = "F' U2 F U F' U' F"
                    else:  # Side.B
                        # Case 22
                        base = "F' U F U2 F' U' F"
        else:  # (Corner in U Face), Edge in place
            if all(k == v for k, v in edge.faces.items()):  # Edge solved
                if corner.U == Side.U:
                    # Case 32
                    base = "R U R' U' R U R' U' R U R'"
                elif corner.F == Side.U:
                    # Case 33
                    base = "U' R U' R' U2 R U' R'"
                else:
                    # Case 34
                    base = "U F' U F U2 F' U F"
            else:  # Edge twisted
                if corner.U == Side.U:
                    # Case 31
                    base = "R U' R' U F' U F"
                elif corner.F == Side.U:
                    # Case 35
                    base = "U' R U R' U F' U' F"
                else:
                    # Case 36
                    base = "U F' U' F U' R U R'"

    algorithm.extend([Rotation(step) for step in base.split()])

    return rotate_algorithm(simplify_algorithm(algorithm), transform_rotations)
Beispiel #7
0
 def map_rotation(rotation):
     new_base = mapping[rotation.name[0]]
     name = new_base + rotation.name[1:]
     return Rotation(name)
Beispiel #8
0
    scramble = "F' U' B2 U2 L2 D' B L' U B L2 D B L F' R' B' R' F2 D F' R D' L2 U'"

    my_cube = Cube(scramble)
    my_cube.ascii()

    # cross_solve = CrossSolver(my_cube).solve()
    cross_solve = "B2 L2 D R' D' B' R"
    my_cube.do(cross_solve)
    # print('Cross solved:', ' '.join(r.name for r in cross_solve))
    # my_cube.ascii()

    # f2l_solve = F2LSolver(cube).solve()
    f2l_solve = "L' U' L U2 R U2 R2 F R F' U' B' U B U2 B' U' B B U' B' U' R' U R"
    my_cube.do(f2l_solve)
    # print('F2L solved', ' '.join(r.name for r in f2l_solve))
    print('Post-F2L:')
    my_cube.ascii()

    sleep(1)

    print(
        'Full prep:', ' '.join(s.name for s in simplify_algorithm(
            [Rotation(s) for s in scramble.split()] +
            [Rotation(s) for s in cross_solve.split()] +
            [Rotation(s) for s in f2l_solve.split()])))

    oll_solve = OLLSolver(my_cube).solve()
    my_cube.do(oll_solve)
    print('OLL solved', oll_solve)
    my_cube.ascii()