### Adding check for cross pieces, and tuple mapping function.

master
Charles Reid 2 years ago
parent
commit
742a5e8d37
1 changed files with 551 additions and 0 deletions
1. +551
-0
rubikscubennnsolver/__init__.py

#### + 551 - 0 rubikscubennnsolver/__init__.pyView File

 @@ -577,6 +577,557 @@ class RubiksCube(object): return False return True def rotation_map(self, action): """ This returns a set of tuples that correspond to the movements of each piece on the cube for the move "action". """ results = [] if action[-1] in ("'", "`"): reverse = True action = action[0:-1] else: reverse = False # 2Uw, Uw and 2U all mean rotate the top 2 U rows # 3Uw and 3U mean rotate the top 3 U rows if len(action) >= 2 and action[0].isdigit() and action[1].isdigit(): rows_to_rotate = int(action[0:2]) action = action[2:] elif action[0].isdigit(): rows_to_rotate = int(action[0]) action = action[1:] else: # Uw also means rotate the top 2 U rows if 'w' in action: rows_to_rotate = 2 else: rows_to_rotate = 1 # We've accounted for this so remove it if 'w' in action: action = action.replace('w', '') # The digit at the end indicates how many quarter turns to do if action[-1].isdigit(): quarter_turns = int(action[-1]) action = action[0:-1] else: quarter_turns = 1 side_name = action # Skip moves x, y, z side = self.sides[side_name] min_pos = side.min_pos max_pos = side.max_pos # Rotation of the squares of the face itself for turn in range(quarter_turns): # Number the squares of the faces # in a 2D array, then re-use all the # existing transforms oldface = [] counter = min_pos for ii in range(self.size): facerow = [] for jj in range(self.size): facerow.append(counter) counter += 1 oldface.append(facerow) # This is not what we want, because it returns # the face colors, not the face index numbers: #oldface = side.get_face_as_2d_list() if reverse: newface = rotate_counter_clockwise(oldface) else: newface = rotate_clockwise(oldface) oldface = compress_2d_list(oldface) newface = compress_2d_list(newface) for (j,k) in zip(oldface,newface): results.append((j,k)) # Again skip rotation of entire cube with x, y, z if side_name == "U": for turn in range(quarter_turns): # rotate the connecting row(s) of the surrounding sides for row in range(rows_to_rotate): left_first_square = self.squares_per_side + 1 + (row * self.size) left_last_square = left_first_square + self.size - 1 front_first_square = (self.squares_per_side * 2) + 1 + (row * self.size) front_last_square = front_first_square + self.size - 1 right_first_square = (self.squares_per_side * 3) + 1 + (row * self.size) right_last_square = right_first_square + self.size - 1 back_first_square = (self.squares_per_side * 4) + 1 + (row * self.size) back_last_square = back_first_square + self.size - 1 if reverse: for square_index in range(left_first_square, left_last_square + 1): old_index = square_index new_index = square_index + (3 * self.squares_per_side) results.append((old_index,new_index)) for square_index in range(front_first_square, front_last_square + 1): old_index = square_index new_index = square_index - self.squares_per_side results.append((old_index,new_index)) for square_index in range(right_first_square, right_last_square + 1): old_index = square_index new_index = square_index - self.squares_per_side results.append((old_index,new_index)) for square_index in range(back_first_square, back_last_square + 1): old_index = square_index new_index = square_index - self.squares_per_side results.append((old_index,new_index)) else: for square_index in range(left_first_square, left_last_square + 1): old_index = square_index new_index = square_index + self.squares_per_side results.append((old_index,new_index)) for square_index in range(front_first_square, front_last_square + 1): old_index = square_index new_index = square_index + self.squares_per_side results.append((old_index,new_index)) for square_index in range(right_first_square, right_last_square + 1): old_index = square_index new_index = square_index + self.squares_per_side results.append((old_index,new_index)) for square_index in range(back_first_square, back_last_square + 1): old_index = square_index new_index = square_index - (3 * self.squares_per_side) results.append((old_index,new_index)) elif side_name == "L": for turn in range(quarter_turns): # rotate the connecting row(s) of the surrounding sides for row in range(rows_to_rotate): top_first_square = 1 + row top_last_square = top_first_square + ((self.size - 1) * self.size) front_first_square = (self.squares_per_side * 2) + 1 + row front_last_square = front_first_square + ((self.size - 1) * self.size) down_first_square = (self.squares_per_side * 5) + 1 + row down_last_square = down_first_square + ((self.size - 1) * self.size) back_first_square = (self.squares_per_side * 4) + self.size - row back_last_square = back_first_square + ((self.size - 1) * self.size) top_squares = [] for square_index in range(top_first_square, top_last_square + 1, self.size): top_squares.append(square_index) front_squares = [] for square_index in range(front_first_square, front_last_square + 1, self.size): front_squares.append(square_index) down_squares = [] for square_index in range(down_first_square, down_last_square + 1, self.size): down_squares.append(square_index) back_squares = [] for square_index in range(back_first_square, back_last_square + 1, self.size): back_squares.append(square_index) if reverse: for (index, square_index) in enumerate(range(top_first_square, top_last_square + 1, self.size)): old_index = square_index new_index = front_squares[index] results.append((old_index,new_index)) for (index, square_index) in enumerate(range(front_first_square, front_last_square + 1, self.size)): old_index = square_index new_index = down_squares[index] results.append((old_index,new_index)) back_squares = list(reversed(back_squares)) for (index, square_index) in enumerate(range(down_first_square, down_last_square + 1, self.size)): old_index = square_index new_index = back_squares[index] results.append((old_index,new_index)) top_squares = list(reversed(top_squares)) for (index, square_index) in enumerate(range(back_first_square, back_last_square + 1, self.size)): old_index = square_index new_index = top_squares[index] results.append((old_index,new_index)) else: back_squares = list(reversed(back_squares)) for (index, square_index) in enumerate(range(top_first_square, top_last_square + 1, self.size)): old_index = square_index new_index = back_squares[index] results.append((old_index,new_index)) for (index, square_index) in enumerate(range(front_first_square, front_last_square + 1, self.size)): old_index = square_index new_index = top_squares[index] results.append((old_index,new_index)) for (index, square_index) in enumerate(range(down_first_square, down_last_square + 1, self.size)): old_index = square_index new_index = front_squares[index] results.append((old_index,new_index)) down_squares = list(reversed(down_squares)) for (index, square_index) in enumerate(range(back_first_square, back_last_square + 1, self.size)): old_index = square_index new_index = down_squares[index] results.append((old_index,new_index)) elif side_name == "F": for turn in range(quarter_turns): # rotate the connecting row(s) of the surrounding sides for row in range(rows_to_rotate): top_first_square = (self.squares_per_side - self.size) + 1 - (row * self.size) top_last_square = top_first_square + self.size - 1 left_first_square = self.squares_per_side + self.size - row left_last_square = left_first_square + ((self.size - 1) * self.size) down_first_square = (self.squares_per_side * 5) + 1 + (row * self.size) down_last_square = down_first_square + self.size - 1 right_first_square = (self.squares_per_side * 3) + 1 + row right_last_square = right_first_square + ((self.size - 1) * self.size) #log.info("top first %d, last %d" % (top_first_square, top_last_square)) #log.info("left first %d, last %d" % (left_first_square, left_last_square)) #log.info("down first %d, last %d" % (down_first_square, down_last_square)) #log.info("right first %d, last %d" % (right_first_square, right_last_square)) top_squares = [] for square_index in range(top_first_square, top_last_square + 1): top_squares.append(square_index) left_squares = [] for square_index in range(left_first_square, left_last_square + 1, self.size): left_squares.append(square_index) down_squares = [] for square_index in range(down_first_square, down_last_square + 1): down_squares.append(square_index) right_squares = [] for square_index in range(right_first_square, right_last_square + 1, self.size): right_squares.append(square_index) if reverse: for (index, square_index) in enumerate(range(top_first_square, top_last_square + 1)): old_index = square_index new_index = right_squares[index] results.append((old_index,new_index)) top_squares = list(reversed(top_squares)) for (index, square_index) in enumerate(range(left_first_square, left_last_square + 1, self.size)): old_index = square_index new_index = top_squares[index] results.append((old_index,new_index)) for (index, square_index) in enumerate(range(down_first_square, down_last_square + 1)): old_index = square_index new_index = left_squares[index] results.append((old_index,new_index)) down_squares = list(reversed(down_squares)) for (index, square_index) in enumerate(range(right_first_square, right_last_square + 1, self.size)): old_index = square_index new_index = down_squares[index] results.append((old_index,new_index)) else: left_squares = list(reversed(left_squares)) for (index, square_index) in enumerate(range(top_first_square, top_last_square + 1)): old_index = square_index new_index = left_squares[index] results.append((old_index,new_index)) for (index, square_index) in enumerate(range(left_first_square, left_last_square + 1, self.size)): old_index = square_index new_index = down_squares[index] results.append((old_index,new_index)) right_squares = list(reversed(right_squares)) for (index, square_index) in enumerate(range(down_first_square, down_last_square + 1)): old_index = square_index new_index = right_squares[index] results.append((old_index,new_index)) for (index, square_index) in enumerate(range(right_first_square, right_last_square + 1, self.size)): old_index = square_index new_index = top_squares[index] results.append((old_index,new_index)) elif side_name == "R": for turn in range(quarter_turns): # rotate the connecting row(s) of the surrounding sides for row in range(rows_to_rotate): top_first_square = self.size - row top_last_square = self.squares_per_side front_first_square = (self.squares_per_side * 2) + self.size - row front_last_square = front_first_square + ((self.size - 1) * self.size) down_first_square = (self.squares_per_side * 5) + self.size - row down_last_square = down_first_square + ((self.size - 1) * self.size) back_first_square = (self.squares_per_side * 4) + 1 + row back_last_square = back_first_square + ((self.size - 1) * self.size) #log.info("top first %d, last %d" % (top_first_square, top_last_square)) #log.info("front first %d, last %d" % (front_first_square, front_last_square)) #log.info("down first %d, last %d" % (down_first_square, down_last_square)) #log.info("back first %d, last %d" % (back_first_square, back_last_square)) top_squares = [] for square_index in range(top_first_square, top_last_square + 1, self.size): top_squares.append(square_index) front_squares = [] for square_index in range(front_first_square, front_last_square + 1, self.size): front_squares.append(square_index) down_squares = [] for square_index in range(down_first_square, down_last_square + 1, self.size): down_squares.append(square_index) back_squares = [] for square_index in range(back_first_square, back_last_square + 1, self.size): back_squares.append(square_index) if reverse: back_squares = list(reversed(back_squares)) for (index, square_index) in enumerate(range(top_first_square, top_last_square + 1, self.size)): old_index = square_index new_index = back_squares[index] results.append((old_index,new_index)) for (index, square_index) in enumerate(range(front_first_square, front_last_square + 1, self.size)): old_index = square_index new_index = top_squares[index] results.append((old_index,new_index)) for (index, square_index) in enumerate(range(down_first_square, down_last_square + 1, self.size)): old_index = square_index new_index = front_squares[index] results.append((old_index,new_index)) down_squares = list(reversed(down_squares)) for (index, square_index) in enumerate(range(back_first_square, back_last_square + 1, self.size)): old_index = square_index new_index = down_squares[index] results.append((old_index,new_index)) else: for (index, square_index) in enumerate(range(top_first_square, top_last_square + 1, self.size)): old_index = square_index new_index = front_squares[index] results.append((old_index,new_index)) for (index, square_index) in enumerate(range(front_first_square, front_last_square + 1, self.size)): old_index = square_index new_index = down_squares[index] results.append((old_index,new_index)) back_squares = list(reversed(back_squares)) for (index, square_index) in enumerate(range(down_first_square, down_last_square + 1, self.size)): old_index = square_index new_index = back_squares[index] results.append((old_index,new_index)) top_squares = list(reversed(top_squares)) for (index, square_index) in enumerate(range(back_first_square, back_last_square + 1, self.size)): old_index = square_index new_index = top_squares[index] results.append((old_index,new_index)) elif side_name == "B": for turn in range(quarter_turns): # rotate the connecting row(s) of the surrounding sides for row in range(rows_to_rotate): top_first_square = 1 + (row * self.size) top_last_square = top_first_square + self.size - 1 left_first_square = self.squares_per_side + 1 + row left_last_square = left_first_square + ((self.size - 1) * self.size) down_first_square = (self.squares_per_side * 6) - self.size + 1 - (row * self.size) down_last_square = down_first_square + self.size - 1 right_first_square = (self.squares_per_side * 3) + self.size - row right_last_square = right_first_square + ((self.size - 1) * self.size) #log.info("top first %d, last %d" % (top_first_square, top_last_square)) #log.info("left first %d, last %d" % (left_first_square, left_last_square)) #log.info("down first %d, last %d" % (down_first_square, down_last_square)) #log.info("right first %d, last %d" % (right_first_square, right_last_square)) top_squares = [] for square_index in range(top_first_square, top_last_square + 1): top_squares.append(square_index) left_squares = [] for square_index in range(left_first_square, left_last_square + 1, self.size): left_squares.append(square_index) down_squares = [] for square_index in range(down_first_square, down_last_square + 1): down_squares.append(square_index) right_squares = [] for square_index in range(right_first_square, right_last_square + 1, self.size): right_squares.append(square_index) if reverse: left_squares = list(reversed(left_squares)) for (index, square_index) in enumerate(range(top_first_square, top_last_square + 1)): old_index = square_index new_index = left_squares[index] results.append((old_index,new_index)) for (index, square_index) in enumerate(range(left_first_square, left_last_square + 1, self.size)): old_index = square_index new_index = down_squares[index] results.append((old_index,new_index)) right_squares = list(reversed(right_squares)) for (index, square_index) in enumerate(range(down_first_square, down_last_square + 1)): old_index = square_index new_index = right_squares[index] results.append((old_index,new_index)) for (index, square_index) in enumerate(range(right_first_square, right_last_square + 1, self.size)): old_index = square_index new_index = top_squares[index] results.append((old_index,new_index)) else: for (index, square_index) in enumerate(range(top_first_square, top_last_square + 1)): old_index = square_index new_index = right_squares[index] results.append((old_index,new_index)) top_squares = list(reversed(top_squares)) for (index, square_index) in enumerate(range(left_first_square, left_last_square + 1, self.size)): old_index = square_index new_index = top_squares[index] results.append((old_index,new_index)) for (index, square_index) in enumerate(range(down_first_square, down_last_square + 1)): old_index = square_index new_index = left_squares[index] results.append((old_index,new_index)) down_squares = list(reversed(down_squares)) for (index, square_index) in enumerate(range(right_first_square, right_last_square + 1, self.size)): old_index = square_index new_index = down_squares[index] results.append((old_index,new_index)) elif side_name == "D": for turn in range(quarter_turns): # rotate the connecting row(s) of the surrounding sides for row in range(rows_to_rotate): left_first_square = (self.squares_per_side * 2) - self.size + 1 - (row * self.size) left_last_square = left_first_square + self.size - 1 front_first_square = (self.squares_per_side * 3) - self.size + 1 - (row * self.size) front_last_square = front_first_square + self.size - 1 right_first_square = (self.squares_per_side * 4) - self.size + 1 - (row * self.size) right_last_square = right_first_square + self.size - 1 back_first_square = (self.squares_per_side * 5) - self.size + 1 - (row * self.size) back_last_square = back_first_square + self.size - 1 #log.info("left first %d, last %d" % (left_first_square, left_last_square)) #log.info("front first %d, last %d" % (front_first_square, front_last_square)) #log.info("right first %d, last %d" % (right_first_square, right_last_square)) #log.info("back first %d, last %d" % (back_first_square, back_last_square)) if reverse: for square_index in range(left_first_square, left_last_square + 1): old_index = square_index new_index = square_index + self.squares_per_side results.append((old_index,new_index)) for square_index in range(front_first_square, front_last_square + 1): old_index = square_index new_index = square_index + self.squares_per_side results.append((old_index,new_index)) for square_index in range(right_first_square, right_last_square + 1): old_index = square_index new_index = square_index + self.squares_per_side results.append((old_index,new_index)) for square_index in range(back_first_square, back_last_square + 1): old_index = square_index new_index = square_index - (3 * self.squares_per_side) results.append((old_index,new_index)) else: for square_index in range(left_first_square, left_last_square + 1): old_index = square_index new_index = square_index + (3 * self.squares_per_side) results.append((old_index,new_index)) for square_index in range(front_first_square, front_last_square + 1): old_index = square_index new_index = square_index - self.squares_per_side results.append((old_index,new_index)) for square_index in range(right_first_square, right_last_square + 1): old_index = square_index new_index = square_index - self.squares_per_side results.append((old_index,new_index)) for square_index in range(back_first_square, back_last_square + 1): old_index = square_index new_index = square_index - self.squares_per_side results.append((old_index,new_index)) return results def rotate(self, action): """ self.state is a dictionary where the key is the square_index and the