Пример #1
0
    def __init__(self):
        self.faces = {}
        self.all_polys = []
        self.x_axis = [ 1, 0, 0 ]
        self.y_axis = [ 0, 1, 0 ]
        self.z_axis = [ 0, 0, 1 ]
        self.net_rotation = RotationMatrix()
        self.history = []
        self.history_index = 0

        up = []

        for j in range(3):
            for i in range(3):
                u = p3d.Polygon3D(COLOR_SCHEME['U'], BORDER_COLOR)
                p1 = (-HALF_SIDE_LEN + i * CUBIE_SIDE_LEN, HALF_SIDE_LEN, -HALF_SIDE_LEN + j * CUBIE_SIDE_LEN)
                p2 = (-HALF_SIDE_LEN + (i + 1) * CUBIE_SIDE_LEN, HALF_SIDE_LEN, -HALF_SIDE_LEN + j * CUBIE_SIDE_LEN)
                p3 = (-HALF_SIDE_LEN + (i + 1) * CUBIE_SIDE_LEN, HALF_SIDE_LEN, -HALF_SIDE_LEN + (j + 1) * CUBIE_SIDE_LEN)
                p4 = (-HALF_SIDE_LEN + i * CUBIE_SIDE_LEN, HALF_SIDE_LEN, -HALF_SIDE_LEN + (j + 1) * CUBIE_SIDE_LEN)
                u.add_points([p1, p2, p3, p4])
                up.append(copy(u))
        
        front = []
        for poly in up:
            front.append(copy(poly))
        f_rot = RotationMatrix().setRotation(0, 90)
        for i in range(len(front)):
            front[i].rotate(f_rot)
            front[i].fill = COLOR_SCHEME['F']

        back = []
        for poly in up:
            back.append(copy(poly))
        b_rot1 = RotationMatrix().setRotation(1, 180)
        b_rot2 = RotationMatrix().setRotation(0, -90)
        for i in range(len(back)):
            back[i].rotate(b_rot1)
            back[i].rotate(b_rot2)
            back[i].fill = COLOR_SCHEME['B']

        left = []
        for poly in up:
            left.append(copy(poly))
        l_rot1 = RotationMatrix().setRotation(0, 90)
        l_rot2 = RotationMatrix().setRotation(1, -90)
        for i in range(len(left)):
            left[i].rotate(l_rot1)
            left[i].rotate(l_rot2)
            left[i].fill = COLOR_SCHEME['L']

        right = []
        for poly in up:
            right.append(copy(poly))
        r_rot1 = RotationMatrix().setRotation(0, 90)
        r_rot2 = RotationMatrix().setRotation(1, 90)
        for i in range(len(right)):
            right[i].rotate(r_rot1)
            right[i].rotate(r_rot2)
            right[i].fill = COLOR_SCHEME['R']

        down = []
        for poly in up:
            down.append(copy(poly))
        d_rot = RotationMatrix().setRotation(0, 180)
        for i in range(len(down)):
            down[i].rotate(d_rot)
            down[i].fill = COLOR_SCHEME['D']
        
        self.faces['B'] = back
        self.faces['F'] = front
        self.faces['U'] = up
        self.faces['D'] = down
        self.faces['L'] = left
        self.faces['R'] = right
        
        for face in self.faces.values():
            self.all_polys += face
Пример #2
0
class Cube:
    def __init__(self):
        self.faces = {}
        self.all_polys = []
        self.x_axis = [ 1, 0, 0 ]
        self.y_axis = [ 0, 1, 0 ]
        self.z_axis = [ 0, 0, 1 ]
        self.net_rotation = RotationMatrix()
        self.history = []
        self.history_index = 0

        up = []

        for j in range(3):
            for i in range(3):
                u = p3d.Polygon3D(COLOR_SCHEME['U'], BORDER_COLOR)
                p1 = (-HALF_SIDE_LEN + i * CUBIE_SIDE_LEN, HALF_SIDE_LEN, -HALF_SIDE_LEN + j * CUBIE_SIDE_LEN)
                p2 = (-HALF_SIDE_LEN + (i + 1) * CUBIE_SIDE_LEN, HALF_SIDE_LEN, -HALF_SIDE_LEN + j * CUBIE_SIDE_LEN)
                p3 = (-HALF_SIDE_LEN + (i + 1) * CUBIE_SIDE_LEN, HALF_SIDE_LEN, -HALF_SIDE_LEN + (j + 1) * CUBIE_SIDE_LEN)
                p4 = (-HALF_SIDE_LEN + i * CUBIE_SIDE_LEN, HALF_SIDE_LEN, -HALF_SIDE_LEN + (j + 1) * CUBIE_SIDE_LEN)
                u.add_points([p1, p2, p3, p4])
                up.append(copy(u))
        
        front = []
        for poly in up:
            front.append(copy(poly))
        f_rot = RotationMatrix().setRotation(0, 90)
        for i in range(len(front)):
            front[i].rotate(f_rot)
            front[i].fill = COLOR_SCHEME['F']

        back = []
        for poly in up:
            back.append(copy(poly))
        b_rot1 = RotationMatrix().setRotation(1, 180)
        b_rot2 = RotationMatrix().setRotation(0, -90)
        for i in range(len(back)):
            back[i].rotate(b_rot1)
            back[i].rotate(b_rot2)
            back[i].fill = COLOR_SCHEME['B']

        left = []
        for poly in up:
            left.append(copy(poly))
        l_rot1 = RotationMatrix().setRotation(0, 90)
        l_rot2 = RotationMatrix().setRotation(1, -90)
        for i in range(len(left)):
            left[i].rotate(l_rot1)
            left[i].rotate(l_rot2)
            left[i].fill = COLOR_SCHEME['L']

        right = []
        for poly in up:
            right.append(copy(poly))
        r_rot1 = RotationMatrix().setRotation(0, 90)
        r_rot2 = RotationMatrix().setRotation(1, 90)
        for i in range(len(right)):
            right[i].rotate(r_rot1)
            right[i].rotate(r_rot2)
            right[i].fill = COLOR_SCHEME['R']

        down = []
        for poly in up:
            down.append(copy(poly))
        d_rot = RotationMatrix().setRotation(0, 180)
        for i in range(len(down)):
            down[i].rotate(d_rot)
            down[i].fill = COLOR_SCHEME['D']
        
        self.faces['B'] = back
        self.faces['F'] = front
        self.faces['U'] = up
        self.faces['D'] = down
        self.faces['L'] = left
        self.faces['R'] = right
        
        for face in self.faces.values():
            self.all_polys += face
            
    def get_axis(self, face):
        face = face.upper()
        neg = lambda (x, y, z): (-x, -y, -z)
        if face == "U" or face == 'Y':
            return self.y_axis
        elif face == "D":
            return neg(self.y_axis)
        elif face == "F" or face == 'Z':
            return self.z_axis
        elif face == "B":
            return neg(self.z_axis)
        elif face == "L":
            return neg(self.x_axis)
        elif face == "R" or face == 'X':
            return self.x_axis
        else:
            return None
        
    def tick(self):
        if self.history_index < len(self.history):
            if self.animate_turn(self.history[self.history_index]):
                self.history_index += 1
                
    def char_pressed(self, ch):
        self.do_turn(KEYS.get(ch, None))
            
    def do_turn(self, turns):
        if turns == None: return
        for turn in turns.split():
            if turn == 'scramble':
                import scrambler
                self.do_turn(scrambler.gen_scramble_str(25))
            elif turn == 'reset':
                #TODO
                pass
            elif turn == 'undo':
                if len(self.history) == 0:
                    continue
                last = self.history[-1].copy()
                last['dir'] *= -1
                del last['total_degrees'] # otherwise, we'll think the move is over
                self.history.append(last)
            else:
                face = turn[:1]
                dir = {"": 1, "'": -1, "2": 2, "2'": -2}[turn[1:]]
                if dir == None:
                    continue
                # can't store this axis now because it may change by the time we start animating
                if self.get_axis(face) == None:
                    continue
                if face in 'xyz':
                    face = {'x':'R', 'y':'U', 'z':'F'}[face]
                    layers = -1
                elif face.islower():
                    layers = 2
                else:
                    layers = 1
                
                self.history.append({'face': face, 'layers': layers, 'dir': dir})
                
    # cycles stickers in self.faces according to cycle
    def cycle_stickers(self, cycle):
        index = cycle[-1]
        last_poly = self.faces[index[0]][index[1]]
        for i in range(len(cycle)-1, 0, -1):
            index = cycle[i]
            index_prev = cycle[i-1]
            self.faces[index[0]][index[1]] = self.faces[index_prev[0]][index_prev[1]]
        index = cycle[0]
        self.faces[index[0]][index[1]] = last_poly

    def animate_turn(self, turn):
        total_degrees_ccw = -90*turn['dir']
        total_degrees = abs(total_degrees_ccw)
        inc_degree = 1.0*total_degrees_ccw / FRAMES_ANIMATION
        rot = RotationMatrix().rotationMatrix(self.get_axis(turn['face']), inc_degree)
        
        permutations = self.get_turn_permutations(turn)
        if permutations == None:
            return True
        for cycle in permutations:
            for index in cycle:
                self.faces[index[0]][index[1]].rotate(rot)
#        for poly in self.faces[turn['face']]:
#            poly.rotate(rot)
            
        turn['total_degrees'] = turn.get('total_degrees', 0) + abs(inc_degree)
        done = (turn['total_degrees'] >= total_degrees)
        if done:
            # updating internal representation
            for i in range(0, turn['dir'] % 4):
                for cycle in permutations:
                    self.cycle_stickers(cycle)
        return done 
        
    def get_turn_permutations(self, turn):
        (face, layers, dir) = (turn['face'], turn['layers'], turn['dir'])
        cycles = None
        if layers == -1:
            layers = 3
        if face == 'U':
            if layers == 1:
                cycles = [ [('U',0),('U',2),('U',8),('U',6)], [('U',1),('U',5),('U',7),('U',3)], [('F',0),('L',0),('B',0),('R',0)], [('F',1),('L',1),('B',1),('R',1)], [('F',2),('L',2),('B',2),('R',2)], [('U',4)] ]
            elif layers == 2:
                cycles = [ [('U',0),('U',2),('U',8),('U',6)], [('U',1),('U',5),('U',7),('U',3)], [('F',0),('L',0),('B',0),('R',0)], [('F',1),('L',1),('B',1),('R',1)], [('F',2),('L',2),('B',2),('R',2)], [('B',4),('R',4),('F',4),('L',4)], [('B',5),('R',5),('F',5),('L',5)], [('B',3),('R',3),('F',3),('L',3)], [('U',4)] ]
            elif layers == 3:
                cycles = [ [('U',0),('U',2),('U',8),('U',6)], [('U',1),('U',5),('U',7),('U',3)], [('F',0),('L',0),('B',0),('R',0)], [('F',1),('L',1),('B',1),('R',1)], [('F',2),('L',2),('B',2),('R',2)], [('B',4),('R',4),('F',4),('L',4)], [('B',5),('R',5),('F',5),('L',5)], [('B',3),('R',3),('F',3),('L',3)], [('U',4)], [('D',6),('D',8),('D',2),('D',0)], [('D',3),('D',7),('D',5),('D',1)], [('L',6),('B',6),('R',6),('F',6)], [('L',7),('B',7),('R',7),('F',7)], [('L',8),('B',8),('R',8),('F',8)], [('D',4)] ]
        elif face == 'F':
            if layers == 1:
                cycles = [ [('F',0),('F',2),('F',8),('F',6)], [('F',1),('F',5),('F',7),('F',3)], [('U',6),('R',0),('D',2),('L',8)], [('U',7),('R',3),('D',1),('L',5)], [('U',8),('R',6),('D',0),('L',2)], [('F',4)] ]  
            elif layers == 2:
                cycles = [ [('F',0),('F',2),('F',8),('F',6)], [('F',1),('F',5),('F',7),('F',3)], [('U',6),('R',0),('D',2),('L',8)], [('U',7),('R',3),('D',1),('L',5)], [('U',8),('R',6),('D',0),('L',2)], [('U',4),('R',4),('D',4),('L',4)], [('U',3),('R',1),('D',5),('L',7)], [('U',5),('R',7),('D',3),('L',1)], [('F',4)] ]  
            elif layers == 3:
                cycles = [ [('F',0),('F',2),('F',8),('F',6)], [('F',1),('F',5),('F',7),('F',3)], [('U',6),('R',0),('D',2),('L',8)], [('U',7),('R',3),('D',1),('L',5)], [('U',8),('R',6),('D',0),('L',2)], [('U',4),('R',4),('D',4),('L',4)], [('U',3),('R',1),('D',5),('L',7)], [('U',5),('R',7),('D',3),('L',1)], [('F',4)], [('B',6),('B',8),('B',2),('B',0)], [('B',3),('B',7),('B',5),('B',1)], [('R',8),('D',6),('L',0),('U',2)], [('R',5),('D',7),('L',3),('U',1)], [('R',2),('D',8),('L',6),('U',0)], [('B',4)] ]  
        elif face == 'R':
            if layers == 1:
                cycles = [ [('R',0),('R',2),('R',8),('R',6)], [('R',1),('R',5),('R',7),('R',3)], [('U',8),('B',0),('D',8),('F',8)], [('U',5),('B',3),('D',5),('F',5)], [('U',2),('B',6),('D',2),('F',2)], [('R',4)] ]
            elif layers == 2:
                cycles = [ [('R',0),('R',2),('R',8),('R',6)], [('R',1),('R',5),('R',7),('R',3)], [('U',8),('B',0),('D',8),('F',8)], [('U',5),('B',3),('D',5),('F',5)], [('U',2),('B',6),('D',2),('F',2)], [('U',4),('B',4),('D',4),('F',4)], [('U',7),('B',1),('D',7),('F',7)], [('U',1),('B',7),('D',1),('F',1)], [('R',4)] ]
            elif layers == 3:
                cycles = [ [('R',0),('R',2),('R',8),('R',6)], [('R',1),('R',5),('R',7),('R',3)], [('U',8),('B',0),('D',8),('F',8)], [('U',5),('B',3),('D',5),('F',5)], [('U',2),('B',6),('D',2),('F',2)], [('U',4),('B',4),('D',4),('F',4)], [('U',7),('B',1),('D',7),('F',7)], [('U',1),('B',7),('D',1),('F',1)], [('R',4)], [('L',6),('L',8),('L',2),('L',0)], [('L',3),('L',7),('L',5),('L',1)], [('B',8),('D',0),('F',0),('U',0)], [('B',5),('D',3),('F',3),('U',3)], [('B',2),('D',6),('F',6),('U',6)], [('L',4)] ]
        elif face == 'B':
            if layers == 1:
                cycles = [ [('B',0),('B',2),('B',8),('B',6)], [('B',1),('B',5),('B',7),('B',3)], [('U',2),('L',0),('D',6),('R',8)], [('U',1),('L',3),('D',7),('R',5)], [('U',0),('L',6),('D',8),('R',2)], [('B',4)] ]
            elif layers == 2:
                cycles = [ [('B',0),('B',2),('B',8),('B',6)], [('B',1),('B',5),('B',7),('B',3)], [('U',2),('L',0),('D',6),('R',8)], [('U',1),('L',3),('D',7),('R',5)], [('U',0),('L',6),('D',8),('R',2)], [('U',4),('R',4),('D',4),('L',4)], [('U',5),('L',1),('D',3),('R',7)], [('U',3),('L',7),('D',5),('R',1)], [('B',4)] ]
            elif layers == 3:
                cycles = [ [('B',0),('B',2),('B',8),('B',6)], [('B',1),('B',5),('B',7),('B',3)], [('U',2),('L',0),('D',6),('R',8)], [('U',1),('L',3),('D',7),('R',5)], [('U',0),('L',6),('D',8),('R',2)], [('U',4),('R',4),('D',4),('L',4)], [('U',5),('L',1),('D',3),('R',7)], [('U',3),('L',7),('D',5),('R',1)], [('B',4)], [('F',6),('F',8),('F',2),('F',0)], [('F',3),('F',7),('F',5),('F',1)], [('L',8),('D',2),('R',0),('U',6)], [('L',5),('D',1),('R',3),('U',7)], [('L',2),('D',0),('R',6),('U',8)], [('F',4)] ]
        elif face == 'L':
            if layers == 1:
                cycles = [ [('L',0),('L',2),('L',8),('L',6)], [('L',1),('L',5),('L',7),('L',3)], [('U',0),('F',0),('D',0),('B',8)], [('U',3),('F',3),('D',3),('B',5)], [('U',6),('F',6),('D',6),('B',2)], [('L',4)] ]
            elif layers == 2:
                cycles = [ [('L',0),('L',2),('L',8),('L',6)], [('L',1),('L',5),('L',7),('L',3)], [('U',0),('F',0),('D',0),('B',8)], [('U',3),('F',3),('D',3),('B',5)], [('U',6),('F',6),('D',6),('B',2)], [('U',4),('F',4),('D',4),('B',4)], [('U',1),('F',1),('D',1),('B',7)], [('U',7),('F',7),('D',7),('B',1)], [('L',4)] ]
            elif layers == 3:
                cycles = [ [('L',0),('L',2),('L',8),('L',6)], [('L',1),('L',5),('L',7),('L',3)], [('U',0),('F',0),('D',0),('B',8)], [('U',3),('F',3),('D',3),('B',5)], [('U',6),('F',6),('D',6),('B',2)], [('U',4),('F',4),('D',4),('B',4)], [('U',1),('F',1),('D',1),('B',7)], [('U',7),('F',7),('D',7),('B',1)], [('L',4)], [('R',6),('R',8),('R',2),('R',0)], [('R',3),('R',7),('R',5),('R',1)], [('F',8),('D',8),('B',0),('U',8)], [('F',5),('D',5),('B',3),('U',5)], [('F',2),('D',2),('B',6),('U',2)], [('R',4)] ]
        elif face == 'D':
            if layers == 1:
                cycles = [ [('D',0),('D',2),('D',8),('D',6)], [('D',1),('D',5),('D',7),('D',3)], [('F',6),('R',6),('B',6),('L',6)], [('F',7),('R',7),('B',7),('L',7)], [('F',8),('R',8),('B',8),('L',8)], [('D',4)] ]
            elif layers == 2:
                cycles = [ [('D',0),('D',2),('D',8),('D',6)], [('D',1),('D',5),('D',7),('D',3)], [('F',6),('R',6),('B',6),('L',6)], [('F',7),('R',7),('B',7),('L',7)], [('F',8),('R',8),('B',8),('L',8)], [('F',4),('R',4),('B',4),('L',4)], [('F',3),('R',3),('B',3),('L',3)], [('U',5),('R',5),('B',5),('L',5)], [('D',4)] ]
            elif layers == 3:
                cycles = [ [('D',0),('D',2),('D',8),('D',6)], [('D',1),('D',5),('D',7),('D',3)], [('F',6),('R',6),('B',6),('L',6)], [('F',7),('R',7),('B',7),('L',7)], [('F',8),('R',8),('B',8),('L',8)], [('F',4),('R',4),('B',4),('L',4)], [('F',3),('R',3),('B',3),('L',3)], [('U',5),('R',5),('B',5),('L',5)], [('D',4)], [('U',6),('U',8),('U',2),('U',0)], [('U',3),('U',7),('U',5),('U',1)], [('R',0),('B',0),('L',0),('F',0)], [('R',1),('B',1),('L',1),('F',1)], [('R',2),('B',2),('L',2),('F',2)], [('U',4)] ]
        return cycles

    def polygons(self):
        return self.all_polys
    
    def rotate(self, rotation):
        if rotation == None:
            rotation = self.net_rotation.invert()
            
        self.net_rotation = rotation.multiply(self.net_rotation)
        self.x_axis = rotation.multiplyPoint(self.x_axis)
        self.y_axis = rotation.multiplyPoint(self.y_axis)
        self.z_axis = rotation.multiplyPoint(self.z_axis)
        for poly in self.polygons():
            poly.rotate(rotation)

    def is_solved(self):
        for face in COLOR_SCHEME.keys():
            color = self.faces[face][0].fill
            for poly in self.faces[face]:
                if color != poly.fill:
                    return False
        return True