Class: PGN::FEN

Inherits:
Object
  • Object
show all
Includes:
PositionFields
Defined in:
lib/pgn/fen.rb

Overview

FEN is responsible for translating between strings in FEN notation and an internal representation of the board.

Constant Summary collapse

INITIAL =

The FEN string representing the starting position in chess

'rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1'.freeze

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods included from PositionFields

#board_string, #board_string=

Constructor Details

#initialize(fen_string = nil) ⇒ FEN

Returns a new instance of FEN.

Parameters:

  • fen_string (String) (defaults to: nil)

    a string in Forsyth-Edwards Notation



110
111
112
113
114
115
116
117
118
119
# File 'lib/pgn/fen.rb', line 110

def initialize(fen_string = nil)
  return unless fen_string

  self.board_string,
    self.active,
    self.castling,
    self.en_passant,
    self.halfmove,
    self.fullmove = fen_string.split
end

Instance Attribute Details

#active'w', 't'

Returns the current player.

Returns:

  • ('w', 't')

    the current player



77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
# File 'lib/pgn/fen.rb', line 77

class FEN
  include PositionFields

  # The FEN string representing the starting position in chess
  #
  INITIAL = 'rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1'.freeze

  attr_accessor :board, :active, :halfmove, :fullmove
  # `castling` and `en_passant` have custom writers in {PositionFields}
  # (normalize nil/empty to '-'), so expose readers here and rely on the
  # module for the writers, to avoid redefining the accessors generated by
  # attr_accessor (Lint/DuplicateMethods).
  attr_reader :castling, :en_passant

  # @return [PGN::FEN] a {PGN::FEN} object representing the starting
  #   position
  #
  def self.start
    PGN::FEN.new(INITIAL)
  end

  # @return [PGN::FEN] a {PGN::FEN} object with the given attributes
  #
  def self.from_attributes(attrs)
    fen = PGN::FEN.new
    attrs.each do |key, val|
      fen.send("#{key}=", val)
    end
    fen
  end

  # @param fen_string [String] a string in Forsyth-Edwards Notation
  #
  def initialize(fen_string = nil)
    return unless fen_string

    self.board_string,
      self.active,
      self.castling,
      self.en_passant,
      self.halfmove,
      self.fullmove = fen_string.split
  end

  # @return [PGN::Position] a {PGN::Position} representing the current
  #   position
  #
  def to_position
    player, castling_rights, ep = position_fields
    PGN::Position.new(board, player, castling_rights, ep, halfmove.to_i, fullmove.to_i)
  end

  # @return [String] the EPD string for this position (the first four FEN
  #   fields, dropping the halfmove/fullmove counters)
  #
  def to_epd
    PGN::EPD.new("#{board_string} #{active} #{castling} #{en_passant}").to_s
  end

  # @return [String] the FEN string
  # @example
  #   PGN::FEN.start.to_s #=> "rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1"
  #
  def to_s
    [
      board_string,
      active,
      castling,
      en_passant,
      halfmove,
      fullmove
    ].join(' ')
  end

  def inspect
    to_s
  end
end

#boardPGN::Board

Returns a Board object for the current board state.

Returns:



77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
# File 'lib/pgn/fen.rb', line 77

class FEN
  include PositionFields

  # The FEN string representing the starting position in chess
  #
  INITIAL = 'rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1'.freeze

  attr_accessor :board, :active, :halfmove, :fullmove
  # `castling` and `en_passant` have custom writers in {PositionFields}
  # (normalize nil/empty to '-'), so expose readers here and rely on the
  # module for the writers, to avoid redefining the accessors generated by
  # attr_accessor (Lint/DuplicateMethods).
  attr_reader :castling, :en_passant

  # @return [PGN::FEN] a {PGN::FEN} object representing the starting
  #   position
  #
  def self.start
    PGN::FEN.new(INITIAL)
  end

  # @return [PGN::FEN] a {PGN::FEN} object with the given attributes
  #
  def self.from_attributes(attrs)
    fen = PGN::FEN.new
    attrs.each do |key, val|
      fen.send("#{key}=", val)
    end
    fen
  end

  # @param fen_string [String] a string in Forsyth-Edwards Notation
  #
  def initialize(fen_string = nil)
    return unless fen_string

    self.board_string,
      self.active,
      self.castling,
      self.en_passant,
      self.halfmove,
      self.fullmove = fen_string.split
  end

  # @return [PGN::Position] a {PGN::Position} representing the current
  #   position
  #
  def to_position
    player, castling_rights, ep = position_fields
    PGN::Position.new(board, player, castling_rights, ep, halfmove.to_i, fullmove.to_i)
  end

  # @return [String] the EPD string for this position (the first four FEN
  #   fields, dropping the halfmove/fullmove counters)
  #
  def to_epd
    PGN::EPD.new("#{board_string} #{active} #{castling} #{en_passant}").to_s
  end

  # @return [String] the FEN string
  # @example
  #   PGN::FEN.start.to_s #=> "rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1"
  #
  def to_s
    [
      board_string,
      active,
      castling,
      en_passant,
      halfmove,
      fullmove
    ].join(' ')
  end

  def inspect
    to_s
  end
end

#castlingObject

castling and en_passant have custom writers in PositionFields (normalize nil/empty to '-'), so expose readers here and rely on the module for the writers, to avoid redefining the accessors generated by attr_accessor (Lint/DuplicateMethods).



77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
# File 'lib/pgn/fen.rb', line 77

class FEN
  include PositionFields

  # The FEN string representing the starting position in chess
  #
  INITIAL = 'rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1'.freeze

  attr_accessor :board, :active, :halfmove, :fullmove
  # `castling` and `en_passant` have custom writers in {PositionFields}
  # (normalize nil/empty to '-'), so expose readers here and rely on the
  # module for the writers, to avoid redefining the accessors generated by
  # attr_accessor (Lint/DuplicateMethods).
  attr_reader :castling, :en_passant

  # @return [PGN::FEN] a {PGN::FEN} object representing the starting
  #   position
  #
  def self.start
    PGN::FEN.new(INITIAL)
  end

  # @return [PGN::FEN] a {PGN::FEN} object with the given attributes
  #
  def self.from_attributes(attrs)
    fen = PGN::FEN.new
    attrs.each do |key, val|
      fen.send("#{key}=", val)
    end
    fen
  end

  # @param fen_string [String] a string in Forsyth-Edwards Notation
  #
  def initialize(fen_string = nil)
    return unless fen_string

    self.board_string,
      self.active,
      self.castling,
      self.en_passant,
      self.halfmove,
      self.fullmove = fen_string.split
  end

  # @return [PGN::Position] a {PGN::Position} representing the current
  #   position
  #
  def to_position
    player, castling_rights, ep = position_fields
    PGN::Position.new(board, player, castling_rights, ep, halfmove.to_i, fullmove.to_i)
  end

  # @return [String] the EPD string for this position (the first four FEN
  #   fields, dropping the halfmove/fullmove counters)
  #
  def to_epd
    PGN::EPD.new("#{board_string} #{active} #{castling} #{en_passant}").to_s
  end

  # @return [String] the FEN string
  # @example
  #   PGN::FEN.start.to_s #=> "rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1"
  #
  def to_s
    [
      board_string,
      active,
      castling,
      en_passant,
      halfmove,
      fullmove
    ].join(' ')
  end

  def inspect
    to_s
  end
end

#en_passantObject

castling and en_passant have custom writers in PositionFields (normalize nil/empty to '-'), so expose readers here and rely on the module for the writers, to avoid redefining the accessors generated by attr_accessor (Lint/DuplicateMethods).



77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
# File 'lib/pgn/fen.rb', line 77

class FEN
  include PositionFields

  # The FEN string representing the starting position in chess
  #
  INITIAL = 'rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1'.freeze

  attr_accessor :board, :active, :halfmove, :fullmove
  # `castling` and `en_passant` have custom writers in {PositionFields}
  # (normalize nil/empty to '-'), so expose readers here and rely on the
  # module for the writers, to avoid redefining the accessors generated by
  # attr_accessor (Lint/DuplicateMethods).
  attr_reader :castling, :en_passant

  # @return [PGN::FEN] a {PGN::FEN} object representing the starting
  #   position
  #
  def self.start
    PGN::FEN.new(INITIAL)
  end

  # @return [PGN::FEN] a {PGN::FEN} object with the given attributes
  #
  def self.from_attributes(attrs)
    fen = PGN::FEN.new
    attrs.each do |key, val|
      fen.send("#{key}=", val)
    end
    fen
  end

  # @param fen_string [String] a string in Forsyth-Edwards Notation
  #
  def initialize(fen_string = nil)
    return unless fen_string

    self.board_string,
      self.active,
      self.castling,
      self.en_passant,
      self.halfmove,
      self.fullmove = fen_string.split
  end

  # @return [PGN::Position] a {PGN::Position} representing the current
  #   position
  #
  def to_position
    player, castling_rights, ep = position_fields
    PGN::Position.new(board, player, castling_rights, ep, halfmove.to_i, fullmove.to_i)
  end

  # @return [String] the EPD string for this position (the first four FEN
  #   fields, dropping the halfmove/fullmove counters)
  #
  def to_epd
    PGN::EPD.new("#{board_string} #{active} #{castling} #{en_passant}").to_s
  end

  # @return [String] the FEN string
  # @example
  #   PGN::FEN.start.to_s #=> "rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1"
  #
  def to_s
    [
      board_string,
      active,
      castling,
      en_passant,
      halfmove,
      fullmove
    ].join(' ')
  end

  def inspect
    to_s
  end
end

#fullmoveString

Note:

The number of full moves. This is incremented after black plays.

Returns the fullmove counter.

Returns:

  • (String)

    the fullmove counter



77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
# File 'lib/pgn/fen.rb', line 77

class FEN
  include PositionFields

  # The FEN string representing the starting position in chess
  #
  INITIAL = 'rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1'.freeze

  attr_accessor :board, :active, :halfmove, :fullmove
  # `castling` and `en_passant` have custom writers in {PositionFields}
  # (normalize nil/empty to '-'), so expose readers here and rely on the
  # module for the writers, to avoid redefining the accessors generated by
  # attr_accessor (Lint/DuplicateMethods).
  attr_reader :castling, :en_passant

  # @return [PGN::FEN] a {PGN::FEN} object representing the starting
  #   position
  #
  def self.start
    PGN::FEN.new(INITIAL)
  end

  # @return [PGN::FEN] a {PGN::FEN} object with the given attributes
  #
  def self.from_attributes(attrs)
    fen = PGN::FEN.new
    attrs.each do |key, val|
      fen.send("#{key}=", val)
    end
    fen
  end

  # @param fen_string [String] a string in Forsyth-Edwards Notation
  #
  def initialize(fen_string = nil)
    return unless fen_string

    self.board_string,
      self.active,
      self.castling,
      self.en_passant,
      self.halfmove,
      self.fullmove = fen_string.split
  end

  # @return [PGN::Position] a {PGN::Position} representing the current
  #   position
  #
  def to_position
    player, castling_rights, ep = position_fields
    PGN::Position.new(board, player, castling_rights, ep, halfmove.to_i, fullmove.to_i)
  end

  # @return [String] the EPD string for this position (the first four FEN
  #   fields, dropping the halfmove/fullmove counters)
  #
  def to_epd
    PGN::EPD.new("#{board_string} #{active} #{castling} #{en_passant}").to_s
  end

  # @return [String] the FEN string
  # @example
  #   PGN::FEN.start.to_s #=> "rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1"
  #
  def to_s
    [
      board_string,
      active,
      castling,
      en_passant,
      halfmove,
      fullmove
    ].join(' ')
  end

  def inspect
    to_s
  end
end

#halfmoveString

Note:

This is the number of halfmoves since the last pawn advance or capture

Returns the halfmove clock.

Returns:

  • (String)

    the halfmove clock



77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
# File 'lib/pgn/fen.rb', line 77

class FEN
  include PositionFields

  # The FEN string representing the starting position in chess
  #
  INITIAL = 'rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1'.freeze

  attr_accessor :board, :active, :halfmove, :fullmove
  # `castling` and `en_passant` have custom writers in {PositionFields}
  # (normalize nil/empty to '-'), so expose readers here and rely on the
  # module for the writers, to avoid redefining the accessors generated by
  # attr_accessor (Lint/DuplicateMethods).
  attr_reader :castling, :en_passant

  # @return [PGN::FEN] a {PGN::FEN} object representing the starting
  #   position
  #
  def self.start
    PGN::FEN.new(INITIAL)
  end

  # @return [PGN::FEN] a {PGN::FEN} object with the given attributes
  #
  def self.from_attributes(attrs)
    fen = PGN::FEN.new
    attrs.each do |key, val|
      fen.send("#{key}=", val)
    end
    fen
  end

  # @param fen_string [String] a string in Forsyth-Edwards Notation
  #
  def initialize(fen_string = nil)
    return unless fen_string

    self.board_string,
      self.active,
      self.castling,
      self.en_passant,
      self.halfmove,
      self.fullmove = fen_string.split
  end

  # @return [PGN::Position] a {PGN::Position} representing the current
  #   position
  #
  def to_position
    player, castling_rights, ep = position_fields
    PGN::Position.new(board, player, castling_rights, ep, halfmove.to_i, fullmove.to_i)
  end

  # @return [String] the EPD string for this position (the first four FEN
  #   fields, dropping the halfmove/fullmove counters)
  #
  def to_epd
    PGN::EPD.new("#{board_string} #{active} #{castling} #{en_passant}").to_s
  end

  # @return [String] the FEN string
  # @example
  #   PGN::FEN.start.to_s #=> "rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1"
  #
  def to_s
    [
      board_string,
      active,
      castling,
      en_passant,
      halfmove,
      fullmove
    ].join(' ')
  end

  def inspect
    to_s
  end
end

Class Method Details

.from_attributes(attrs) ⇒ PGN::FEN

Returns a PGN::FEN object with the given attributes.

Returns:



100
101
102
103
104
105
106
# File 'lib/pgn/fen.rb', line 100

def self.from_attributes(attrs)
  fen = PGN::FEN.new
  attrs.each do |key, val|
    fen.send("#{key}=", val)
  end
  fen
end

.startPGN::FEN

Returns a PGN::FEN object representing the starting position.

Returns:



94
95
96
# File 'lib/pgn/fen.rb', line 94

def self.start
  PGN::FEN.new(INITIAL)
end

Instance Method Details

#inspectObject



151
152
153
# File 'lib/pgn/fen.rb', line 151

def inspect
  to_s
end

#to_epdString

Returns the EPD string for this position (the first four FEN fields, dropping the halfmove/fullmove counters).

Returns:

  • (String)

    the EPD string for this position (the first four FEN fields, dropping the halfmove/fullmove counters)



132
133
134
# File 'lib/pgn/fen.rb', line 132

def to_epd
  PGN::EPD.new("#{board_string} #{active} #{castling} #{en_passant}").to_s
end

#to_positionPGN::Position

Returns a Position representing the current position.

Returns:



124
125
126
127
# File 'lib/pgn/fen.rb', line 124

def to_position
  player, castling_rights, ep = position_fields
  PGN::Position.new(board, player, castling_rights, ep, halfmove.to_i, fullmove.to_i)
end

#to_sString

Returns the FEN string.

Examples:

PGN::FEN.start.to_s #=> "rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1"

Returns:

  • (String)

    the FEN string



140
141
142
143
144
145
146
147
148
149
# File 'lib/pgn/fen.rb', line 140

def to_s
  [
    board_string,
    active,
    castling,
    en_passant,
    halfmove,
    fullmove
  ].join(' ')
end