Os botões Dica e Automático abaixo do tabuleiro não dão conselhos prontos. Eles fazem uma busca de verdade sobre a sua posição exata, no seu navegador, e devolvem a jogada mais bem avaliada. Dica mostra uma seta sobre o tabuleiro; Automático continua fazendo essa jogada até a partida acabar. Nada é enviado a nenhum servidor.
Deixada jogando sozinha a partir de um tabuleiro novo, essa busca termina com um bloco 2048 em 91,4% das partidas. É assim que ela consegue.
A ferramenta óbvia para uma árvore de jogo é o minimax: supor que o adversário escolhe a pior resposta possível e planejar contra ela. O 2048 não tem adversário. Ele tem um bloco que aparece ao acaso, e essa diferença importa muito.
Um jogador minimax trata o surgimento dos blocos como algo mal-intencionado e supõe que o 4 sempre cai na pior célula possível. Isso produz um jogo paranoico e defensivo, que gasta todo o seu orçamento se protegendo de um tabuleiro que acontece talvez uma vez a cada trinta. O expectimax, por outro lado, tira a média de todos os surgimentos que podem acontecer de verdade, ponderada pela probabilidade de cada um. Ele joga com as probabilidades, não com o pesadelo — o modelo certo quando o acaso não está nem a seu favor nem contra você.
Então a busca alterna entre dois tipos de nó. Em um nó do jogador, ela testa as quatro direções e fica com o melhor resultado. Em um nó de acaso, ela coloca um 2 em cada célula vazia com peso 0,9 e um 4 em cada célula vazia com peso 0,1, avalia cada caso e tira a média — a mesma proporção 90/10 que o próprio jogo usa quando faz um bloco aparecer.
A árvore não pode ser explorada até o fim da partida, então, no fundo da busca, o solucionador pontua a posição com quatro medidas, somadas com estes pesos:
| Termo | Peso | O que mede |
|---|---|---|
| Células vazias | 2.7 | Simplesmente quantas células estão livres. É de longe o termo mais pesado: ficar sem espaço é como se perde. |
| Monotonia | 1 | Se os valores crescem de forma constante em uma direção ao longo das linhas e colunas, em vez de ir em zigue-zague. |
| Canto | 1 | Um bônus, proporcional ao tamanho, quando o maior bloco está em um dos quatro cantos. |
| Suavidade | 0.1 | Uma penalidade para blocos vizinhos de tamanhos muito diferentes: um 2 ao lado de um 512 nunca vai poder se fundir, então é peso morto. |
Três dessas quatro não passam do conselho humano de sempre escrito como aritmética: mantenha espaço livre, mantenha a ordem, mantenha o bloco grande em um canto. Os pesos são o que transforma o conselho em decisões: a busca aceita sem problema uma posição de canto pior se em troca ganhar células vazias suficientes, e essa troca é justamente a que as pessoas costumam errar na direção contrária.
Cada termo usa o logaritmo na base 2 do valor de um bloco em vez do valor em si, de modo que o salto de 2 para 4 conta o mesmo que o de 1024 para 2048. Sem isso, o maior bloco do tabuleiro abafaria todo o resto.
Os nós de acaso se ramificam uma vez por célula vazia, e em dobro. Um tabuleiro aberto com dez células livres tem vinte ramos em cada nível; um quase cheio com três células livres tem seis. Explorar os dois na mesma profundidade seria fazer ao contrário: o tabuleiro aberto é fácil de sobreviver e caro de explorar, e o tabuleiro cheio é exatamente o oposto.
Por isso a profundidade se adapta ao tabuleiro:
| Células vazias | Profundidade da busca |
|---|---|
| 7 ou mais | 2 jogadas à frente |
| De 4 a 6 | 3 jogadas à frente |
| 3 ou menos | 4 jogadas à frente |
É o mesmo instinto de um bom jogador humano — dar uma olhada rápida em um tabuleiro aberto e frear de vez quando ele fica difícil —, só que aplicado com precisão, e graças a isso a seta aparece quase assim que você clica, em qualquer fase da partida.
Em 500 partidas completas, ele chegou a 2048 em 91,4%, com pontuação mediana de 37.004 e duração mediana de 1.943 jogadas. Os resultados completos, com as referências colocam esses números em contexto.
Não é um bot de 2048 de ponta, e vale deixar isso claro. Os solucionadores publicados chegam a 32768 buscando muito mais fundo, com representações em bitboard, tabelas de jogadas pré-calculadas e caches de transposição. Este roda com uma matriz comum na thread principal do navegador, não guarda cache entre jogadas e é limitado a quatro níveis para que a página nunca trave. Ele foi feito para responder “o que eu faço aqui?” rápido o bastante para parecer instantâneo, não para bater recordes.
O jeito mais útil de usar a Dica não é obedecer a ela. Decida primeiro a sua própria jogada e só depois aperte o botão. Quando a seta concorda, você não aprendeu nada que já não soubesse, mas quando ela discorda, você encontrou um tabuleiro que está lendo errado — e é aí que você melhora de verdade.
O Automático serve mais como demonstração do que como resgate. Ligue-o a partir de uma posição que deu trabalho a você e observe que direção ele protege e quais fusões ele se recusa a fazer. Apertar uma seta a qualquer momento devolve o controle na hora.
O solucionador tem umas 250 linhas de JavaScript sem dependências, servidas como um arquivo comum em /js/ai.js: você pode lê-lo pelo “ver código-fonte” do navegador se quiser conferir qualquer coisa daqui.
Pronto para colocar em prática?
Jogar 2048