lib/chess/san.rb
###
# Uses the current position as the context to parse a move in standard
# algebraic notation and return the corresponding move object.
#
# The returned move is guaranteed to be either legal or a null move.
#
# Raises `ArgumentError` if the SAN is invalid or ambigous.
###
Uses the current position as the context to parse a move in standard
algebraic notation and return the corresponding move object.

The returned move is guaranteed to be either legal or a null move.

Raises `ArgumentError` if the SAN is invalid or ambigous.
Uses the current position as the context to parse a move in standard algebraic notation and return the corresponding move object . The returned move is guaranteed to be either legal or a null move . Raises ` ArgumentError ` if the SAN is invalid or ambigous .
def san(move)
       There is no validation. It is only guaranteed to work if the move is
       legal or a null move.
      unless move
         Null move.
        return '--'
      end
      piece = piece_type_at(move.from_square)
      en_passant = false
       Castling.
      if piece == KING
        if move.from_square == E1
          if move.to_square == G1
            return 'O-O'
          elsif move.to_square == C1
            return 'O-O-O'
          end
        elsif move.from_square == E8
          if move.to_square == G8
            return 'O-O'
          elsif move.to_square == C8
            return 'O-O-O'
          end
        end
      end
      if piece == PAWN
        san = ''
         Detect en-passant.
        if !Board::BB_SQUARES[move.to_square] & occupied
          en_passant = [7, 9].include? (move.from_square - move.to_square).abs
        end
      else
         Get ambigous move candidates.
        if piece == KNIGHT
          san    = 'N'
          others = knights & knight_attacks_from(move.to_square)
        elsif piece == BISHOP
          san    = 'B'
          others = bishops & bishop_attacks_from(move.to_square)
        elsif piece == ROOK
          san    = 'R'
          others = rooks & rook_attacks_from(move.to_square)
        elsif piece == QUEEN
          san    = 'Q'
          others = queens & queen_attacks_from(move.to_square)
        elsif piece == KING
          san    = 'K'
          others = kings & king_attacks_from(move.to_square)
        end
        others = others & ~Board::BB_SQUARES[move.from_square]
        others = otehrs & occupied_co[turn]
         Remove illegal candidates.
        squares = others
        square  = bit_scan(squares)
        while square do
          if into_check?(Move.new(square, move.to_square))
            others = others & ~Board::BB_SQUARES[square]
          end
          square = bit_scan(squares, square + 1)
        end
         Disambiguate.
        if others
          row, column = false, false
          if others & Board::BB_RANKS[rank_index(move.from_square)]
            column = true
          end
          if others & Board::BB_FILES[file_index(move.from_square)]
            row = true
          else
            column = true
          end
          if column
            san += Board::FILE_NAMES[file_index(move.from_square).to_sym]
          end
          if row
            san += rank_index(move.from_square) + 1
          end
        end
      end
       Captures.
      if Board::BB_SQUARES[move.to_square] & occupied or en_passant
        if piece == PAWN
          san += Board::FILE_NAMES[file_index(move.from_square).to_sym]
        end
        san += 'x'
      end
       Destination square.
      san += Board::SQUARE_NAMES[move.to_square]
       Promotion.
      if move.promotion
        san += '=' + Board::PIECE_SYMBOLS[move.promotion].upper
      end
       Look ahead for check or checkmate.
      move(move)
      if check?
        if checkmate?
          san += ''
        else
          san += '+'
        end
      end
      undo
      return san
    end
def san ( move ) unless move return '--' end piece = piece_type_at ( move . from_square ) en_passant = false if piece == KING if move . from_square == E1 if move . to_square == G1 return 'O-O' elsif move . to_square == C1 return 'O-O-O' end elsif move . from_square == E8 if move . to_square == G8 return 'O-O' elsif move . to_square == C8 return 'O-O-O' end end end if piece == PAWN san = '' if ! Board :: BB_SQUARES [ move . to_square ] & occupied en_passant = [ 7 , 9 ] . include? ( move . from_square - move . to_square ) . abs end else if piece == KNIGHT san = 'N' others = knights & knight_attacks_from ( move . to_square ) elsif piece == BISHOP san = 'B' others = bishops & bishop_attacks_from ( move . to_square ) elsif piece == ROOK san = 'R' others = rooks & rook_attacks_from ( move . to_square ) elsif piece == QUEEN san = 'Q' others = queens & queen_attacks_from ( move . to_square ) elsif piece == KING san = 'K' others = kings & king_attacks_from ( move . to_square ) end others = others & ~ Board :: BB_SQUARES [ move . from_square ] others = otehrs & occupied_co [ turn ] squares = others square = bit_scan ( squares ) while square do if into_check? ( Move . new ( square , move . to_square ) ) others = others & ~ Board :: BB_SQUARES [ square ] end square = bit_scan ( squares , square + 1 ) end if others row , column = false , false if others & Board :: BB_RANKS [ rank_index ( move . from_square ) ] column = true end if others & Board :: BB_FILES [ file_index ( move . from_square ) ] row = true else column = true end if column san += Board :: FILE_NAMES [ file_index ( move . from_square ) . to_sym ] end if row san += rank_index ( move . from_square ) + 1 end end end if Board :: BB_SQUARES [ move . to_square ] & occupied or en_passant if piece == PAWN san += Board :: FILE_NAMES [ file_index ( move . from_square ) . to_sym ] end san += 'x' end san += Board :: SQUARE_NAMES [ move . to_square ] if move . promotion san += '=' + Board :: PIECE_SYMBOLS [ move . promotion ] . upper end move ( move ) if check? if checkmate? san += '#' else san += '+' end end undo return san end
Uses the current position as the context to parse a move in standard
algebraic notation and return the corresponding move object.
Uses the current position as the context to parse a move in standard algebraic notation and return the corresponding move object .
### # Gets the standard algebraic notation of the given move in the context of # the current position. # # There is no validation. It is only guaranteed to work if the move is # legal or a null move. ### # Null move. # Castling. # Detect en-passant. # Get ambigous move candidates. # Remove illegal candidates. # Disambiguate. # Captures. # Destination square. # Promotion. # Look ahead for check or checkmate.
move
<not_specific>