依存関係のないchess engineライブラリは、どこでも実行できるように構築されています。
Rustで書かれている??
何よりも、Tom7 によるこのビデオがこのプロジェクトのインスピレーションです。彼は本当に素晴らしいので、ぜひ彼のコンテンツを見てください。
私はチェスが大好きです。それは間違いなく私のこれまでで一番好きなゲームの 1 つです。しかし、デジタルでチェスをプレイするプログラムを (特にコンパイル言語で) 書こうとするとき、私はいつもがっかりしてきました。素晴らしいエンジンはいくつか存在しますが、あらゆるもので動作するチェス関連のプログラミング用のきちんとしたライブラリを見つけるのはほぼ不可能です。
chess-engine は私の問題の解決策です。組み込みデバイス、ターミナル、デスクトップ (GUI 付き)、およびWeb 上で実行されるchess engine必要な場合は、これがおそらく最善の策です。
この特定の AI (他のほとんどのチェス AI と同様) は、最適化のためのアルファ-ベータ プルーニングとともに Minimax アルゴリズムを使用して動作します。
では、開梱してみましょう。
Minimax アルゴリズムは基本的に、考えられるすべての手を再帰的に反復し、手がプレイされた後にすべてのボードを評価します。ボードの方が有利な場合は、その親の手をプレイすることが推奨されますが、ボードの方が有利でない場合は、特定の手をプレイしないことを選択します。
さらに、AI が現在のボードだけを見ようとすると、人間が常に最良の手を打つと想定します。その結果、コンピュータが誤動作することはほとんどありません。これにより、コンピューターはほぼ常にプレーヤーよりも客観的に優れた手を打つことができます。
依存関係がないため、wasm を使用して Web ブラウザに埋め込むのは非常に簡単です。自分でも遊んでみてください!
平均AI設定
Board
構造には、 get_best_next_move
、 get_worst_next_move
、 get_legal_moves
など、ユーザーが特定の位置から手を生成できるようにするいくつかの異なるメソッドがあります。これらは、対戦するチェス AI を作成する場合に特に便利です。
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" )
}
}
バリエーションやより高度なプレイを追加するには、 get_best_next_move
メソッドを使用する前に、より良いポジションを構築する既知のオープニングをプレイする AI を作成することを検討してください。
さらに、ユーザーはデフォルト以外の独自のカスタムBoard
オブジェクトを作成できます。これはBoardBuilder
構造を使用して行われます。 BoardBuilder
構造は、キャスリングの有効化と無効化、ピースの行と列の配置、および個々のピースの配置をサポートします。
BoardBuilder
使用するときは、キャスリングがデフォルトで無効になっていることに注意してください。
Horde Chess のバリアントをプレイする
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." ) ;
}
}
}
私は大学の新入生で、主に授業間の約 30 分の休憩時間にこのようなサイド プロジェクトに取り組んでいます。私のプロジェクトを気に入っていただけましたら、コーヒーをおごって私をサポートしていただけませんか。