= chess-data
Install from {RubyGems}[https://rubygems.org/gems/chess-data/]:
> gem install chess-data
source:: {chess-data.zip}[http://peterlane.info/downloads/chess-data.zip]
== Description
For searching/filtering datasets of chess games.
Features
* Read and save collections of PGN files
* Filter games looking for games containing positions with certain combinations
of pieces
* Save collections of PGN games or individual positions after filtering.
* PGN lexer follows specification in https://www.chessclub.com/help/PGN-spec
* note that the lexer recognises but ignores comments and NAGs, so they will
not appear in any resaved games
== Position Definitions
Games are stored in an instance of +ChessData+::+Database+, and can be filtered using
the +search+ method. The search method takes a block defining the numbers of pieces of
each type and returns a new database containing just those games which match the
definition. For example, the following filters for 5-4 rook endings:
rook_endings_database = database.search do
exactly 1, "R", "r"
exactly 5, "P"
exactly 4, "p"
end
Filters include:
* 'exactly n, *pieces'
* 'at_least n, *pieces'
* 'at_most n, *pieces'
== Example: Extracting all 5-4 R+P endings
# Read database of games and query
require 'chess-data'
# create a database
database = ChessData::Database.new
# read in pgn files provided on command line and add them to the database
ARGV.each do |file|
puts "Reading from #{file}"
database.add_games_from file
end
# extract those games which at some point reach given position definition
selected = database.search do
exactly 1, "R", "r"
exactly 5, "P"
exactly 4, "p"
end
# report and save result
puts "Found #{selected.size} games"
selected.to_file "selected.pgn"
puts "Selected #{selected.size} out of #{database.size}"
== Example: Study a game move-by-move
The ChessData::Game#play_game method takes a block, which is passed the current
board and next move after each half move. The following example prints out the
board position and information to create a trace of the game:
$game.play_game do |board, next_move|
puts board.to_s
puts
puts "Move #{board.fullmove_number}: #{if board.to_move == "w" then "" else "... " end}#{next_move}"
end
Sample output:
Move 32: Rxd7+
........
..kR...p
....pb.Q
........
..P..Pq.
.Pn.....
......P.
......BK
Move 32: ... Kxd7
........
...k...p
....pb.Q
........
..P..Pq.
.Pn.....
......P.
......BK
Move 33: Qxf6
........
...k...p
....pQ..
........
..P..Pq.
.Pn.....
......P.
......BK
Move 33: ... 1/2-1/2