Class: Chess::Pgn

Inherits:
Object
  • Object
show all
Defined in:
lib/chess/pgn.rb

Overview

Rappresents a game in PGN (Portable Game Notation) format.

Constant Summary collapse

TAGS =

Array that include PGN standard tags.

%w[event site date round white black result].freeze

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(filename = nil, check_moves: false) ⇒ Pgn

Returns a new instance of Pgn.

Parameters:

  • filename (String) (defaults to: nil)

    The path of the PGN file.

  • check_moves (Boolean) (defaults to: false)

    If true check if the moves are legal.

Raises:



40
41
42
43
# File 'lib/chess/pgn.rb', line 40

def initialize(filename = nil, check_moves: false)
  self.load(filename, check_moves: check_moves) if filename
  @date = '??'
end

Instance Attribute Details

#blackString

The player of the black pieces, same format as White.

Returns:

  • (String)


26
27
28
# File 'lib/chess/pgn.rb', line 26

def black
  @black
end

#dateString

The starting date of the game, in YYYY.MM.DD form. ?? is used for unknown values.

Returns:

  • (String)


17
18
19
# File 'lib/chess/pgn.rb', line 17

def date
  @date
end

#eventString

The name of the tournament or match event.

Returns:

  • (String)


9
10
11
# File 'lib/chess/pgn.rb', line 9

def event
  @event
end

#movesArray<String>

The array with all moves done in short algebraic chess notation.

Returns:

  • (Array<String>)


34
35
36
# File 'lib/chess/pgn.rb', line 34

def moves
  @moves
end

#resultString

The result of the game. This can only have four possible values: 1-0 (White won), 0-1 (Black won), 1/2-1/2 (Draw), or * (other, e.g., the game is ongoing).

Returns:

  • (String)


31
32
33
# File 'lib/chess/pgn.rb', line 31

def result
  @result
end

#roundString

The playing round ordinal of the game within the event.

Returns:

  • (String)


20
21
22
# File 'lib/chess/pgn.rb', line 20

def round
  @round
end

#siteString

The location of the event. This is in City, Region COUNTRY format, where COUNTRY is the three-letter International Olympic Committee code for the country.

Returns:

  • (String)


14
15
16
# File 'lib/chess/pgn.rb', line 14

def site
  @site
end

#whiteString

The player of the white pieces, in Lastname, Firstname format.

Returns:

  • (String)


23
24
25
# File 'lib/chess/pgn.rb', line 23

def white
  @white
end

Instance Method Details

#load(filename, check_moves: false) ⇒ Pgn

Load a PGN from file.

Parameters:

  • filename (String)

    The path of the PGN file.

  • check_moves (Boolean) (defaults to: false)

    If true check if the moves are legal.

Returns:

  • (Pgn)

    Returns ‘self`.

Raises:



51
52
53
54
# File 'lib/chess/pgn.rb', line 51

def load(filename, check_moves: false)
  str = File.open(filename, 'r').read
  load_from_string(str, check_moves: check_moves)
end

#load_from_string(str, check_moves: false) ⇒ Pgn

Load a PGN from string.

Parameters:

  • str (String)

    The PGN string to load.

  • check_moves (Boolean) (defaults to: false)

    If true check if the moves are legal.

Returns:

  • (Pgn)

    Returns ‘self`.

Raises:



62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
# File 'lib/chess/pgn.rb', line 62

def load_from_string(str, check_moves: false)
  str.gsub!(/\{.*?\}/, '') # remove comments
  TAGS.each do |t|
    instance_variable_set("@#{t}", str.match(/^\[#{t.capitalize} ".*"\]\s?$/).to_s.strip[t.size + 3..-3])
  end
  @result = '1/2-1/2' if @result == '1/2'
  game_index = str.index(/^1\./)
  raise Chess::InvalidPgnFormatError.new if game_index.nil?

  game = str[game_index..-1].strip
  @moves = game.tr("\n", ' ').split(/\d+\./).collect(&:strip)[1..-1].map(&:split).flatten
  @moves.delete_at(@moves.size - 1) if @moves.last.match?(/(0-1)|(1-0)|(1\/2)|(1\/2-1\/2)|(\*)/)
  @moves.each do |m|
    raise Chess::InvalidPgnFormatError.new if m !~ MOVE_REGEXP && m !~ SHORT_CASTLING_REGEXP && m !~ LONG_CASTLING_REGEXP
  end
  Chess::Game.new(@moves) if check_moves
  return self
end

#to_sObject

PGN to string.



82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
# File 'lib/chess/pgn.rb', line 82

def to_s
  s = ''
  TAGS.each do |t|
    tag = instance_variable_defined?("@#{t}") ? instance_variable_get("@#{t}") : ''
    s << "[#{t.capitalize} \"#{tag}\"]\n"
  end
  s << "\n"
  m = ''
  @moves.each_with_index do |move, i|
    m << "#{i / 2 + 1}. " if i.even?
    m << "#{move} "
  end
  m << @result unless @result.nil?
  s << m.gsub(/(.{1,78})(?: +|$)\n?|(.{78})/, "\\1\\2\n")
end

#write(filename) ⇒ Object

Write PGN to file.

Parameters:

  • filename (String)

    The path of the PGN file.



100
101
102
# File 'lib/chess/pgn.rb', line 100

def write(filename)
  File.open(filename, 'w') { |f| f.write(self.to_s) }
end