Method: ChessRB::Position#check?

Defined in:
lib/chess_rb/position.rb

#check?Boolean

Returns if the current position is check, false otherwise

Returns:

  • (Boolean)


60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
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
# File 'lib/chess_rb/position.rb', line 60

def check?
  raise RuntimeError "Invalid Position" if !valid?

  t = turn().upcase
  not_t = t == 'W' ? 'B' : 'W'
  king_vector = Vector[*(squares_with([t + 'K'])[0])]

  # check pawn squares
  pawn_vectors = t == 'W' ? [[-1, -1], [1, -1]] : [[-1, 1], [1, 1]]
  pawn_vectors.each do |s|
    s = (king_vector + Vector[*s]).to_a
    next if !self.class.valid_square?(s)
    return true if piece_on(s).desc == (not_t + 'P')
  end

  # check knight squares
  knight_vectors = [[1,2], [-1,2], [1,-2], [-1,-2], [2,1], [-2,1], [2,-1],
    [-2,-1]]
  knight_vectors.each do |s|
    s = (king_vector + Vector[*s]).to_a
    next if !self.class.valid_square?(s)
    return true if piece_on(s).desc == (not_t + 'N')
  end

  # check bishop/queen squares
  diagonal_vectors = [[1, 1], [-1, 1], [1, -1], [-1, -1]]
  diagonal_vectors.each do |v|
    dist = 1
    v = Vector[*v]
    while dist < 8
      current_vector = v * dist
      current_square = (king_vector + current_vector).to_a

      break if !self.class.valid_square?(current_square)

      p = piece_on(current_square).desc
      return true if p == (not_t + 'B') || p == (not_t + 'Q')
      break if p != 'E'

      dist += 1
    end
  end

  # check rook/queen squares
  straight_vectors = [[1, 0], [0, 1], [-1, 0], [0, -1]]
  straight_vectors.each do |v|
    dist = 1
    v = Vector[*v]
    while dist < 8
      current_vector = v * dist
      current_square = (king_vector + current_vector).to_a

      break if !self.class.valid_square?(current_square)

      p = piece_on(current_square).desc
      return true if p == (not_t + 'B') || p == (not_t + 'Q')
      break if p != 'E'

      dist += 1
    end
  end

  return false
end