Browse Source

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__.py View 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

Loading…
Cancel
Save