git.mcksp
    1
    2
    3
    4
    5
    6
    7
    8
    9
   10
   11
   12
   13
   14
   15
   16
   17
   18
   19
   20
   21
   22
   23
   24
   25
   26
   27
   28
   29
   30
   31
   32
   33
   34
   35
   36
   37
   38
   39
   40
   41
   42
   43
   44
   45
   46
   47
   48
   49
   50
   51
   52
   53
   54
   55
   56
   57
   58
   59
   60
   61
   62
   63
   64
   65
   66
   67
   68
   69
   70
   71
   72
   73
   74
   75
   76
   77
   78
   79
require "./moves"

module Fork
  def self.uci
    board = STARTING_BOARD.dup
    running = true

    while running
      input = gets
      if input
        case input.strip
        when "uci"
          puts "id name fork"
          puts "id author mcksp"
          puts "uciok"
        when "isready"
          puts "readyok"
        when /^position.*/
          parts = input.split
          if parts[1] == "startpos"
            board = STARTING_BOARD.dup
          else
            fen_start = input.index("fen")
            fen_end = input.index("moves")
            break if fen_start.nil? || fen_end.nil?
            fen = input[(fen_start + 4)..fen_end]
            board = Board.new(fen)
          end
          moves_pos = input.index("moves")
          next if moves_pos.nil?
          moves = input[moves_pos + 5..-1].split
          moves.each do |m|
            col_from = m[0] - 'a'
            row_from = m[1] - '1'
            col_to = m[2] - 'a'
            row_to = m[3] - '1'
            promo = 0
            if m.size > 4
              case m[4]
              when 'n'
                promo = KNIGHT
              when 'b'
                promo = BISHOP
              when 'r'
                promo = ROOK
              when 'q'
                promo = QUEEN
              end
            end
            move = Fork.generate_moves(board).find do |lm|
              lm.from == col_from + 8 * row_from && lm.to == col_to + 8 * row_to && lm.promote_to = promo
            end
            raise "no legal move found" if move.nil?
            board.make_move(move)
          end
        when /^go.*/
          moves = Search.new(board).run
          m = moves.first
          promo = ""
          if !m.nil? && m.promote_to != 0
            case m.promote_to
            when KNIGHT
              promo = "n"
            when BISHOP
              promo = "b"
            when ROOK
              promo = "r"
            when QUEEN
              promo = "q"
            end
          end
          puts "bestmove #{Fork.square_to_text(m.from)}#{Fork.square_to_text(m.to)}#{promo}" unless m.nil?
        when "quit"
          running = false
        end
      end
    end
  end
end