#pgn #chess #position #filter #collection #piece #save

pgn_filter

用于搜索/过滤棋类游戏的pgn文件

1个稳定版本

1.1.0 2023年11月10日
1.0.0 2020年11月20日

98游戏 中排名

31 每月下载次数

MIT 协议

88KB
2K SLoC

pgn_filter

用于搜索/过滤棋类游戏的pgn文件。

功能

  • 读取和保存PGN文件集合
  • 过滤包含特定棋子组合的位置的游戏
  • 过滤后保存PGN游戏集合或单个位置。
  • PGN词法分析器遵循https://www.chessclub.com/help/PGN-spec规范
    • 注意,词法分析器识别但忽略注释和NAG,因此它们不会出现在任何重新保存的游戏中

位置定义

游戏存储在类型为pgn_filter::Games的集合中,可以使用搜索方法进行过滤。搜索方法接受一个BoardFilter定义,该定义指定了每种类型的棋子允许的数量,并返回一个只包含匹配定义的游戏的新集合。

例如,以下过滤器匹配5-4车兵结束,即有5个白兵、4个黑兵和一边的车的位置

let filter = pgn_filter::Board::must_have()
    .exactly(1, "R")
    .exactly(1, "r")
    .exactly(5, "P")
    .exactly(4, "p");

请注意,该过滤器是通过调用"must_have"获得的基过滤器构建的。此基过滤器识别每种颜色恰好有一个国王且没有棋子或兵的位置。您通过为每个所需的棋子添加一个关系来构建过滤器。如果您为给定棋子添加第二个过滤器,第二个过滤器将替换第一个。

可用的过滤器有

  • "exactly(n, piece)"
  • "at_least(n, piece)"
  • "at_most(n, piece)"

示例:提取所有5-4车兵结束

以下示例显示如何构建一个过滤器以识别5-4车结束,并将选定的游戏保存到文件中。

// Create a database and add some games
let mut db = pgn_filter::Games::new();
db.add_games("examples/twic1356.pgn").unwrap();

// Display some information
println!("Database has {} game(s)", db.iter().count());

// Create a position definition for 5-4 rook endings
let filter = pgn_filter::Board::must_have()
    .exactly(1, "R")
    .exactly(1, "r")
    .exactly(5, "P")
    .exactly(4, "p");

// Extract those games which at some point reach 
let selected = db.search(&filter);
selected.to_file("rook-endings.pgn").unwrap();

// Report and save result
println!("Selected {} out of {} games", selected.iter().count(), db.iter().count());

示例:逐步研究游戏

Game#play_game方法接受一个闭包/函数,该闭包/函数在每半个回合后接收当前棋盘和下一个走法。以下示例打印出棋盘位置和信息以创建游戏跟踪

let fischer = pgn_filter::Games::from_file("examples/fischer.pgn").unwrap();

println!("File has {} game(s)", fischer.games.len());

if fischer.games.len() > 0 {
    let game = &fischer.games[0];

    game.play_game(|board, next_move| {
        println!("{}", board.to_string());
        match next_move {
            Some(mv) => {
                // next move in the game
                println!(
                    "Move {}: {}{}",
                    board.fullmove_number,
                    if board.white_to_move { "" } else { "..." },
                    mv
                );
                println!("");
            }
            None => {
                // game over, so display the result
                println!("Result: {}", game.header.get("Result").unwrap());
            }
        };
    });
}

示例输出

File has 1 game(s)
rnbqkbnr
pppppppp
........
........
........
........
PPPPPPPP
RNBQKBNR

Move 1: e4

rnbqkbnr
pppppppp
........
........
....P...
........
PPPP.PPP
RNBQKBNR

Move 1: ...e5

rnbqkbnr
pppp.ppp
........
....p...
....P...
........
PPPP.PPP
RNBQKBNR

Move 2: Nf3

rnbqkbnr
pppp.ppp
........
....p...
....P...
.....N..
PPPP.PPP
RNBQKB.R

Move 2: ...Nc6

r.bqkbnr
pppp.ppp
..n.....
....p...
....P...
.....N..
PPPP.PPP
RNBQKB.R

Move 3: Bb5

MIT许可证

版权所有 (c) 2020-23, Peter Lane [email protected]

以下条件准许任何人免费获得本软件及其相关文档文件("软件")的副本,并使用软件,包括但不限于使用、复制、修改、合并、发布、分发、再许可和/或销售软件副本,并允许向软件提供的人这样做,前提是

上述版权声明和本许可声明应包含在软件的所有副本或实质性部分中。

软件按“现状”提供,不提供任何形式的保证,无论是明示的还是暗示的,包括但不限于适销性、适用于特定目的和非侵权性。在任何情况下,作者或版权所有者不对任何索赔、损害或其他责任负责,无论该责任源于合同、侵权或其他,与软件或软件的使用或其他方式有关。

依赖项

~2.6–3.5MB
~57K SLoC