Class: PGN::Notation
- Inherits:
-
Object
- Object
- PGN::Notation
- Defined in:
- lib/pgn/notation.rb
Overview
Notation generates Standard Algebraic Notation (SAN) for a single move described in coordinate form -- an origin square, a destination square, and an optional promotion piece -- given the Position before the move is played.
Unlike Move, which parses an existing SAN string, Notation builds SAN from coordinates. This requires the kind of legality analysis the rest of the gem does not perform: attack detection, "does this move leave the mover's king in check", disambiguation among same-type pieces that can legally reach the destination, and check (+) / checkmate (#) suffix detection (the latter needing full legal-move generation for the side to move).
The board is addressed with the same 0x88 integer indices the rest of the
gem uses (see Board); an index is on-board when
(idx & 0x88).zero?.
Constant Summary collapse
- KNIGHT_OFFS =
0x88 single-step offsets for a knight (symmetric, so they double as attack deltas).
[33, 31, -31, -33, 18, 14, -14, -18].freeze
- KING_OFFS =
0x88 single-step offsets for a king (symmetric).
[-1, 1, -16, 16, -15, 15, -17, 17].freeze
- BISHOP_DIRS =
[-15, 15, -17, 17].freeze
- ROOK_DIRS =
[-1, 1, -16, 16].freeze
Class Method Summary collapse
-
.san(position, from, to, promotion = nil) ⇒ String
Build SAN for a coordinate move from a Position.
-
.san_from_fen(fen, from, to, promotion = nil) ⇒ String
Convenience: build SAN directly from a FEN string.
Instance Method Summary collapse
-
#initialize(position) ⇒ Notation
constructor
A new instance of Notation.
- #san(from, to, promotion = nil) ⇒ String
Constructor Details
#initialize(position) ⇒ Notation
Returns a new instance of Notation.
57 58 59 60 61 62 63 |
# File 'lib/pgn/notation.rb', line 57 def initialize(position) @position = position @board = position.board @player = position.player @mover = (@player == :white ? 'w' : 'b') @enemy = (@player == :white ? 'b' : 'w') end |
Class Method Details
.san(position, from, to, promotion = nil) ⇒ String
Build SAN for a coordinate move from a Position.
43 44 45 |
# File 'lib/pgn/notation.rb', line 43 def self.san(position, from, to, promotion = nil) new(position).san(from, to, promotion) end |
.san_from_fen(fen, from, to, promotion = nil) ⇒ String
Convenience: build SAN directly from a FEN string.
53 54 55 |
# File 'lib/pgn/notation.rb', line 53 def self.san_from_fen(fen, from, to, promotion = nil) san(PGN::FEN.new(fen).to_position, from, to, promotion) end |
Instance Method Details
#san(from, to, promotion = nil) ⇒ String
67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 |
# File 'lib/pgn/notation.rb', line 67 def san(from, to, promotion = nil) from_idx = @board.index_of(from) to_idx = @board.index_of(to) piece = @board.at_index(from_idx) raise ArgumentError, "no piece on #{from}" if piece.nil? promotion = promotion.upcase if promotion castling = piece.upcase == 'K' && ((from_idx & 0x0F) - (to_idx & 0x0F)).abs == 2 capture = castling ? false : capture?(piece, from_idx, to_idx) body = if castling to_idx < from_idx ? 'O-O-O' : 'O-O' elsif piece.upcase == 'P' pawn_body(from_idx, to_idx, capture, promotion) else piece_body(piece, from_idx, to_idx, capture) end body + suffix(from_idx, to_idx, piece, promotion, castling) end |