def get_depth_phase1(self): slice_ = self.slice_sorted // N_PERM_4 flip = self.flip twist = self.twist flipslice = N_FLIP * slice_ + flip classidx = sy.flipslice_classidx[flipslice] sym = sy.flipslice_sym[flipslice] depth_mod3 = pr.get_flipslice_twist_depth3(N_TWIST * classidx + sy.twist_conj[(twist << 4) + sym]) depth = 0 while flip != SOLVED or slice_ != SOLVED or twist != SOLVED: if depth_mod3 == 0: depth_mod3 = 3 for m in enums.Move: twist1 = mv.twist_move[N_MOVE * twist + m] flip1 = mv.flip_move[N_MOVE * flip + m] slice1 = mv.slice_sorted_move[N_MOVE * slice_ * N_PERM_4 + m] // N_PERM_4 flipslice1 = N_FLIP * slice1 + flip1 classidx1 = sy.flipslice_classidx[flipslice1] sym = sy.flipslice_sym[flipslice1] if pr.get_flipslice_twist_depth3( N_TWIST * classidx1 + sy.twist_conj[(twist1 << 4) + sym]) == depth_mod3 - 1: depth += 1 twist = twist1 flip = flip1 slice_ = slice1 depth_mod3 -= 1 break return depth
def search(self, flip, twist, slice_sorted, dist, togo_phase1): # ############################################################################################################## if self.terminated.is_set(): return ################################################################################################################ if togo_phase1 == 0: # phase 1 solved # if time.monotonic() > self.start_time + self.timeout and len(self.solutions) > 0: if 1000*(time.clock() - self.start_time) > self.timeout and len(self.solutions) > 0: self.terminated.set() # compute initial phase 2 coordinates if self.sofar_phase1: # check if list is not empty m = self.sofar_phase1[-1] else: m = en.Move.U1 # value is irrelevant here, no phase 1 moves if m in [en.Move.R3, en.Move.F3, en.Move.L3, en.Move.B3]: # phase 1 solution come in pairs corners = mv.corners_move[18 * self.cornersave + m - 1] # apply R2, F2, L2 ord B2 on last ph1 solution else: corners = self.co_cube.corners for m in self.sofar_phase1: # get current corner configuration corners = mv.corners_move[18 * corners + m] self.cornersave = corners # new solution must be shorter and we do not use phase 2 maneuvers with length > 11 - 1 = 10 togo2_limit = min(self.shortest_length[0] - len(self.sofar_phase1), 11) if pr.cornslice_depth[24 * corners + slice_sorted] >= togo2_limit: # this precheck speeds up the computation return u_edges = self.co_cube.u_edges d_edges = self.co_cube.d_edges for m in self.sofar_phase1: u_edges = mv.u_edges_move[18 * u_edges + m] d_edges = mv.d_edges_move[18 * d_edges + m] ud_edges = coord.u_edges_plus_d_edges_to_ud_edges[24 * u_edges + d_edges % 24] dist2 = self.co_cube.get_depth_phase2(corners, ud_edges) for togo2 in range(dist2, togo2_limit): # do not use more than togo2_limit - 1 moves in phase 2 self.sofar_phase2 = [] self.search_phase2(corners, ud_edges, slice_sorted, dist2, togo2) else: for m in en.Move: # dist = 0 means that we are already are in the subgroup H. If there are less than 5 moves left # this forces all remaining moves to be phase 2 moves. So we can forbid these at the end of phase 1 # and generate these moves in phase 2. if dist == 0 and togo_phase1 < 5 and m in [en.Move.U1, en.Move.U2, en.Move.U3, en.Move.R2, en.Move.F2, en.Move.D1, en.Move.D2, en.Move.D3, en.Move.L2, en.Move.B2]: continue if len(self.sofar_phase1) > 0: diff = self.sofar_phase1[-1] // 3 - m // 3 if diff in [0, 3]: # successive moves: on same face or on same axis with wrong order continue flip_new = mv.flip_move[18 * flip + m] # N_MOVE = 18 twist_new = mv.twist_move[18 * twist + m] slice_sorted_new = mv.slice_sorted_move[18 * slice_sorted + m] flipslice = 2048 * (slice_sorted_new // 24) + flip_new # N_FLIP * (slice_sorted // N_PERM_4) + flip classidx = sy.flipslice_classidx[flipslice] sym = sy.flipslice_sym[flipslice] dist_new_mod3 = pr.get_flipslice_twist_depth3(2187 * classidx + sy.twist_conj[(twist_new << 4) + sym]) dist_new = pr.distance[3 * dist + dist_new_mod3] if dist_new >= togo_phase1: # impossible to reach subgroup H in togo_phase1 - 1 moves continue self.sofar_phase1.append(m) self.search(flip_new, twist_new, slice_sorted_new, dist_new, togo_phase1 - 1) self.sofar_phase1.pop(-1)