SOLVED = ['w', 'w', 'w', 'w', 'w', 'w', 'w', 'w', 'w', 'y', 'y', 'y', 'y', 'y', 'y', 'y', 'y', 'y', 'g', 'g', 'g', 'g',
'g', 'g', 'g', 'g', 'g', 'r', 'r', 'r', 'r', 'r', 'r', 'r', 'r', 'r', 'b', 'b', 'b', 'b', 'b', 'b', 'b', 'b',
'b', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o']
class Move:
def __init__(self, indices):
self.indices = indices
def inverted(self):
inverted = []
for item in self.indices: inverted.append((item[1], item[0]))
return Move(inverted)
class Cube:
def __init__(self, state=SOLVED):
self.state = state[:]
def move(self, move): # Function which applies a move to the cube object, takes a move object as its parameter
cube = self.state[:]
indices = move.indices[:]
next_cube = cube[:]
for item in indices:
next_cube[item[1]] = cube[item[0]]
self.state = next_cube[:]
def sequence(self, sequence):
for move in sequence:
self.move(move)
def is_state(self, state_args):
for arg in state_args:
if self.state[arg[1]] != arg[0]: return False
return True
def move_from_sequence(sequence): # Turns a list of move objects into a single move object
cube = Cube()
cycle = 0
new_indices = []
item = ()
for sticker in cube.state:
cube.state[cycle] = (sticker, cycle)
cycle += 1
cube.sequence(sequence)
cycle = 0
for sticker in cube.state:
item = cube.state[cycle]
if cycle != item[1]:
new_indices.append((item[1], cycle))
cycle += 1
cube.state = SOLVED[:]
return Move(new_indices)
def cy(targets): # Makes manually coding moves easier by automating cycles of stickers, so you don't have to code
# every swap by hand
out = []
for i in range(len(targets)): out.append((targets[i], targets[(i + 1) % len(targets)]))
return out
# Manually coded moves:
R = Move(
[(8, 36), (5, 39), (2, 42), (36, 17), (39, 14), (42, 11), (17, 26), (14, 23), (11, 20), (26, 8), (23, 5), (20, 2),
(27, 29), (29, 35), (35, 33), (33, 27), (28, 32), (32, 34), (34, 30), (30, 28)])
y = Move(
[(0, 2), (2, 8), (8, 6), (6, 0), (1, 5), (5, 7), (7, 3), (3, 1), (9, 15), (15, 17), (17, 11), (11, 9), (10, 12),
(12, 16), (16, 14), (14, 10), (20, 47), (19, 46), (18, 45), (47, 38), (46, 37), (45, 36), (38, 29), (37, 28),
(36, 27), (29, 20), (28, 19), (27, 18), (23, 50), (22, 49), (21, 48), (50, 41), (49, 40), (48, 39), (41, 32),
(40, 31), (39, 30), (32, 23), (31, 22), (30, 21), (26, 53), (25, 52), (24, 51), (53, 44), (52, 43), (51, 42),
(41, 32), (43, 34), (44, 35), (42, 33), (35, 26), (34, 25), (33, 24)])
x = Move(
cy([20, 2, 42, 11]) + cy([19, 1, 43, 10]) + cy([18, 0, 44, 9]) + cy([23, 5, 39, 14]) + cy([22, 4, 40, 13]) + cy(
[21, 3, 41, 12]) + cy([27, 29, 35, 33]) + cy([28, 32, 34, 30]) + cy([45, 51, 53, 47]) + cy(
[46, 48, 52, 50]) + cy([26, 8, 36, 17]) + cy([25, 7, 37, 16]) + cy([24, 6, 38, 15]))
# Other moves out of the manually coded moves:
# x move setup
x2 = move_from_sequence([x, x])
x_ = x.inverted()
# R move setup
R_ = R.inverted()
R2 = move_from_sequence([R, R])
# y move setup
y2 = move_from_sequence([y, y])
y_ = y.inverted()
# L move setup
L = move_from_sequence([y2, R, y2])
L_ = L.inverted()
L2 = move_from_sequence([L, L])
# F move setup
F = move_from_sequence([y_, R, y])
F2 = move_from_sequence([F, F])
F_ = F.inverted()
# B move setup
B = move_from_sequence([y, R, y_])
B_ = B.inverted()
B2 = move_from_sequence([B, B])
# U move setup
U = move_from_sequence([x_, y_, R, y, x]) # The code breaks down when I start using x moves, I don't know why.
U_ = U.inverted()
U2 = move_from_sequence([U, U])
# D move setup
D = move_from_sequence([x2, U, x2])
D_ = D.inverted()
D2 = move_from_sequence([D, D])
# M move setup
M = move_from_sequence([R, L_, x_])
M_ = M.inverted()
M2 = move_from_sequence([M, M])
z = move_from_sequence([x, y, x_])
z_ = z.inverted()
z2 = move_from_sequence([z, z])