Uma biblioteca chess engine livre de dependências construída para ser executada em qualquer lugar.
Escrito em ferrugem??
Acima de tudo, este vídeo do Tom7 é a minha inspiração para este projeto. Ele é absolutamente brilhante e imploro que você assista ao conteúdo dele.
Eu amo muito xadrez. É definitivamente um dos meus jogos favoritos de todos os tempos. No entanto, sempre fiquei desapontado ao tentar escrever programas que jogassem xadrez digitalmente (principalmente em uma linguagem compilada). Embora existam vários mecanismos incríveis, é quase impossível encontrar uma biblioteca bacana para programação relacionada ao xadrez que rode em tudo.
o mecanismo de xadrez é uma solução para o meu problema. Se você deseja um chess engine que rode em dispositivos embarcados, no terminal, no desktop (com interface gráfica) e na web, esta é provavelmente sua melhor aposta.
Esta IA específica (junto com a maioria das outras IAs de xadrez) funciona usando o algoritmo Minimax, junto com a poda Alfa-Beta para otimização.
Agora, vamos descompactar isso.
O algoritmo Minimax essencialmente itera recursivamente todos os movimentos possíveis e avalia todos os tabuleiros após os movimentos serem jogados. Se o tabuleiro for mais favorável, ele encorajará a execução de seu movimento pai, mas se um tabuleiro for menos favorável, ele irá optar por não jogar um determinado movimento.
Além disso, quando a IA tenta ver além do tabuleiro atual, ela assumirá que o humano sempre responde com os melhores movimentos. Como resultado, o computador quase nunca comete erros. Isso permite que o computador quase sempre execute movimentos objetivamente melhores que o jogador.
Por não ter nenhuma dependência, é extremamente simples de incorporar no navegador da web usando wasm. Tente jogar você mesmo!
Configuração média de IA
A estrutura Board
possui alguns métodos diferentes que permitem aos usuários gerar movimentos a partir de uma determinada posição, incluindo get_best_next_move
, get_worst_next_move
e get_legal_moves
. Eles são particularmente úteis para escrever IAs de xadrez contra as quais jogar.
fn main ( ) {
let board = Board :: default ( ) ;
// Get the best move with 4 moves of lookahead
let best_move = board . get_best_next_move ( 4 ) ;
// Get the worst move with 3 moves of lookahead
let worst_move = board . get_worst_next_move ( 3 ) ;
// Get all of the possible legal moves for the given player
let legal_moves = board . get_legal_moves ( ) ;
// Print the board
println ! ( "{}" , board ) ;
print ! ( "CPU chose to " ) ;
match best_move {
Move :: Piece ( from , to ) => println ! ( "move {} to {}" , from, to ) ,
Move :: KingSideCastle => println ! ( "castle kingside" ) ,
Move :: QueenSideCastle => println ! ( "castle queenside" ) ,
Move :: Resign => println ! ( "resign" )
}
}
Para adicionar alguma variação ou jogo mais avançado, considere escrever uma IA que jogue aberturas conhecidas que construam posições melhores antes de usar o método get_best_next_move
!
Além disso, os usuários podem criar seus próprios objetos Board
personalizados, diferentes do padrão. Isso é feito usando a estrutura BoardBuilder
. A estrutura BoardBuilder
oferece suporte à ativação e desativação do roque, à colocação de linhas e colunas de peças e à colocação de peças individuais.
Tenha em mente que, ao usar um BoardBuilder
, o roque está desabilitado por padrão!
Jogue a variante do xadrez da Horda
fn main ( ) {
// `BoardBuilder::new()` returns an empty board
// with castling disabled.
// Creating a board builder from another board
// structure will preserve
// all settings from the board (such as castling
// and the last en-passant move).
// This BoardBuilder constructs the "Horde" chess variant!
let board = BoardBuilder :: from ( Board :: default ( ) )
. row ( Piece :: Pawn ( WHITE , A1 ) )
. row ( Piece :: Pawn ( WHITE , A2 ) )
. row ( Piece :: Pawn ( WHITE , A3 ) )
. row ( Piece :: Pawn ( WHITE , A4 ) )
. piece ( Piece :: Pawn ( WHITE , F5 ) )
. piece ( Piece :: Pawn ( WHITE , G5 ) )
. piece ( Piece :: Pawn ( WHITE , B5 ) )
. piece ( Piece :: Pawn ( WHITE , C5 ) )
. build ( ) ;
// The CPU can also play variants!
let cpu_move = board . get_best_next_move ( 3 ) ;
match board . play_move ( cpu_move ) {
GameResult :: Continuing ( next_board ) => {
println ! ( "{}" , next_board ) ;
}
GameResult :: Victory ( winner ) => {
// You can use the ! operator on a player's
// color to invert.
println ! ( "{} loses. {} is victorious." ,
!winner, winner
) ;
}
GameResult :: IllegalMove ( x ) => {
eprintln ! ( "{} is an illegal move." , x ) ;
}
GameResult :: Stalemate => {
println ! ( "Drawn game." ) ;
}
}
}
Sou um calouro na faculdade, trabalhando principalmente em projetos paralelos como esses nos intervalos de aproximadamente 30 minutos entre as aulas. Se você gosta dos meus projetos, considere me apoiar comprando um café para mim!