Spaces:
Sleeping
Sleeping
Update app.py
Browse files
app.py
CHANGED
@@ -1,8 +1,89 @@
|
|
1 |
import gradio as gr
|
2 |
import numpy as np
|
3 |
import matplotlib.pyplot as plt
|
4 |
-
|
5 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
6 |
def num_to_color(num):
|
7 |
colors = {
|
8 |
0: "#FFFFFF", # Branco
|
@@ -18,13 +99,11 @@ def create_cube_visualization(cube_state):
|
|
18 |
fig, ax = plt.subplots(4, 3, figsize=(10, 12))
|
19 |
plt.subplots_adjust(hspace=0.4, wspace=0.4)
|
20 |
|
21 |
-
# Desabilitar eixos
|
22 |
for row in ax:
|
23 |
for col in row:
|
24 |
col.set_xticks([])
|
25 |
col.set_yticks([])
|
26 |
|
27 |
-
# Posições das faces no layout planificado
|
28 |
face_positions = [
|
29 |
(1, 1), # Face superior (branco)
|
30 |
(2, 1), # Face frontal (verde)
|
@@ -34,7 +113,6 @@ def create_cube_visualization(cube_state):
|
|
34 |
(2, 2), # Face traseira (azul)
|
35 |
]
|
36 |
|
37 |
-
# Desenhar cada face
|
38 |
for face_idx, (row, col) in enumerate(face_positions):
|
39 |
if row < 4 and col < 3:
|
40 |
face = cube_state[face_idx]
|
@@ -46,7 +124,6 @@ def create_cube_visualization(cube_state):
|
|
46 |
ax[row, col].set_ylim(0, 1)
|
47 |
ax[row, col].set_title(f'Face {cube.color_names[face_idx]}')
|
48 |
|
49 |
-
# Remover subplots vazios
|
50 |
for row in range(4):
|
51 |
for col in range(3):
|
52 |
if (row, col) not in face_positions:
|
@@ -54,8 +131,7 @@ def create_cube_visualization(cube_state):
|
|
54 |
|
55 |
return fig
|
56 |
|
57 |
-
def process_moves(
|
58 |
-
"""Processa os movimentos solicitados e retorna a visualização atualizada"""
|
59 |
moves_list = moves.strip().split('\n')
|
60 |
output_text = []
|
61 |
|
@@ -78,8 +154,7 @@ def process_moves(cube, moves, current_state):
|
|
78 |
|
79 |
return fig, "\n".join(output_text), status
|
80 |
|
81 |
-
def scramble_cube(
|
82 |
-
"""Embaralha o cubo com n movimentos"""
|
83 |
moves = cube.scramble(int(n_moves))
|
84 |
fig = create_cube_visualization(cube.cube)
|
85 |
status = "Resolvido!" if cube.is_solved() else "Não resolvido"
|
@@ -113,15 +188,14 @@ with gr.Blocks(title="Cubo Mágico") as demo:
|
|
113 |
output_text = gr.Textbox(label="Movimentos realizados", lines=5)
|
114 |
status_text = gr.Textbox(label="Status")
|
115 |
|
116 |
-
# Conectar os botões às funções
|
117 |
scramble_btn.click(
|
118 |
-
fn=
|
119 |
inputs=[n_moves],
|
120 |
outputs=[cube_plot, output_text, status_text]
|
121 |
)
|
122 |
|
123 |
move_btn.click(
|
124 |
-
fn=
|
125 |
inputs=[moves_input, status_text],
|
126 |
outputs=[cube_plot, output_text, status_text]
|
127 |
)
|
|
|
1 |
import gradio as gr
|
2 |
import numpy as np
|
3 |
import matplotlib.pyplot as plt
|
4 |
+
import random
|
5 |
|
6 |
+
# Classe RubiksCube
|
7 |
+
class RubiksCube:
|
8 |
+
def __init__(self):
|
9 |
+
self.cube = np.zeros((6, 3, 3), dtype=int)
|
10 |
+
for i in range(6):
|
11 |
+
self.cube[i] = np.full((3, 3), i)
|
12 |
+
|
13 |
+
self.color_names = {
|
14 |
+
0: "Branco",
|
15 |
+
1: "Amarelo",
|
16 |
+
2: "Verde",
|
17 |
+
3: "Azul",
|
18 |
+
4: "Vermelho",
|
19 |
+
5: "Laranja"
|
20 |
+
}
|
21 |
+
|
22 |
+
def rotate_face_clockwise(self, face_num):
|
23 |
+
if 0 <= face_num < 6:
|
24 |
+
self.cube[face_num] = np.rot90(self.cube[face_num], k=-1)
|
25 |
+
self._update_adjacent_faces(face_num, clockwise=True)
|
26 |
+
|
27 |
+
def rotate_face_counterclockwise(self, face_num):
|
28 |
+
if 0 <= face_num < 6:
|
29 |
+
self.cube[face_num] = np.rot90(self.cube[face_num], k=1)
|
30 |
+
self._update_adjacent_faces(face_num, clockwise=False)
|
31 |
+
|
32 |
+
def _update_adjacent_faces(self, face_num, clockwise=True):
|
33 |
+
adjacent_faces = {
|
34 |
+
0: [(2,0), (4,0), (3,0), (5,0)], # Topo
|
35 |
+
1: [(2,2), (5,2), (3,2), (4,2)], # Base
|
36 |
+
2: [(0,2), (4,3), (1,0), (5,1)], # Frente
|
37 |
+
3: [(0,0), (5,3), (1,2), (4,1)], # Traseira
|
38 |
+
4: [(0,1), (2,1), (1,1), (3,3)], # Direita
|
39 |
+
5: [(0,3), (3,1), (1,3), (2,3)] # Esquerda
|
40 |
+
}
|
41 |
+
|
42 |
+
affected = adjacent_faces[face_num]
|
43 |
+
temp_values = []
|
44 |
+
|
45 |
+
for face, edge in affected:
|
46 |
+
if edge == 0:
|
47 |
+
temp_values.append(self.cube[face][0].copy())
|
48 |
+
elif edge == 1:
|
49 |
+
temp_values.append(self.cube[face][:,2].copy())
|
50 |
+
elif edge == 2:
|
51 |
+
temp_values.append(self.cube[face][2].copy())
|
52 |
+
else: # edge == 3
|
53 |
+
temp_values.append(self.cube[face][:,0].copy())
|
54 |
+
|
55 |
+
if clockwise:
|
56 |
+
temp_values = [temp_values[-1]] + temp_values[:-1]
|
57 |
+
else:
|
58 |
+
temp_values = temp_values[1:] + [temp_values[0]]
|
59 |
+
|
60 |
+
for (face, edge), new_values in zip(affected, temp_values):
|
61 |
+
if edge == 0:
|
62 |
+
self.cube[face][0] = new_values
|
63 |
+
elif edge == 1:
|
64 |
+
self.cube[face][:,2] = new_values
|
65 |
+
elif edge == 2:
|
66 |
+
self.cube[face][2] = new_values
|
67 |
+
else: # edge == 3
|
68 |
+
self.cube[face][:,0] = new_values
|
69 |
+
|
70 |
+
def is_solved(self):
|
71 |
+
return all(np.all(self.cube[face] == face) for face in range(6))
|
72 |
+
|
73 |
+
def scramble(self, num_moves=20):
|
74 |
+
moves = []
|
75 |
+
for _ in range(num_moves):
|
76 |
+
face = random.randint(0, 5)
|
77 |
+
direction = random.choice([True, False])
|
78 |
+
if direction:
|
79 |
+
self.rotate_face_clockwise(face)
|
80 |
+
moves.append(f"Rotação horária da face {self.color_names[face]}")
|
81 |
+
else:
|
82 |
+
self.rotate_face_counterclockwise(face)
|
83 |
+
moves.append(f"Rotação anti-horária da face {self.color_names[face]}")
|
84 |
+
return moves
|
85 |
+
|
86 |
+
# Funções de interface
|
87 |
def num_to_color(num):
|
88 |
colors = {
|
89 |
0: "#FFFFFF", # Branco
|
|
|
99 |
fig, ax = plt.subplots(4, 3, figsize=(10, 12))
|
100 |
plt.subplots_adjust(hspace=0.4, wspace=0.4)
|
101 |
|
|
|
102 |
for row in ax:
|
103 |
for col in row:
|
104 |
col.set_xticks([])
|
105 |
col.set_yticks([])
|
106 |
|
|
|
107 |
face_positions = [
|
108 |
(1, 1), # Face superior (branco)
|
109 |
(2, 1), # Face frontal (verde)
|
|
|
113 |
(2, 2), # Face traseira (azul)
|
114 |
]
|
115 |
|
|
|
116 |
for face_idx, (row, col) in enumerate(face_positions):
|
117 |
if row < 4 and col < 3:
|
118 |
face = cube_state[face_idx]
|
|
|
124 |
ax[row, col].set_ylim(0, 1)
|
125 |
ax[row, col].set_title(f'Face {cube.color_names[face_idx]}')
|
126 |
|
|
|
127 |
for row in range(4):
|
128 |
for col in range(3):
|
129 |
if (row, col) not in face_positions:
|
|
|
131 |
|
132 |
return fig
|
133 |
|
134 |
+
def process_moves(moves, current_state):
|
|
|
135 |
moves_list = moves.strip().split('\n')
|
136 |
output_text = []
|
137 |
|
|
|
154 |
|
155 |
return fig, "\n".join(output_text), status
|
156 |
|
157 |
+
def scramble_cube(n_moves):
|
|
|
158 |
moves = cube.scramble(int(n_moves))
|
159 |
fig = create_cube_visualization(cube.cube)
|
160 |
status = "Resolvido!" if cube.is_solved() else "Não resolvido"
|
|
|
188 |
output_text = gr.Textbox(label="Movimentos realizados", lines=5)
|
189 |
status_text = gr.Textbox(label="Status")
|
190 |
|
|
|
191 |
scramble_btn.click(
|
192 |
+
fn=scramble_cube,
|
193 |
inputs=[n_moves],
|
194 |
outputs=[cube_plot, output_text, status_text]
|
195 |
)
|
196 |
|
197 |
move_btn.click(
|
198 |
+
fn=process_moves,
|
199 |
inputs=[moves_input, status_text],
|
200 |
outputs=[cube_plot, output_text, status_text]
|
201 |
)
|