Module: ChessEngine::MoveValidator

Included in:
Game
Defined in:
lib/chess_engine/validator.rb

Instance Method Summary collapse

Instance Method Details

#en_passant_coords(from) ⇒ Object



74
75
76
77
78
79
80
81
82
83
84
85
# File 'lib/chess_engine/validator.rb', line 74

def en_passant_coords(from)
  pawn = @board.at(from)
  [1, -1].each do |x|
    next_coords = [from[0] + x, from[1]]
    next_piece = @board.at(next_coords)
    if next_piece.class == Pawn && next_piece == @last_piece &&
      next_piece.moves_count == 1 && from[1].between?(3, 4)
        return [from[0] + x, from[1] + pawn.direction]
    end
  end
  nil
end

#fatal_move?(from, to) ⇒ Boolean

Returns:

  • (Boolean)


47
48
49
50
51
52
53
54
# File 'lib/chess_engine/validator.rb', line 47

def fatal_move?(from, to)
  is_fatal = false
  move = Move.new(@board, from, to)
  move.commit
  is_fatal = true if king_attacked?
  move.rollback
  is_fatal
end

#pawn_valid_moves(from) ⇒ Object



56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
# File 'lib/chess_engine/validator.rb', line 56

def pawn_valid_moves(from)
  pawn = @board.at(from)
  direction = pawn.direction
  moves = []
  next_coords = relative_coords(from, [0, direction])
  jump_coords = relative_coords(from, [0, direction * 2])
  take_coords = [relative_coords(from, [1, direction]),
    relative_coords(from, [-1, direction])]
  if @board.exists_at?(next_coords) && @board.at(next_coords).nil?
    moves << next_coords
    moves << jump_coords unless pawn.moves_count > 0 || @board.at(jump_coords)
  end
  take_coords.each do |coords|
    moves << coords if @board.at(coords) && @board.at(coords).color != pawn.color
  end
  en_passant_coords(from) ? moves << en_passant_coords(from) : moves
end

#relative_coords(from, move) ⇒ Object



35
36
37
# File 'lib/chess_engine/validator.rb', line 35

def relative_coords(from, move)
  [from[0] + move[0], from[1] + move[1]]
end

#repeated_move(from, move, valid_moves = []) ⇒ Object



28
29
30
31
32
33
# File 'lib/chess_engine/validator.rb', line 28

def repeated_move(from, move, valid_moves = [])
  coordinates = relative_coords(from, move)
  return valid_moves unless valid_move?(coordinates)
  return valid_moves << coordinates unless @board.at(coordinates).nil?
  repeated_move(coordinates, move, valid_moves << coordinates)
end

#safe_moves(from) ⇒ Object



3
4
5
# File 'lib/chess_engine/validator.rb', line 3

def safe_moves(from)
  valid_moves(from).reject { |move| fatal_move?(from, move) }
end

#valid_move?(coordinates) ⇒ Boolean

Returns:

  • (Boolean)


39
40
41
42
43
44
45
# File 'lib/chess_engine/validator.rb', line 39

def valid_move?(coordinates)
  if @board.exists_at?(coordinates)
    piece = @board.at(coordinates)
    return (piece.nil? || piece.color != @current_color)
  end
  return false
end

#valid_moves(from) ⇒ Object



7
8
9
10
11
12
13
14
15
16
17
18
19
# File 'lib/chess_engine/validator.rb', line 7

def valid_moves(from)
  piece = @board.at(from)
  if piece.king? || piece.knight?
    piece.moves.map do |move|
      to = relative_coords(from, move)
      to if valid_move?(to)
    end.compact
  elsif piece.pawn?
    pawn_valid_moves(from)
  else
    valid_moves_recursive(from)
  end
end

#valid_moves_recursive(from) ⇒ Object



21
22
23
24
25
26
# File 'lib/chess_engine/validator.rb', line 21

def valid_moves_recursive(from)
  piece = @board.at(from)
  piece.moves.inject([]) do |valid_moves, move|
    valid_moves.push(*repeated_move(from, move))
  end
end