DHEIVER commited on
Commit
6b09c13
·
verified ·
1 Parent(s): 2eb8c3b

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +166 -191
app.py CHANGED
@@ -1,216 +1,191 @@
1
  import gradio as gr
2
  import numpy as np
3
  import matplotlib.pyplot as plt
4
- import random
5
 
6
- # Classe RubiksCube (mantém o mesmo código)
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
90
- 1: "#FFFF00", # Amarelo
91
- 2: "#00FF00", # Verde
92
- 3: "#0000FF", # Azul
93
- 4: "#FF0000", # Vermelho
94
- 5: "#FFA500" # Laranja
95
- }
96
- return colors.get(num, "#CCCCCC")
97
-
98
- def create_cube_visualization(cube_state):
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)
110
- (1, 2), # Face direita (vermelho)
111
- (1, 0), # Face esquerda (laranja)
112
- (3, 1), # Face inferior (amarelo)
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]
119
- for i in range(3):
120
- for j in range(3):
121
- color = num_to_color(face[i, j])
122
- ax[row, col].add_patch(plt.Rectangle((j/3, (2-i)/3), 1/3, 1/3, facecolor=color, edgecolor='black'))
 
 
 
 
123
  ax[row, col].set_xlim(0, 1)
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:
130
- fig.delaxes(ax[row, col])
131
-
132
- return fig
133
-
134
- def process_moves(moves, current_state):
135
- moves_list = moves.strip().split('\n')
136
- output_text = []
137
-
138
- for move in moves_list:
139
- move = move.strip().lower()
140
- try:
141
- if move.startswith('r'): # rotação horária
142
- face = int(move[1])
143
- cube.rotate_face_clockwise(face)
144
- output_text.append(f"Rotação horária da face {cube.color_names[face]}")
145
- elif move.startswith('l'): # rotação anti-horária
146
- face = int(move[1])
147
- cube.rotate_face_counterclockwise(face)
148
- output_text.append(f"Rotação anti-horária da face {cube.color_names[face]}")
149
- except:
150
- output_text.append(f"Movimento inválido: {move}")
151
-
152
- fig = create_cube_visualization(cube.cube)
153
- status = "Resolvido!" if cube.is_solved() else "Não resolvido"
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"
161
- return fig, "\n".join(moves), status
162
-
163
- def show_initial_state():
164
- fig = create_cube_visualization(cube.cube)
165
- return fig, "", "Cubo inicial"
166
-
167
- # Criar instância do cubo
168
- cube = RubiksCube()
169
 
170
- # Criar interface Gradio
171
- with gr.Blocks(title="Cubo Mágico") as demo:
172
- gr.Markdown("# Simulador de Cubo Mágico")
173
- gr.Markdown("""
174
- ### Como usar:
175
- 1. Use o botão 'Embaralhar' para misturar o cubo
176
- 2. Digite movimentos no formato:
177
- - r0 (rotação horária da face 0)
178
- - l0 (rotação anti-horária da face 0)
179
- onde o número representa a face:
180
- 0: Branco, 1: Amarelo, 2: Verde, 3: Azul, 4: Vermelho, 5: Laranja
181
- """)
182
-
183
- with gr.Row():
184
- with gr.Column():
185
- n_moves = gr.Slider(minimum=1, maximum=20, value=5, step=1, label="Número de movimentos para embaralhar")
186
- scramble_btn = gr.Button("Embaralhar")
187
- moves_input = gr.Textbox(label="Digite os movimentos (um por linha)", lines=5)
188
- move_btn = gr.Button("Executar Movimentos")
189
-
190
- with gr.Column():
191
- cube_plot = gr.Plot()
192
- output_text = gr.Textbox(label="Movimentos realizados", lines=5)
193
- status_text = gr.Textbox(label="Status")
194
-
195
- # Conectar os botões às funções
196
- scramble_btn.click(
197
- fn=scramble_cube,
198
- inputs=[n_moves],
199
- outputs=[cube_plot, output_text, status_text]
200
- )
201
-
202
- move_btn.click(
203
- fn=process_moves,
204
- inputs=[moves_input, status_text],
205
- outputs=[cube_plot, output_text, status_text]
206
- )
207
 
208
- # Carregar estado inicial
209
- demo.load(
210
- fn=show_initial_state,
211
- inputs=None,
212
- outputs=[cube_plot, output_text, status_text]
213
- )
214
 
215
  # Iniciar a aplicação
 
216
  demo.launch()
 
1
  import gradio as gr
2
  import numpy as np
3
  import matplotlib.pyplot as plt
 
4
 
5
+ class RubiksCube4x4:
 
6
  def __init__(self):
7
+ self.size = 4
8
+ self.cube = np.zeros((6, 4, 4), dtype=int)
9
  for i in range(6):
10
+ self.cube[i] = np.full((4, 4), i)
11
 
12
  self.color_names = {
13
+ 0: "Branco", # Face superior
14
+ 1: "Amarelo", # Face inferior
15
+ 2: "Verde", # Face frontal
16
+ 3: "Azul", # Face traseira
17
+ 4: "Vermelho", # Face direita
18
+ 5: "Laranja" # Face esquerda
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
+ # 1. Resolver centros
40
+ solution.extend(self._solve_centers())
41
+
42
+ # 2. Emparelhar arestas
43
+ solution.extend(self._pair_edges())
44
+
45
+ # 3. Resolver como um 3x3
46
+ solution.extend(self._solve_as_3x3())
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 create_interface():
82
+ cube = RubiksCube4x4()
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
83
 
84
+ def process_input(face0, face1, face2, face3, face4, face5):
85
+ try:
86
+ # Define as cores para cada face
87
+ faces = [face0, face1, face2, face3, face4, face5]
88
+ for i, face in enumerate(faces):
89
+ cube.set_face(i, face)
90
+
91
+ # Obtém a solução
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
+ def create_visualization(cube_state):
103
+ fig, ax = plt.subplots(4, 4, figsize=(12, 12))
104
+ plt.subplots_adjust(hspace=0.4, wspace=0.4)
105
+
106
+ # Configuração das cores
107
+ colors = {
108
+ 0: "#FFFFFF", # Branco
109
+ 1: "#FFFF00", # Amarelo
110
+ 2: "#00FF00", # Verde
111
+ 3: "#0000FF", # Azul
112
+ 4: "#FF0000", # Vermelho
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):
131
+ color = colors[face[i, j]]
132
+ ax[row, col].add_patch(plt.Rectangle(
133
+ (j/4, (3-i)/4), 1/4, 1/4,
134
+ facecolor=color,
135
+ edgecolor='black'
136
+ ))
137
  ax[row, col].set_xlim(0, 1)
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 {cube.color_names[face_idx]}')
142
+
143
+ # Remover subplots não utilizados
144
+ for i in range(4):
145
+ for j in range(4):
146
+ if (i, j) not in face_positions:
147
+ fig.delaxes(ax[i, j])
148
+
149
+ return fig
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
150
 
151
+ # Interface Gradio
152
+ with gr.Blocks(title="Resolvedor de Cubo Mágico 4x4") as demo:
153
+ gr.Markdown("""
154
+ # Resolvedor de Cubo Mágico 4x4
155
+
156
+ Digite as cores de cada face (16 números por face, separados por vírgula):
157
+ - 0: Branco (face superior)
158
+ - 1: Amarelo (face inferior)
159
+ - 2: Verde (face frontal)
160
+ - 3: Azul (face traseira)
161
+ - 4: Vermelho (face direita)
162
+ - 5: Laranja (face esquerda)
163
+
164
+ Exemplo para uma face branca: 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
165
+ """)
166
+
167
+ with gr.Row():
168
+ with gr.Column():
169
+ face0 = gr.Textbox(label="Face Superior (Branco)", value="0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0")
170
+ face1 = gr.Textbox(label="Face Inferior (Amarelo)", value="1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1")
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
+ return demo
 
 
 
 
 
188
 
189
  # Iniciar a aplicação
190
+ demo = create_interface()
191
  demo.launch()