Une bibliothèque chess engine sans dépendance conçue pour fonctionner n'importe où.
Écrit en Rust ??
Surtout, cette vidéo de Tom7 est mon inspiration pour ce projet. Il est absolument génial et je vous implore de regarder son contenu.
J'aime beaucoup les échecs. C'est définitivement l'un de mes jeux préférés. Cependant, j'ai toujours été déçu lorsque j'essayais d'écrire des programmes permettant de jouer aux échecs de manière numérique (en particulier dans un langage compilé). Bien qu'il existe plusieurs moteurs étonnants, il est presque impossible de trouver une bibliothèque soignée pour la programmation liée aux échecs qui fonctionne sur tout.
Le moteur d'échecs est une solution à mon problème. Si vous voulez un chess engine qui fonctionne sur les appareils embarqués, le terminal, le bureau (avec une interface graphique) et le Web, c'est probablement votre meilleur choix.
Cette IA particulière (ainsi que la plupart des autres IA d'échecs) fonctionne en utilisant l'algorithme Minimax, ainsi que l'élagage Alpha-Beta pour l'optimisation.
Maintenant, déballons cela.
L'algorithme Minimax parcourt essentiellement tous les mouvements possibles de manière récursive et évalue tous les tableaux une fois les mouvements joués. Si le tableau est plus favorable, il encouragera à jouer son coup parent, mais si un tableau est moins favorable, il choisira de ne pas jouer un coup donné.
De plus, lorsque l’IA tente de voir au-delà du tableau actuel, elle supposera que l’humain répond toujours avec les meilleurs mouvements. En conséquence, l’ordinateur ne fait presque jamais d’erreur. Cela permet à l'ordinateur de jouer presque toujours objectivement de meilleurs coups que le joueur.
Parce qu'il n'a aucune dépendance, il est extrêmement simple à intégrer dans le navigateur Web à l'aide de wasm. Essayez d'y jouer vous-même !
Paramètres IA moyens
La structure Board
comporte plusieurs méthodes différentes qui permettent aux utilisateurs de générer des mouvements à partir d'une position donnée, notamment get_best_next_move
, get_worst_next_move
et get_legal_moves
. Ceux-ci sont particulièrement utiles pour écrire des IA d’échecs contre lesquelles jouer.
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" )
}
}
Pour ajouter une variante ou un jeu plus avancé, envisagez d'écrire une IA qui joue les ouvertures connues qui créent de meilleures positions avant d'utiliser la méthode get_best_next_move
!
De plus, les utilisateurs peuvent créer leurs propres objets Board
personnalisés autres que celui par défaut. Cela se fait en utilisant la structure BoardBuilder
. La structure BoardBuilder
prend en charge l'activation et la désactivation du roque, le placement de rangées et de colonnes de pièces et le placement de pièces individuelles.
Gardez à l'esprit lorsque vous utilisez un BoardBuilder
que le roque est désactivé par défaut !
Jouez à la variante des échecs de la Horde
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." ) ;
}
}
}
Je suis un étudiant de première année à l'université, je travaille principalement sur des projets parallèles comme ceux-ci pendant les pauses d'environ 30 minutes entre les cours. Si mes projets vous plaisent, pensez à me soutenir en m'offrant un café !