File size: 5,349 Bytes
a6b8103
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
import numpy as np

class RubiksCube:
    def __init__(self):
        """
        Inicializa um cubo mágico resolvido.
        Faces são numeradas de 0-5:
        0: Branco (topo)
        1: Amarelo (base)
        2: Verde (frente)
        3: Azul (traseira)
        4: Vermelho (direita)
        5: Laranja (esquerda)
        """
        # Criar um cubo 3x3x3 com cores padrão
        self.cube = np.zeros((6, 3, 3), dtype=int)
        for i in range(6):
            self.cube[i] = np.full((3, 3), i)
        
        self.color_names = {
            0: "Branco",
            1: "Amarelo",
            2: "Verde",
            3: "Azul",
            4: "Vermelho",
            5: "Laranja"
        }
    
    def get_face(self, face_num):
        """Retorna uma face específica do cubo."""
        if 0 <= face_num < 6:
            return self.cube[face_num].copy()
        raise ValueError("Número de face inválido")
    
    def set_face(self, face_num, new_state):
        """Define o estado de uma face específica."""
        if 0 <= face_num < 6 and new_state.shape == (3, 3):
            self.cube[face_num] = new_state.copy()
        else:
            raise ValueError("Face inválida ou dimensões incorretas")
    
    def rotate_face_clockwise(self, face_num):
        """Rotaciona uma face no sentido horário."""
        if 0 <= face_num < 6:
            self.cube[face_num] = np.rot90(self.cube[face_num], k=-1)
            self._update_adjacent_faces(face_num, clockwise=True)
        else:
            raise ValueError("Número de face inválido")
    
    def rotate_face_counterclockwise(self, face_num):
        """Rotaciona uma face no sentido anti-horário."""
        if 0 <= face_num < 6:
            self.cube[face_num] = np.rot90(self.cube[face_num], k=1)
            self._update_adjacent_faces(face_num, clockwise=False)
        else:
            raise ValueError("Número de face inválido")
    
    def _update_adjacent_faces(self, face_num, clockwise=True):
        """Atualiza as faces adjacentes após uma rotação."""
        # Definição das faces adjacentes e suas bordas afetadas para cada face
        adjacent_faces = {
            0: [(2,0), (4,0), (3,0), (5,0)],  # Topo
            1: [(2,2), (5,2), (3,2), (4,2)],  # Base
            2: [(0,2), (4,3), (1,0), (5,1)],  # Frente
            3: [(0,0), (5,3), (1,2), (4,1)],  # Traseira
            4: [(0,1), (2,1), (1,1), (3,3)],  # Direita
            5: [(0,3), (3,1), (1,3), (2,3)]   # Esquerda
        }
        
        # Obter as faces e bordas afetadas
        affected = adjacent_faces[face_num]
        temp_values = []
        
        # Guardar valores temporários
        for face, edge in affected:
            if edge == 0:
                temp_values.append(self.cube[face][0].copy())
            elif edge == 1:
                temp_values.append(self.cube[face][:,2].copy())
            elif edge == 2:
                temp_values.append(self.cube[face][2].copy())
            else:  # edge == 3
                temp_values.append(self.cube[face][:,0].copy())
        
        # Rotacionar valores
        if clockwise:
            temp_values = [temp_values[-1]] + temp_values[:-1]
        else:
            temp_values = temp_values[1:] + [temp_values[0]]
        
        # Atualizar faces
        for (face, edge), new_values in zip(affected, temp_values):
            if edge == 0:
                self.cube[face][0] = new_values
            elif edge == 1:
                self.cube[face][:,2] = new_values
            elif edge == 2:
                self.cube[face][2] = new_values
            else:  # edge == 3
                self.cube[face][:,0] = new_values
    
    def is_solved(self):
        """Verifica se o cubo está resolvido."""
        for face in range(6):
            if not np.all(self.cube[face] == face):
                return False
        return True
    
    def scramble(self, num_moves=20):
        """Embaralha o cubo com um número específico de movimentos aleatórios."""
        import random
        moves = []
        for _ in range(num_moves):
            face = random.randint(0, 5)
            direction = random.choice([True, False])
            if direction:
                self.rotate_face_clockwise(face)
                moves.append(f"Rotação horária da face {self.color_names[face]}")
            else:
                self.rotate_face_counterclockwise(face)
                moves.append(f"Rotação anti-horária da face {self.color_names[face]}")
        return moves
    
    def get_state_str(self):
        """Retorna uma representação string do estado atual do cubo."""
        state = []
        for face in range(6):
            face_str = f"Face {self.color_names[face]}:\n"
            face_str += str(self.cube[face])
            state.append(face_str)
        return "\n\n".join(state)

# Exemplo de uso
if __name__ == "__main__":
    # Criar um novo cubo
    cube = RubiksCube()
    
    print("Estado inicial do cubo:")
    print(cube.get_state_str())
    
    # Embaralhar o cubo
    moves = cube.scramble(5)
    print("\nMovimentos realizados:")
    for move in moves:
        print(move)
    
    print("\nEstado após embaralhar:")
    print(cube.get_state_str())
    
    # Verificar se está resolvido
    print("\nCubo está resolvido?", cube.is_solved())