一个无依赖的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 分钟的休息时间里做这些副业项目。如果您喜欢我的项目,请考虑给我买杯咖啡来支持我!