File size: 5,528 Bytes
a2f6240 c79a44e a2f6240 c79a44e a2f6240 c79a44e a2f6240 c79a44e a2f6240 c79a44e a2f6240 c79a44e a2f6240 c79a44e a2f6240 c79a44e a2f6240 c79a44e a2f6240 c79a44e a2f6240 c79a44e a2f6240 c79a44e a2f6240 c79a44e a2f6240 c79a44e a2f6240 c79a44e a2f6240 c79a44e a2f6240 c79a44e a2f6240 c79a44e a2f6240 c79a44e a2f6240 c79a44e a2f6240 c79a44e a2f6240 c79a44e a2f6240 c79a44e a2f6240 | 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 | import gradio as gr
import time
# Dados baseados na sua versão 1.4 EN
GRID_NUMBERS = [
10, 12, 14, 15, 16, 18, 20, 21,
24, 25, 27, 28, 30, 32, 35, 36,
40, 42, 45, 48, 50, 54, 56, 60,
63, 64, 70, 72, 80, 81, 90, 100
]
KEYBOARD_KEYS = [2, 3, 4, 5, 6, 7, 8, 9, 10]
MAX_TIME = 150
def get_empty_state():
"""Inicializa o estado conforme o script original"""
return {
"solved": [False] * 32,
"selected_idx": None,
"current_factors": [],
"start_time": time.time(),
"game_over": False,
"score": MAX_TIME
}
def format_grid_button(idx, solved_list, selected_idx):
label = str(GRID_NUMBERS[idx])
if solved_list[idx]:
return gr.update(value=f"✅ {label}", variant="success", interactive=False)
if selected_idx == idx:
return gr.update(variant="primary", interactive=True)
return gr.update(value=label, variant="secondary", interactive=True)
def handle_game_logic(state, action_type, value=None):
if state["game_over"]:
return state, "Fim de jogo! Reinicie para jogar novamente."
feedback = "Selecione um número na grade..."
if action_type == "select_target":
state["selected_idx"] = value
state["current_factors"] = []
feedback = f"Fatorar o número: {GRID_NUMBERS[value]}"
elif action_type == "select_factor":
if state["selected_idx"] is None:
feedback = "⚠️ Selecione um número na grade primeiro!"
else:
state["current_factors"].append(int(value))
# Mostra os fatores atuais
factors_str = " x ".join(map(str, state["current_factors"]))
feedback = f"Calculando: {factors_str}"
if len(state["current_factors"]) == 2:
a, b = state["current_factors"]
target = GRID_NUMBERS[state["selected_idx"]]
if a * b == target:
state["solved"][state["selected_idx"]] = True
feedback = f"✔️ {a} x {b} = {target}! Correto!"
state["selected_idx"] = None
state["current_factors"] = []
else:
feedback = f"❌ {a} x {b} = {a*b} (Errado para {target}). Tente de novo!"
state["current_factors"] = []
# Atualiza Score e Verifica Conclusão
elapsed = int(time.time() - state["start_time"])
state["score"] = max(0, MAX_TIME - elapsed)
if all(state["solved"]):
state["game_over"] = True
feedback = f"🏆 PARABÉNS! Você completou a grade com {state['score']} pontos!"
return state, feedback
with gr.Blocks(title="Interactive Factorization v1.4", css=".grid-btn { height: 70px !important; }") as demo:
state = gr.State(get_empty_state())
gr.Markdown(f"# 🎮 Interactive Factorization - Marcos Autúori")
with gr.Row():
with gr.Column(scale=3):
# Grade de Números (4x8)
grid_buttons = []
for r in range(4):
with gr.Row():
for c in range(8):
idx = r * 8 + c
btn = gr.Button(str(GRID_NUMBERS[idx]), elem_classes="grid-btn")
grid_buttons.append(btn)
with gr.Column(scale=1):
# Painel Lateral de Status
status_box = gr.Textbox(label="Instruções / Feedback", value="Clique em um número azul para começar", interactive=False)
score_display = gr.Number(label="Pontuação", value=MAX_TIME, interactive=False)
gr.Markdown("### Teclado de Fatores")
# Criamos os botões do teclado e vinculamos a lógica
keyboard_btns = []
with gr.Row():
for val in KEYBOARD_KEYS:
kb_btn = gr.Button(str(val), variant="secondary", min_width=50)
keyboard_btns.append(kb_btn)
reset_btn = gr.Button("Reiniciar Partida", variant="stop")
# --- MAPEAMENTO DE EVENTOS ---
# Função auxiliar para atualizar visualmente toda a interface
def update_ui(s):
updates = [format_grid_button(i, s["solved"], s["selected_idx"]) for i in range(32)]
return updates + [s["score"]]
# Clique na Grade
for i, btn in enumerate(grid_buttons):
btn.click(
fn=lambda s, idx=i: handle_game_logic(s, "select_target", idx),
inputs=[state],
outputs=[state, status_box]
).then(fn=update_ui, inputs=[state], outputs=grid_buttons + [score_display])
# Clique no Teclado (Correção da Closure aqui)
for kb_btn in keyboard_btns:
# Usamos o próprio valor do botão como entrada para garantir que o número correto seja enviado
kb_btn.click(
fn=lambda s, v=kb_btn.value: handle_game_logic(s, "select_factor", v),
inputs=[state],
outputs=[state, status_box]
).then(fn=update_ui, inputs=[state], outputs=grid_buttons + [score_display])
# Função de Reset
def reset_all():
new_state = get_empty_state()
updates = [gr.update(value=str(num), variant="secondary", interactive=True) for num in GRID_NUMBERS]
return [new_state, "Jogo reiniciado!"] + updates + [MAX_TIME]
reset_btn.click(
fn=reset_all,
outputs=[state, status_box] + grid_buttons + [score_display]
)
if __name__ == "__main__":
demo.launch() |