chess_data

Install from RubyGems:

> gem install chess_data
source

notabug.org/peterlane/chess_data/

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 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