Hi all,
I am currently creating a Rubik’s cube solver and I have all the functionality of the cube working perfectly. You can move it and turn faces…
I have written a class to scramble the cube where it creates a random list of moves to run. The idea is that when the user clicks ‘p’ it sets scrambling = True and every time that draw() runs it gets the next move from this list and displays the move. However, no matter what I have tried it only ever displays the last move. If you look carefully it looks like it is trying to rotate the face but it doesn’t. Any help much appreciated
Sorry for the awfully written code
Daniel
add_library('peasycam')
from peasy import PeasyCam
import math
def setup():
size(800, 800, P3D)
cam = PeasyCam(this, 100)
cam.setMinimumDistance(50)
cam.setMaximumDistance(500)
background(23,117,46)
textSize(10)
frameRate(120)
strokeWeight(5)
global angle
angle = 0
global animating
animating = False
global amount
amount = 0.01
index = 0
global scrambling
scrambling = False
#faces class
class Face:
def __init__(self, index):
self.index = index
def getcolour(self):
if self.index == 0:
self.colour = 'white'
self.pos_curr = [0,1,0]
self.pos_set = [0,1,0]
elif self.index == 1:
self.colour = 'blue'
self.pos_curr = [0,0,1]
self.pos_set = [0,0,1]
elif self.index == 2:
self.colour = 'orange'
self.pos_curr = [1,0,0]
self.pos_set = [1,0,0]
elif self.index == 3:
self.colour = 'green'
self.pos_curr = [0,0,-1]
self.pos_set = [0,0,-1]
elif self.index == 4:
self.colour = 'red'
self.pos_curr = [-1,0,0]
self.pos_set = [-1,0,0]
elif self.index == 5:
self.colour = 'yellow'
self.pos_curr = [0,-1,0]
self.pos_set = [0,-1,0]
def check(self):
if self.pos_curr == self.pos_set:
return True
else:
return False
#cube class
class Cube:
def __init__(self, x, y, z):
self.faces = []
#current positions of each cube -2<x<2
self.x_curr = x
self.y_curr = y
self.z_curr = z
#the solved positition of the cube
self._xset = x
self._yset = y
self._zset = z
def getfaces(self):
for i in range (0,6):
newFace = Face(i)
newFace.getcolour()
self.faces.append(newFace)
def show(self, rotation, face):
len_= 10
r=6
stroke(0)
pushMatrix()
if animating == True:
if face == 'z':
if rotation == self.z_curr:
rotateZ(angle)
elif face == 'y':
if rotation == self.y_curr:
rotateY(angle)
elif face == 'x':
if rotation == self.x_curr:
rotateX(-angle)
translate(self.x_curr*r*2, self.y_curr*r*2, self.z_curr*r*2)
beginShape(QUADS)
#front face
for each in self.faces:
if each.pos_curr == [0,0,1]:
if each.colour == 'white':
fill(251,255,255)
elif each.colour == 'blue':
fill(77,77,255)
elif each.colour == 'green':
fill(57,255,20)
elif each.colour == 'orange':
fill(255,95,31)
elif each.colour == 'yellow':
fill(255,237,39)
elif each.colour == 'red':
fill(255,49,49)
vertex(r, r, r)
vertex(r, -r, r)
vertex(-r, -r, r)
vertex(-r, r, r)
#bottom face
for each in self.faces:
if each.pos_curr == [0,-1,0]:
if each.colour == 'white':
fill(251,255,255)
elif each.colour == 'blue':
fill(77,77,255)
elif each.colour == 'green':
fill(57,255,20)
elif each.colour == 'orange':
fill(255,95,31)
elif each.colour == 'yellow':
fill(255,237,39)
elif each.colour == 'red':
fill(255,49,49)
vertex(r, r, r)
vertex(r, r, -r)
vertex(-r, r, -r)
vertex(-r, r, r)
#right face
for each in self.faces:
if each.pos_curr == [1,0,0]:
if each.colour == 'white':
fill(251,255,255)
elif each.colour == 'blue':
fill(77,77,255)
elif each.colour == 'green':
fill(57,255,20)
elif each.colour == 'orange':
fill(255,95,31)
elif each.colour == 'yellow':
fill(255,237,39)
elif each.colour == 'red':
fill(255,49,49)
vertex(r, r, r)
vertex(r, r, -r)
vertex(r, -r, -r)
vertex(r, -r, r)
#back face
for each in self.faces:
if each.pos_curr == [0,0,-1]:
if each.colour == 'white':
fill(251,255,255)
elif each.colour == 'blue':
fill(77,77,255)
elif each.colour == 'green':
fill(57,255,20)
elif each.colour == 'orange':
fill(255,95,31)
elif each.colour == 'yellow':
fill(255,237,39)
elif each.colour == 'red':
fill(255,49,49)
vertex(r, r, -r)
vertex(r, -r, -r)
vertex(-r, -r, -r)
vertex(-r, r, -r)
#up face
for each in self.faces:
if each.pos_curr == [0,1,0]:
if each.colour == 'white':
fill(251,255,255)
elif each.colour == 'blue':
fill(77,77,255)
elif each.colour == 'green':
fill(57,255,20)
elif each.colour == 'orange':
fill(255,95,31)
elif each.colour == 'yellow':
fill(255,237,39)
elif each.colour == 'red':
fill(255,49,49)
vertex(r, -r, r)
vertex(r, -r, -r)
vertex(-r, -r, -r)
vertex(-r, -r, r)
#left face
for each in self.faces:
if each.pos_curr == [-1,0,0]:
if each.colour == 'white':
fill(251,255,255)
elif each.colour == 'blue':
fill(77,77,255)
elif each.colour == 'green':
fill(57,255,20)
elif each.colour == 'orange':
fill(255,95,31)
elif each.colour == 'yellow':
fill(255,237,39)
elif each.colour == 'red':
fill(255,49,49)
vertex(-r, r, r)
vertex(-r, r, -r)
vertex(-r, -r, -r)
vertex(-r, -r, r)
endShape()
popMatrix()
#Moves class
class Moves:
def __init__(self):
self.face = ''
self.rotation = ''
def create(self):
a=[]
b=[]
self.cubeList = []
for x in range(-1,2):
for y in range(-1,2):
for z in range(-1,2):
newCube = Cube(x, y, z)
newCube.getfaces()
a.append(newCube)
b.append(a)
a=[]
self.cubeList.append(b)
b=[]
def animating_(self):
if angle < HALF_PI:
global angle
angle += amount
for n in self.cubeList:
for each in n:
for q in each:
q.show(self.rotation, self.face)
return True
else:
for a in self.cubeList:
for b in a:
for i in b:
if self.face == 'z':
check = i.z_curr
elif self.face == 'y':
check = i.y_curr
elif self.face == 'x':
check = i.x_curr
if check == self.rotation:
#altering position of each cube
newx = self.matrix3D[0][0]*i.x_curr + self.matrix3D[0][1]*i.y_curr + self.matrix3D[0][2]*i.z_curr
newy = self.matrix3D[1][0]*i.x_curr + self.matrix3D[1][1]*i.y_curr + self.matrix3D[1][2]*i.z_curr
newz = self.matrix3D[2][0]*i.x_curr + self.matrix3D[2][1]*i.y_curr + self.matrix3D[2][2]*i.z_curr
i.x_curr = newx
i.y_curr = newy
i.z_curr = newz
strokeWeight(0)
for a in self.cubeList:
for b in a:
for i in b:
if self.face == 'z':
check = i.z_curr
elif self.face == 'y':
check = i.y_curr
elif self.face == 'x':
check = i.x_curr
if check == self.rotation:
#altering the rotation of each cube
for each in i.faces:
if self.face == 'z':
a = -self.matrix3D[0][0]*each.pos_curr[0] + -self.matrix3D[0][1]*each.pos_curr[1] + -self.matrix3D[0][2]*each.pos_curr[2]
b = -self.matrix3D[1][0]*each.pos_curr[0] + -self.matrix3D[1][1]*each.pos_curr[1] + -self.matrix3D[1][2]*each.pos_curr[2]
c = self.matrix3D[2][0]*each.pos_curr[0] + self.matrix3D[2][1]*each.pos_curr[1] + self.matrix3D[2][2]*each.pos_curr[2]
elif self.face == 'x':
a = self.matrix3D[0][0]*each.pos_curr[0] + self.matrix3D[0][1]*each.pos_curr[1] + self.matrix3D[0][2]*each.pos_curr[2]
b = -self.matrix3D[1][0]*each.pos_curr[0] + -self.matrix3D[1][1]*each.pos_curr[1] + -self.matrix3D[1][2]*each.pos_curr[2]
c = -self.matrix3D[2][0]*each.pos_curr[0] + -self.matrix3D[2][1]*each.pos_curr[1] + -self.matrix3D[2][2]*each.pos_curr[2]
elif self.face == 'y':
a = -self.matrix3D[0][0]*each.pos_curr[0] + -self.matrix3D[0][1]*each.pos_curr[1] + -self.matrix3D[0][2]*each.pos_curr[2]
b = self.matrix3D[1][0]*each.pos_curr[0] + self.matrix3D[1][1]*each.pos_curr[1] + self.matrix3D[1][2]*each.pos_curr[2]
c = -self.matrix3D[2][0]*each.pos_curr[0] + -self.matrix3D[2][1]*each.pos_curr[1] + -self.matrix3D[2][2]*each.pos_curr[2]
a=-a
b=b
c=-c
newVector = [a,b,c]
each.pos_curr = newVector
return False
def applyMatrix_(self, rotation, matrix3D, face, matrix3D_2):
self.rotation = rotation
self.matrix3D = matrix3D
self.face = face
self.matrix3D_2 = matrix3D_2
global animating
animating = True
global angle
angle = 0
strokeWeight(5)
'''for a in self.cubeList:
for b in a:
for i in b:
i.x_curr = round(i.x_curr)
i.y_curr = round(i.y_curr)
i.z_curr = round(i.z_curr)'''
def turnZ(self, move):
#for z rotations
#user = input('f, m, b, F, M or B')
user= move
if user == 'f':
rotation = 1
dir = -1
elif user == 'F':
rotation = 1
dir = 1
elif user == 's':
rotation = 0
dir = -1
elif user == 'S':
rotation =0
dir = 1
elif user == 'b':
rotation = -1
dir = -1
elif user == 'B':
rotation =-1
dir = 1
matrix3D = [[round(cos(dir*HALF_PI)),-round(sin(dir*HALF_PI)),0],[round(sin(dir*HALF_PI)),round(cos(dir*HALF_PI)),0],[0,0,1]]
matrix3D_2 = [[cos(dir*amount),-sin(dir*amount),0],[sin(dir*amount),cos(dir*amount),0],[0,0,1]]
self.applyMatrix_(rotation, matrix3D, 'z', matrix3D_2)
def turnX(self, move):
#for x rotations
user = move
if user == 'r':
rotation = 1
dir = -1
elif user == 'R':
rotation = 1
dir = 1
elif user == 'm':
rotation = 0
dir = -1
elif user == 'M':
rotation =0
dir = 1
elif user == 'l':
rotation = -1
dir = -1
elif user == 'L':
rotation =-1
dir = 1
matrix3D = [[1,0,0],[0,round(cos(dir*HALF_PI)),-round(sin(dir*HALF_PI))],[0,round(sin(dir*HALF_PI)),round(cos(dir*HALF_PI))]]
matrix3D_2 = [[1,0,0],[0,cos(dir*amount),-sin(dir*amount)],[0,sin(dir*amount),cos(dir*amount)]]
self.applyMatrix_(rotation, matrix3D, 'x', matrix3D_2)
def turnY(self, move):
#for y rotations
user = move
if user == 'u':
rotation = 1
dir = -1
elif user == 'U':
rotation = 1
dir = 1
elif user == 'e':
rotation = 0
dir = -1
elif user == 'E':
rotation =0
dir = 1
elif user == 'd':
rotation = -1
dir = -1
elif user == 'D':
rotation =-1
dir = 1
matrix3D = [[round(cos(dir*HALF_PI)), 0, round(sin(dir*HALF_PI))], [0, 1, 0], [-round(sin(dir*HALF_PI)), 0, round(cos(dir*HALF_PI))]]
matrix3D_2 = [[cos(dir*amount), 0, sin(dir*amount)], [0, 1, 0], [-sin(dir*amount), 0, cos(dir*amount)]]
self.applyMatrix_(rotation, matrix3D, 'y', matrix3D_2)
def axis(self, move):
#a = input('Would you like to rotate along x, y or z axis? ')
if move == 'l' or move == 'm' or move == 'r' or move == 'L' or move == 'M' or move == 'R':
self.turnX(move)
elif move == 'u' or move == 'e' or move == 'd' or move == 'U' or move == 'E' or move == 'D':
self.turnY(move)
elif move == '':
pass
else:
self.turnZ(move)
#Moves meaning
#Z axis
#f front face
#s middle face
#b back face
#Y axis
#u top face
#e middle face
#d bottom face
#X axis
#l left face
#m middle face
#r right face
a=Moves()
a.create()
#############################
class list_of_moves:
def __init__(self):
self.index = 0
self.moves = ['F', 'D', 'l', 'r','B', 'U']
self.scramble = []
for i in range(0, 20):
self.scramble.append(self.moves[int(random(0,6))])
def rotate_(self):
print(self.index)
if self.index == len(self.scramble):
global scrambling
scrambling = False
return ''
else:
self.mov = self.scramble[self.index]
self.index += 1
return self.mov
q = list_of_moves()
def draw():
background(79,117,110)
textSize(8)
n = 'p'
if keyPressed and animating == False:
if key == ' ':
fill(0)
text("Moves:", -50, -30,0)
textSize(5)
text("f- blue", -50, -20,0)
text("b- green", -50, -13,0)
text("u- white", -50, -6,0)
text("d- yellow", -50, 1,0)
text("l- red", -50, 8,0)
text("r- orange", -50, 13,0)
###################
if key == 'p':
global scrambling
scrambling = True
#####################
if scrambling == True:
n = q.rotate_()
a.axis(n)
delay(800)
counter=0
for i in a.cubeList:
for each in i:
for z in each:
z.show(a.rotation, a.face)
counter+=1
stroke(5)
if keyPressed and animating == False:
if key == 'f' or next == 'f':
a.axis('F')
delay(800)
elif key == 'r':
a.axis('r')
delay(800)
#elif key == 's':
# a.axis('S')
# delay(500)
elif key == 'b':
a.axis('B')
delay(800)
elif key == 'u' or next == 'u':
a.axis('D')
delay(800)
#elif key == 'e':
# a.axis('E')
# delay(800)
elif key == 'd':
a.axis('U')
delay(800)
elif key == 'l':
a.axis('l')
delay(800)
#elif key == 'm':
# a.axis('m')
# delay(800)
#elif key == 'F':
# a.axis('f')
# delay(800)
#elif key == 'R':
# a.axis('R')
# delay(800)
#elif key == 'S':
# a.axis('s')
# delay(500)
#elif key == 'B':
# a.axis('b')
# delay(800)
#elif key == 'U':
# a.axis('d')
# delay(800)
#elif key == 'E':
# a.axis('e')
# delay(800)
#elif key == 'D':
# a.axis('u')
# delay(800)
#elif key == 'L':
# a.axis('L')
# delay(800)
#elif key == 'M':
# a.axis('M')
# delay(800)
global animating
if animating == True:
global angle
angle += amount
animating = a.animating_()
elif animating == False:
strokeWeight(5)
for n in a.cubeList:
for b in n:
for i in b:
i.x_curr = round(i.x_curr)
i.y_curr = round(i.y_curr)
i.z_curr = round(i.z_curr)