一個無依賴的chess engine庫,可以在任何地方運行。
用 Rust 寫的?
最重要的是,Tom7 的這段影片是我這個專案的靈感來源。他非常出色,我懇請您觀看他的內容。
我非常喜歡西洋棋。這絕對是我最喜歡的遊戲之一。然而,當我嘗試編寫數位下棋程式(特別是使用編譯語言)時,我總是感到失望。儘管存在一些令人驚嘆的引擎,但幾乎不可能找到一個可以在所有東西上運行的與國際象棋相關的程式設計的簡潔庫。
國際象棋引擎是我的問題的解決方案。如果您想要一個在嵌入式設備、終端、桌面(帶有 GUI)和網路上運行的chess engine ,這可能是您最好的選擇。
這個特殊的人工智慧(以及大多數其他國際象棋人工智慧)使用 Minimax 演算法以及 Alpha-Beta 剪枝進行最佳化。
現在,讓我們來解開它。
Minimax 演算法本質上是遞歸地迭代所有可能的移動,並在移動完成後評估所有棋盤。如果棋盤更有利,它將鼓勵下其父棋步,但如果棋盤不太有利,那麼它將選擇不棋子下棋。
此外,當人工智慧試圖只看當前棋盤時,它會假設人類總是以最佳動作做出反應。結果,計算機幾乎從不出錯。這使得電腦幾乎總是能夠客觀地比玩家下更好的棋步。
由於它具有零依賴性,因此使用 wasm 嵌入到 Web 瀏覽器中非常簡單。自己嘗試玩一下吧!
平均人工智慧設定
Board
結構有幾種不同的方法,允許使用者從給定位置產生移動,包括get_best_next_move
、 get_worst_next_move
和get_legal_moves
。這些對於編寫要對戰的國際象棋人工智慧來說特別方便。
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" )
}
}
要添加一些變化或更高級的玩法,請考慮編寫一個 AI 來玩已知的空缺,從而在使用get_best_next_move
方法之前構建更好的位置!
此外,使用者可以建立自己的自訂Board
對象,而不是預設的 Board 對象。這是使用BoardBuilder
結構完成的。 BoardBuilder
結構支援啟用和停用易位、放置棋子的行和列以及放置單一棋子。
請記住,在使用BoardBuilder
時,預設會停用易位!
玩部落西洋棋變體
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 分鐘的休息時間裡做這些副業項目。如果您喜歡我的項目,請考慮為我買杯咖啡來支持我!