Ch355 - Stockfish
Do protótipo de 2015 para uma partida de verdade.
No post anterior eu parei exatamente onde a coisa começava a ficar interessante: eu já tinha um tabuleiro, as peças, as coordenadas e uma boa quantidade de regras implementadas manualmente. O que faltava era uma coisa que eu deliberadamente deixei para a CPU: tomar decisões.
É aqui que entra o Stockfish. Em vez de tentar transformar o meu antigo showLegalMoves() em uma inteligência artificial, a ideia agora é separar as responsabilidades: o código do Ch355 cuida da interface e da partida, enquanto o motor recebe a posição atual e devolve a melhor jogada que encontrou.
O protocolo UCI
O primeiro conceito importante é o UCI — Universal Chess Interface. É um protocolo textual usado para conversar com motores de xadrez. O navegador não precisa entender a estratégia do Stockfish; ele só precisa enviar comandos e interpretar as respostas.
uci
isready
position fen <FEN>
go depth 12
O comando uci inicializa o motor. Depois, isready verifica se ele está pronto. O comando position informa a posição atual e, finalmente, go depth 12 pede uma análise até a profundidade indicada.
A resposta que nos interessa é algo parecido com:
bestmove e7e5
Ou seja: o motor não precisa saber nada sobre o nosso HTML. Ele recebe uma posição padronizada e devolve uma jogada no formato de coordenadas que já estávamos estudando no post anterior.
FEN: uma fotografia do tabuleiro
Para transportar o estado completo da partida existe a FEN (Forsyth–Edwards Notation). Ela representa as peças, quem deve jogar, direitos de roque, possibilidade de en passant e os contadores necessários para a partida.
rnbqkbnr/pppppppp/8/8/4P3/8/PPPP1PPP/RNBQKBNR b KQkq - 0 1
Então a arquitetura fica muito mais limpa: a partida mantém o estado do jogo, transforma esse estado em FEN e o motor responde através do UCI. O Stockfish não precisa conhecer o nosso CSS, e o CSS definitivamente não precisa saber jogar xadrez. Cada um no seu quadrado — literalmente.
Engine dentro do navegador
Outra decisão importante foi não colocar o processamento do motor no PHP. O jogo é executado no navegador e o Stockfish roda em um Web Worker. Assim, o cálculo pesado acontece em outra thread e a interface continua respondendo aos cliques.
Para este primeiro jogo estou usando a versão lite single-threaded do Stockfish compilada para WebAssembly. É uma escolha deliberada: o arquivo é bem menor que a versão completa e não exige uma infraestrutura de servidor para fazer a partida acontecer.
Do protótipo ao Ch355
O mais interessante é que eu não precisei jogar fora o que foi construído em 2015. O protótipo continua sendo uma parte importante da história do projeto. Só que agora algumas responsabilidades mudam de lugar.
Usuário
↓
Interface do Ch355
↓
Estado da partida
↓
FEN
↓
Stockfish / UCI
↓
bestmove
↓
Nova posição
É uma diferença conceitual enorme em relação ao código original. Antes eu precisava escrever uma regra para cada peça e descobrir manualmente os movimentos possíveis. Agora o nosso código pode se concentrar na experiência de jogar, enquanto uma engine especializada faz o trabalho pesado de avaliação.
Também mantive a ideia que começou tudo: usar os caracteres Unicode das peças. Não precisamos de um pacote de imagens para cada Rei, Rainha, Torre, Bispo, Cavalo e Peão. O navegador já sabe desenhar os caracteres.
E finalmente...
Chegou a hora de parar de falar sobre o jogo e simplesmente jogar. A próxima página é independente do artigo e traz o tabuleiro, os controles e o adversário controlado pelo Stockfish.
Você joga com as peças brancas. O computador joga com as pretas.
