-
Notifications
You must be signed in to change notification settings - Fork 0
/
chess_board.rb
127 lines (110 loc) · 2.79 KB
/
chess_board.rb
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
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
124
125
126
127
class Board
attr_reader :board
def self.make_starting_board
board = Board.new
starting_row = [Rook, Knight, Bishop, Queen, King, Bishop, Knight, Rook]
starting_row.each_with_index do |piece_class, idx|
board.place_piece(piece_class, [0, idx], :black)
board.place_piece(piece_class, [7, idx], :white)
board.place_piece(Pawn, [1, idx], :black)
board.place_piece(Pawn, [6, idx], :white)
end
board
end
def initialize
@board = Array.new(8) { Array.new(8) }
end
def deep_dup
dupped_board = Board.new
@board.each_with_index do |row, r_index|
row.each_with_index do |square, c_index|
unless square.nil?
pos = [r_index, c_index]
klass, color = square.class, square.color
dupped_board.place_piece(klass, pos, color)
end
end
end
dupped_board
end
def place_piece(piece_class, pos, color)
piece = piece_class.new(self, pos, color)
self[pos] = piece
end
def checkmate?(color)
if in_check?(color)
own_color_pieces = get_same_color_pieces(color)
own_color_pieces.all? { |piece| piece.valid_moves.empty? }
end
end
def move(start, end_pos)
raise "No piece." if empty?(start)
piece = self[start]
raise "Invalid move." unless piece.valid_moves.include?(end_pos)
piece.position = end_pos
move!(start, end_pos)
end
def move!(start, end_pos)
self[start], self[end_pos] = nil, self[start]
end
def on_board?(row, col)
(0..7).include?(row) && (0..7).include?(col)
end
def empty?(pos)
self[pos].nil?
end
def capturable?(pos, color)
self[pos].color != color
end
def find_opposite_pieces(color)
@board.flatten.compact.select do |piece|
piece.color != color
end
end
def get_same_color_pieces(color)
@board.flatten.compact.select do |piece|
piece.color == color
end
end
def in_check?(color)
king_position = find_king(color)
find_opposite_pieces(color).each do |piece|
return true if piece.possible_moves.include?(king_position)
end
false
end
def inspect
return @board.each {|r| p r}
end
def render
puts " 0 1 2 3 4 5 6 7"
@board.each_with_index do |row, i|
print "#{i}:"
row.each do |tile|
if tile.nil?
print " _ "
else
print " #{tile.inspect} "
end
end
puts
end
end
def [](pos)
x = pos[0]
y = pos[1]
@board[x][y]
end
def []=(pos, value)
x = pos[0]
y = pos[1]
@board[x][y] = value
end
def find_king(color)
@board.each_with_index do |row, r_index|
row.each_with_index do |square, c_index|
return [r_index, c_index] if square.is_a?(King) && square.color == color
end
end
end
end