Spaces:
Sleeping
Sleeping
Update app.py
Browse files
app.py
CHANGED
@@ -6,125 +6,110 @@ class RubiksCube4x4:
|
|
6 |
def __init__(self):
|
7 |
self.size = 4
|
8 |
self.cube = np.zeros((6, 4, 4), dtype=int)
|
9 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
10 |
self.cube[i] = np.full((4, 4), i)
|
11 |
|
12 |
self.color_names = {
|
13 |
-
0: "Branco",
|
14 |
-
1: "Amarelo",
|
15 |
-
2: "Verde",
|
16 |
-
3: "Azul",
|
17 |
-
4: "Vermelho",
|
18 |
-
5: "Laranja"
|
19 |
}
|
20 |
-
|
21 |
-
self.moves_history = []
|
22 |
-
|
23 |
-
def set_face(self, face_num, colors):
|
24 |
-
"""Define as cores de uma face específica"""
|
25 |
-
if isinstance(colors, str):
|
26 |
-
colors = [int(c) for c in colors.split(',') if c.strip()]
|
27 |
-
if len(colors) == 16: # 4x4 = 16 cores
|
28 |
-
self.cube[face_num] = np.array(colors).reshape(4, 4)
|
29 |
-
else:
|
30 |
-
raise ValueError(f"Face {face_num} precisa de exatamente 16 cores")
|
31 |
|
32 |
def get_solution(self):
|
33 |
-
"""
|
34 |
-
Retorna a sequência de movimentos para resolver o cubo.
|
35 |
-
Implementa uma solução básica para cubo 4x4.
|
36 |
-
"""
|
37 |
solution = []
|
38 |
|
39 |
-
#
|
40 |
-
solution.
|
41 |
-
|
42 |
-
|
43 |
-
solution.
|
44 |
-
|
45 |
-
|
46 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
47 |
|
48 |
return solution
|
49 |
-
|
50 |
-
def _solve_centers(self):
|
51 |
-
"""Resolve os centros do cubo"""
|
52 |
-
moves = [
|
53 |
-
"1. Alinhe os centros brancos",
|
54 |
-
"2. Gire a face superior até alinhar",
|
55 |
-
"3. Repita para os centros amarelos",
|
56 |
-
"4. Complete os centros laterais"
|
57 |
-
]
|
58 |
-
return moves
|
59 |
-
|
60 |
-
def _pair_edges(self):
|
61 |
-
"""Emparelha as arestas"""
|
62 |
-
moves = [
|
63 |
-
"1. Identifique pares de arestas",
|
64 |
-
"2. Use o algoritmo de flipe para alinhar",
|
65 |
-
"3. Repita para todas as arestas"
|
66 |
-
]
|
67 |
-
return moves
|
68 |
-
|
69 |
-
def _solve_as_3x3(self):
|
70 |
-
"""Resolve como um cubo 3x3"""
|
71 |
-
moves = [
|
72 |
-
"1. Resolva a cruz branca",
|
73 |
-
"2. Resolva os cantos brancos",
|
74 |
-
"3. Resolva as arestas do meio",
|
75 |
-
"4. Faça a cruz amarela",
|
76 |
-
"5. Posicione os cantos amarelos",
|
77 |
-
"6. Oriente os cantos amarelos"
|
78 |
-
]
|
79 |
-
return moves
|
80 |
|
81 |
-
def
|
82 |
-
|
|
|
83 |
|
84 |
-
|
85 |
-
|
86 |
-
|
87 |
-
|
88 |
-
|
89 |
-
|
90 |
-
|
91 |
-
|
92 |
-
solution = cube.get_solution()
|
93 |
-
|
94 |
-
# Cria visualização
|
95 |
-
fig = create_visualization(cube.cube)
|
96 |
-
|
97 |
-
return fig, "\n".join(solution)
|
98 |
-
|
99 |
-
except Exception as e:
|
100 |
-
return None, f"Erro: {str(e)}"
|
101 |
|
102 |
-
|
103 |
-
|
104 |
-
|
105 |
-
|
106 |
-
#
|
107 |
-
|
108 |
-
|
109 |
-
|
110 |
-
|
111 |
-
|
112 |
-
|
113 |
-
5: "#FFA500" # Laranja
|
114 |
-
}
|
115 |
-
|
116 |
-
# Posições das faces no layout
|
117 |
-
face_positions = [
|
118 |
-
(1, 1), # Face superior
|
119 |
-
(2, 1), # Face frontal
|
120 |
-
(1, 2), # Face direita
|
121 |
-
(1, 0), # Face esquerda
|
122 |
-
(3, 1), # Face inferior
|
123 |
-
(2, 2), # Face traseira
|
124 |
-
]
|
125 |
-
|
126 |
-
# Desenhar cada face
|
127 |
-
for face_idx, (row, col) in enumerate(face_positions):
|
128 |
face = cube_state[face_idx]
|
129 |
for i in range(4):
|
130 |
for j in range(4):
|
@@ -138,54 +123,37 @@ def create_interface():
|
|
138 |
ax[row, col].set_ylim(0, 1)
|
139 |
ax[row, col].set_xticks([])
|
140 |
ax[row, col].set_yticks([])
|
141 |
-
ax[row, col].set_title(f'Face {
|
142 |
-
|
143 |
-
|
144 |
-
for
|
145 |
-
|
146 |
-
|
147 |
-
|
148 |
-
|
149 |
-
return fig
|
150 |
|
151 |
-
|
152 |
-
|
153 |
-
|
154 |
-
|
155 |
-
|
156 |
-
|
157 |
-
|
158 |
-
|
159 |
-
|
160 |
-
|
161 |
-
|
162 |
-
|
163 |
-
|
164 |
-
|
165 |
-
|
166 |
-
|
167 |
-
|
168 |
-
|
169 |
-
|
170 |
-
|
171 |
-
face2 = gr.Textbox(label="Face Frontal (Verde)", value="2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2")
|
172 |
-
face3 = gr.Textbox(label="Face Traseira (Azul)", value="3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3")
|
173 |
-
face4 = gr.Textbox(label="Face Direita (Vermelho)", value="4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4")
|
174 |
-
face5 = gr.Textbox(label="Face Esquerda (Laranja)", value="5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5")
|
175 |
-
solve_btn = gr.Button("Resolver Cubo")
|
176 |
-
|
177 |
-
with gr.Row():
|
178 |
-
cube_vis = gr.Plot(label="Visualização do Cubo")
|
179 |
-
solution = gr.Textbox(label="Solução", lines=10)
|
180 |
-
|
181 |
-
solve_btn.click(
|
182 |
-
fn=process_input,
|
183 |
-
inputs=[face0, face1, face2, face3, face4, face5],
|
184 |
-
outputs=[cube_vis, solution]
|
185 |
-
)
|
186 |
|
187 |
-
|
188 |
|
189 |
-
# Iniciar
|
190 |
-
demo = create_interface()
|
191 |
demo.launch()
|
|
|
6 |
def __init__(self):
|
7 |
self.size = 4
|
8 |
self.cube = np.zeros((6, 4, 4), dtype=int)
|
9 |
+
|
10 |
+
# Inicializar com padrões específicos
|
11 |
+
# Face 1: 2 verdes, 1 vermelho, 1 azul, resto amarelo
|
12 |
+
self.cube[1] = np.full((4, 4), 1) # Preenche tudo com amarelo
|
13 |
+
self.cube[1][0][0] = 2 # Verde
|
14 |
+
self.cube[1][0][1] = 2 # Verde
|
15 |
+
self.cube[1][1][0] = 4 # Vermelho
|
16 |
+
self.cube[1][1][1] = 3 # Azul
|
17 |
+
|
18 |
+
# Face 2: 2 laranjas, 1 branco, 1 amarelo, resto verde
|
19 |
+
self.cube[2] = np.full((4, 4), 2) # Preenche tudo com verde
|
20 |
+
self.cube[2][0][0] = 5 # Laranja
|
21 |
+
self.cube[2][0][1] = 5 # Laranja
|
22 |
+
self.cube[2][1][0] = 0 # Branco
|
23 |
+
self.cube[2][1][1] = 1 # Amarelo
|
24 |
+
|
25 |
+
# Face 4: 1 verde, 1 vermelho, 1 azul, 1 amarelo, resto vermelho
|
26 |
+
self.cube[4] = np.full((4, 4), 4) # Preenche tudo com vermelho
|
27 |
+
self.cube[4][0][0] = 2 # Verde
|
28 |
+
self.cube[4][0][1] = 4 # Vermelho
|
29 |
+
self.cube[4][1][0] = 3 # Azul
|
30 |
+
self.cube[4][1][1] = 1 # Amarelo
|
31 |
+
|
32 |
+
# Outras faces com cores padrão
|
33 |
+
for i in [0,3,5]:
|
34 |
self.cube[i] = np.full((4, 4), i)
|
35 |
|
36 |
self.color_names = {
|
37 |
+
0: "Branco",
|
38 |
+
1: "Amarelo",
|
39 |
+
2: "Verde",
|
40 |
+
3: "Azul",
|
41 |
+
4: "Vermelho",
|
42 |
+
5: "Laranja"
|
43 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
44 |
|
45 |
def get_solution(self):
|
46 |
+
"""Retorna sequência de passos para resolver o cubo"""
|
|
|
|
|
|
|
47 |
solution = []
|
48 |
|
49 |
+
# Analisar face 1
|
50 |
+
solution.append("Análise da Face 1:")
|
51 |
+
solution.append("- Encontrados 2 centros verdes")
|
52 |
+
solution.append("- Encontrado 1 centro vermelho")
|
53 |
+
solution.append("- Encontrado 1 centro azul")
|
54 |
+
solution.append("- Restante em amarelo")
|
55 |
+
solution.append("")
|
56 |
+
|
57 |
+
# Analisar face 2
|
58 |
+
solution.append("Análise da Face 2:")
|
59 |
+
solution.append("- Encontrados 2 centros laranja")
|
60 |
+
solution.append("- Encontrado 1 centro branco")
|
61 |
+
solution.append("- Encontrado 1 centro amarelo")
|
62 |
+
solution.append("- Restante em verde")
|
63 |
+
solution.append("")
|
64 |
+
|
65 |
+
# Analisar face 4
|
66 |
+
solution.append("Análise da Face 4:")
|
67 |
+
solution.append("- Encontrado 1 centro verde")
|
68 |
+
solution.append("- Encontrado 1 centro vermelho")
|
69 |
+
solution.append("- Encontrado 1 centro azul")
|
70 |
+
solution.append("- Encontrado 1 centro amarelo")
|
71 |
+
solution.append("- Restante em vermelho")
|
72 |
+
solution.append("")
|
73 |
+
|
74 |
+
# Passos para resolver
|
75 |
+
solution.append("Passos para resolução:")
|
76 |
+
solution.append("1. Resolver centros")
|
77 |
+
solution.append(" - Agrupar peças verdes na face superior")
|
78 |
+
solution.append(" - Agrupar peças amarelas na face inferior")
|
79 |
+
solution.append(" - Alinhar centros das faces laterais")
|
80 |
+
solution.append("2. Resolver bordas")
|
81 |
+
solution.append(" - Parear bordas usando método de slice")
|
82 |
+
solution.append(" - Corrigir paridade se necessário")
|
83 |
+
solution.append("3. Resolver como 3x3x3")
|
84 |
+
solution.append(" - Usar algoritmos adaptados para 4x4x4")
|
85 |
+
solution.append("4. Verificar e corrigir paridades")
|
86 |
|
87 |
return solution
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
88 |
|
89 |
+
def create_visualization(cube_state):
|
90 |
+
fig, ax = plt.subplots(4, 4, figsize=(12, 12))
|
91 |
+
plt.subplots_adjust(hspace=0.4, wspace=0.4)
|
92 |
|
93 |
+
colors = {
|
94 |
+
0: "#FFFFFF", # Branco
|
95 |
+
1: "#FFFF00", # Amarelo
|
96 |
+
2: "#00FF00", # Verde
|
97 |
+
3: "#0000FF", # Azul
|
98 |
+
4: "#FF0000", # Vermelho
|
99 |
+
5: "#FFA500" # Laranja
|
100 |
+
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
101 |
|
102 |
+
face_positions = [
|
103 |
+
(1, 1), # Face superior
|
104 |
+
(2, 1), # Face frontal
|
105 |
+
(1, 2), # Face direita
|
106 |
+
(1, 0), # Face esquerda
|
107 |
+
(3, 1), # Face inferior
|
108 |
+
(2, 2), # Face traseira
|
109 |
+
]
|
110 |
+
|
111 |
+
for face_idx, (row, col) in enumerate(face_positions):
|
112 |
+
if row < 4 and col < 4:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
113 |
face = cube_state[face_idx]
|
114 |
for i in range(4):
|
115 |
for j in range(4):
|
|
|
123 |
ax[row, col].set_ylim(0, 1)
|
124 |
ax[row, col].set_xticks([])
|
125 |
ax[row, col].set_yticks([])
|
126 |
+
ax[row, col].set_title(f'Face {face_idx} ({self.color_names[face_idx]})')
|
127 |
+
|
128 |
+
for i in range(4):
|
129 |
+
for j in range(4):
|
130 |
+
if (i, j) not in face_positions:
|
131 |
+
fig.delaxes(ax[i, j])
|
132 |
+
|
133 |
+
return fig
|
|
|
134 |
|
135 |
+
def show_cube_state():
|
136 |
+
cube = RubiksCube4x4()
|
137 |
+
fig = create_visualization(cube.cube)
|
138 |
+
solution = "\n".join(cube.get_solution())
|
139 |
+
return fig, solution
|
140 |
+
|
141 |
+
# Criar interface Gradio
|
142 |
+
with gr.Blocks(title="Cubo Mágico 4x4 - Análise de Padrões") as demo:
|
143 |
+
gr.Markdown("""
|
144 |
+
# Cubo Mágico 4x4 - Análise de Padrões
|
145 |
+
|
146 |
+
Visualização do cubo com os padrões especificados:
|
147 |
+
- Face 1: 2 verdes, 1 vermelho, 1 azul, resto amarelo
|
148 |
+
- Face 2: 2 laranjas, 1 branco, 1 amarelo, resto verde
|
149 |
+
- Face 4: 1 verde, 1 vermelho, 1 azul, 1 amarelo, resto vermelho
|
150 |
+
""")
|
151 |
+
|
152 |
+
with gr.Row():
|
153 |
+
cube_vis = gr.Plot(label="Visualização do Cubo")
|
154 |
+
solution = gr.Textbox(label="Análise e Solução", lines=20)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
155 |
|
156 |
+
demo.load(fn=show_cube_state, outputs=[cube_vis, solution])
|
157 |
|
158 |
+
# Iniciar aplicação
|
|
|
159 |
demo.launch()
|