1 个稳定版本

使用旧的 Rust 2015

1.0.0 2022年11月27日

游戏开发 中排名第 1429

每月下载量 34
tanton_engine 使用

MIT 许可证

410KB
8K SLoC

坦顿

坦顿是一个棋类库,包含棋引擎 Stockfish 的构建块,完全用 Rust 重新编写。

它是现在不再维护的项目 Pleco 的一个分支。

Tanton crate

此项目分为两个包,tanton(你当前所在的库),包含库功能,以及 tanton_engine,包含兼容 UCI(通用棋类接口)的引擎和 AI。

坦顿的整体目标是重新创建 Stockfish 引擎,以进行比较和教育。因此,这里使用的绝大多数算法都是 Stockfish 的直接移植,绝大多数代码的版权归 Stockfish 的维护者和作者所有。

有关使用 tanton 库实现的棋引擎,请参阅 tanton_engine

功能

tanton 实现的一些功能

  • 棋子位置的位图表示
  • 支持并发访问棋盘状态,以便由并行搜索器使用
  • 完整的走法生成能力,包括生成伪合法走法
  • 静态计算的查找表(包括魔法位图)
  • Zobrist 哈希
  • 转换表:用于存储棋盘信息的闪电般快速的查找表
  • 预实现的搜索器,其中一些使用 rayon.rs 以实现易于并行的功能

使用

要在自己的 Rust 项目中使用坦顿,Tanton.rs 可在 crates.io 上作为库使用。坦顿在 rust 的所有三个发行版(nightlybetastable)上运行。

基本用法

设置棋盘位置非常简单。

use tanton::{Board,Player,PieceType};

let board = Board::start_pos();
assert_eq!(board.count_piece(Player::White,PieceType::P), 8);
assert_eq!(&board.fen(),"rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1");

从位置创建棋盘

可以使用有效的 FEN(Forsyth-Edwards Notation)字符串创建一个 Board,其中包含任何有效的棋盘位置。有关 FEN 字符串及其格式的更多信息,请参阅 维基百科文章

let board: Board = Board::from_fen("rnbqkbnr/pp1ppppp/8/2p5/4P3/8/PPPP1PPP/RNBQKBNR w KQkq c6 0 2").unwrap();

应用和生成走法

移动由一个BitMove结构表示。它们必须由一个Board对象直接生成,才能被认为是有效的移动。使用Board::generate_moves()将生成当前玩家当前位置的所有合法的BitMove

use tanton::{Board,BitMove};

let mut board = Board::start_pos(); // create a board of the starting position
let moves = board.generate_moves(); // generate all possible legal moves
board.apply_move(moves[0]);
assert_eq!(board.moves_played(), 1);

我们可以要求棋盘对象从字符串中应用一个移动。这个字符串必须遵循标准UCI移动的格式,格式为[src_sq][dst_sq][promo]。例如,将一个棋子从A1移动到B3,UCI字符串为"a1b3",而提升兵则可能看起来像"e7e81"。如果提供给棋盘的UCI移动格式不正确或非法,则返回false。

let mut board = Board::start_pos(); // create a board of the starting position
let success = board.apply_uci_move("e7e8q"); // apply a move where piece on e7 -> eq, promotes to queen
assert!(!success); // Wrong, not a valid move for the starting position

撤销移动

我们可以使用一个简单的Board::undo_move()回到之前的棋盘状态。

let mut board = Board::start_pos();
board.apply_uci_move("e2e4"); // A very good starting move, might I say
assert_eq!(board.moves_played(),1);
board.undo_move();
assert_eq!(board.moves_played(),0);

依赖项

~2MB
~35K SLoC