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 parse_san(san)
      if san == '--'
        return Move.new
      end
      move = nil
      if ['O-O', 'O-O+', 'O-O#'].include? san
        if turn == WHITE
          move = Move.new(E1, G1)
        else
          move = Move.new(E8, G8)
        end
        if kings & occupied_co[turn] & Board::BB_SQUARES[move.from_square] and legal?(move)
          return move
        else
          raise ArgumentError, "illegal san: #{san}"
        end
      elsif ['O-O-O', 'O-O-O+', 'O-O-O#'].include? san
        if turn == WHITE
          move = Move.new(E1, C1)
        else
          move = Move.new(E8, C8)
        end
        if kings & occupied_co[turn] & Board::BB_SQUARES[move.from_square] and legal?(move)
          return move
        else
          raise ArgumentError, "illegal san: #{san}"
        end
      end
      match = Board::SAN_REGEX.match(san)
      unless match
        raise ArgumentError, "invalid san: #{san}"
      end
      to_square = Board::SQUARE_NAMES.index(match[4].to_sym)
      if !match[5]
        promotion = nil
      else
        promotion = Board::PIECE_SYMBOLS.index(match[5][1].downcase().to_sym)
      end
      if match[1] == 'N'
        moves = generate_pseudo_legal_moves(castling: false, pawns: false, knights: true,
                                            bishops: false, rooks: false, queens: false, king: false)
      elsif match[1] == 'B'
        moves = generate_pseudo_legal_moves(castling: false, pawns: false, knights: false,
                                            bishops: true, rooks: false, queens: false, king: false)
      elsif match[1] == 'K'
        moves = generate_pseudo_legal_moves(castling: false, pawns: false, knights: false,
                                            bishops: false, rooks: false, queens: false, king: true)
      elsif match[1] == 'R'
        moves = generate_pseudo_legal_moves(castling: false, pawns: false, knights: false,
                                            bishops: false, rooks: true, queens: false, king: false)
      elsif match[1] == 'Q'
        moves = generate_pseudo_legal_moves(castling: false, pawns: false, knights: false,
                                            bishops: false, rooks: false, queens: true, king: false)
      else
        moves = generate_pseudo_legal_moves(castling: false, pawns: true, knights: false,
                                            bishops: false, rooks: false, queens: false, king: false)
      end
      from_mask = Board::BB_ALL
      if match[2]
        from_mask = from_mask & Board::BB_FILES[Board::FILE_NAMES.index(match[2].to_sym)]
      end
      if match[3]
        from_mask = from_mask & Board::BB_RANKS[match[3].to_i - 1]
      end
      matched_move = nil
      moves.each do |move|
        if move.to_square != to_square
          next
        end
        if move.promotion != promotion
          next
        end
        if Board::BB_SQUARES[move.from_square] & from_mask == 0
          next
        end
        if into_check?(move)
          next
        end
        if matched_move
          raise ArgumentError, "ambiguous san: #{san}"
        end
        matched_move = move
      end
      if !matched_move
        raise ArgumentError, "illegal san: #{san}"
      end
      return matched_move
    end
def parse_san ( san ) if san == '--' return Move . new end move = nil if [ 'O-O' , 'O-O+' , 'O-O#' ] . include? san if turn == WHITE move = Move . new ( E1 , G1 ) else move = Move . new ( E8 , G8 ) end if kings & occupied_co [ turn ] & Board :: BB_SQUARES [ move . from_square ] and legal? ( move ) return move else raise ArgumentError , "illegal san: #{san}" end elsif [ 'O-O-O' , 'O-O-O+' , 'O-O-O#' ] . include? san if turn == WHITE move = Move . new ( E1 , C1 ) else move = Move . new ( E8 , C8 ) end if kings & occupied_co [ turn ] & Board :: BB_SQUARES [ move . from_square ] and legal? ( move ) return move else raise ArgumentError , "illegal san: #{san}" end end match = Board :: SAN_REGEX . match ( san ) unless match raise ArgumentError , "invalid san: #{san}" end to_square = Board :: SQUARE_NAMES . index ( match [ 4 ] . to_sym ) if ! match [ 5 ] promotion = nil else promotion = Board :: PIECE_SYMBOLS . index ( match [ 5 ] [ 1 ] . downcase ( ) . to_sym ) end if match [ 1 ] == 'N' moves = generate_pseudo_legal_moves ( castling : false , pawns : false , knights : true , bishops : false , rooks : false , queens : false , king : false ) elsif match [ 1 ] == 'B' moves = generate_pseudo_legal_moves ( castling : false , pawns : false , knights : false , bishops : true , rooks : false , queens : false , king : false ) elsif match [ 1 ] == 'K' moves = generate_pseudo_legal_moves ( castling : false , pawns : false , knights : false , bishops : false , rooks : false , queens : false , king : true ) elsif match [ 1 ] == 'R' moves = generate_pseudo_legal_moves ( castling : false , pawns : false , knights : false , bishops : false , rooks : true , queens : false , king : false ) elsif match [ 1 ] == 'Q' moves = generate_pseudo_legal_moves ( castling : false , pawns : false , knights : false , bishops : false , rooks : false , queens : true , king : false ) else moves = generate_pseudo_legal_moves ( castling : false , pawns : true , knights : false , bishops : false , rooks : false , queens : false , king : false ) end from_mask = Board :: BB_ALL if match [ 2 ] from_mask = from_mask & Board :: BB_FILES [ Board :: FILE_NAMES . index ( match [ 2 ] . to_sym ) ] end if match [ 3 ] from_mask = from_mask & Board :: BB_RANKS [ match [ 3 ] . to_i - 1 ] end matched_move = nil moves . each do | move | if move . to_square != to_square next end if move . promotion != promotion next end if Board :: BB_SQUARES [ move . from_square ] & from_mask == 0 next end if into_check? ( move ) next end if matched_move raise ArgumentError , "ambiguous san: #{san}" end matched_move = move end if ! matched_move raise ArgumentError , "illegal san: #{san}" end return matched_move 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 .
# Null moves. # Castling. # Match normal moves. # Get target square. # Get the promotion type. # Filter by piece type. # Filter by source file. # Filter by source rank. # Match legal moves.
san
<not_specific>