
Método
O vlm_macro_client.py se conecta à tela em Qt e pergunta uma vez cada vez que surge uma peça nova.
- Desenha o tabuleiro como imagem, com 20 pixels por casa. Cada tipo de peça tem uma cor diferente.
- Junto com o nome da peça (I, O, T…), pergunta "um lugar para colocá-la de forma plana, sem buracos, eliminando linhas".
- A resposta é um JSON com target_rot (0–3) e target_x (0–9).
- Ajusta a rotação, move a peça até x e a solta de vez.
Resultados
Rodamos 2 partidas no mesmo motor.
- 12 e 11 peças, 0 linhas, 50 e 46 buracos
- Perguntamos 23 vezes, e nas 23 ele respeitou o formato JSON.
- O target_x foi 4 todas as 23 vezes. Só a rotação mudou, entre 1 (17 vezes) e 0 (6 vezes).
- Cada pergunta levou em média 5,7 segundos.
O resultado é igual ao do DQN macro. Ele constrói uma torre no meio e termina por volta de 12 peças.
Por que só sai x=4
- A imagem não tem números de coluna nem linhas de grade. Para descobrir a coluna é preciso contar as casas de 20 pixels, o que é difícil para um modelo 3B. No gomoku também, quando o VLM escolhia coordenadas só olhando a imagem, muitas vezes escolhia casas já ocupadas.
- No momento da pergunta, a peça nova está nas linhas ocultas e não aparece na imagem. A peça é informada só pelo nome.
- O prompt descreve target_x como "coluna", mas o x do motor é a borda esquerda de uma caixa 4×4. Mesmo escolhendo a coluna certa, as peças verticais caem uma ou duas casas à direita. O problema da coluna mais à esquerda do post 3 também continua.
Em vez de deixar o VLM inventar coordenadas, mudamos para o código calcular todos os lugares possíveis e deixar ao modelo só a escolha.
O código real desta etapa
Esta é a pergunta enviada ao VLM.
vlm_macro_client.py
def get_macro_action(self, obs: np.ndarray, current_piece_name: str) -> tuple[int, int]:
img = _grid_to_image(obs)
prompt = (
"You are an expert Tetris AI.\n"
f"A new piece ({current_piece_name}) has just appeared at the top of the board.\n"
"Look at the current board state and decide the best final resting position for this piece.\n"
"Return your decision strictly as JSON with two keys:\n"
'- "target_rot": an integer from 0 to 3 representing the number of clockwise rotations.\n'
'- "target_x": an integer representing the target column (0-9 for a standard board, from left to right).\n'
"Try to keep the stack flat, avoid creating holes, and clear lines if possible.\n"
"Return ONLY the JSON string. Do not output anything else."
)Ele pergunta uma vez quando surge uma peça nova e, depois disso, envia ações de baixo nível até chegar ao alvo.
vlm_macro_client.py
if piece_index > current_piece_index:
# New piece spawned. Ask VLM for macro action
piece_name = name_piece(piece_type)
print(f"\n--- New Piece Spawned: {piece_name} (Index: {piece_index}) ---")
current_piece_index = piece_index
target_rot, target_x = agent.get_macro_action(grid, piece_name)
target_x = max(0, min(target_x, w - 1))
print(f"VLM Decision -> Target Rot: {target_rot}, Target X: {target_x}")
# Translate target macro state to next micro action
micro = next_micro_for_target(piece_type, cur_rot, cur_x, target_rot, target_x)O próximo post é "5. O código calcula os lugares, o LLM só escolhe".
COMMENTS · CHAPTER 04
Deixando o VLM escolher diretamente o lugar da peça 0 comentários
Ainda não há comentários. Deixe uma pergunta ou algo que queira acrescentar.
Para publicar um comentário, comece com o Google e registre um apelido e um e-mail.
Começar com o Google