-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathboard.rb
153 lines (127 loc) · 3.47 KB
/
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
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
require_relative "piece"
require_relative "bishop"
require_relative "king"
require_relative "knight"
require_relative "null_piece"
require_relative "pawn"
require_relative "queen"
require_relative "rook"
class Board
def initialize (is_dup=false)
@grid = Array.new(8) { Array.new(8) { NullPiece.instance } }
if !is_dup
@grid.each_with_index do |row, i|
if i.between?(0,1)
symbol = :b
elsif i.between?(6,7)
symbol = :w
end
if i == 0 || i == 7
@grid[i] = [Rook.new(symbol, self, [i, 0]),
Knight.new(symbol, self, [i, 1]),
Bishop.new(symbol, self, [i, 2]),
Queen.new(symbol, self, [i, 3]),
King.new(symbol, self, [i, 4]),
Bishop.new(symbol, self, [i, 5]),
Knight.new(symbol, self, [i, 6]),
Rook.new(symbol, self, [i, 7])]
elsif i == 1 || i == 6
(0...@grid.length).each { |j| @grid[i][j] = Pawn.new(symbol, self, [i, j]) }
end
end
end
end
def [] (pos)
row, col = pos
@grid[row][col]
end
def []=(pos, value)
row, col = pos
@grid[row][col] = value
end
def move_piece (color, start_pos, end_pos)
start_piece = self[start_pos]
end_piece = self[end_pos]
if start_piece.empty?
raise "No piece at #{start_pos}!"
elsif start_piece.color != color
raise "Cannot move other player's piece!"
elsif !end_piece.empty? && end_piece.color == color
raise "Cannot move to #{end_pos}: Occupied by same-colored piece."
elsif !start_piece.valid_moves.include?(end_pos)
raise "Invalid move!"
end
add_piece(start_piece, end_pos)
self[start_pos] = NullPiece.instance
end
def valid_pos? (pos)
row, col = pos
if !row.between?(0,7) || !col.between?(0,7)
return false
else
return true
end
end
def add_piece (piece, pos)
self[pos] = piece
piece.pos = pos
end
def find_king (color)
pieces.each do |piece|
if piece.is_a?(King) && piece.color == color
return piece.pos
end
end
end
def in_check? (color)
king_pos = find_king(color)
pieces.each do |piece|
moves = piece.moves
if piece.color != color && moves.include?(king_pos)
return true
end
end
return false
end
def checkmate? (color)
if in_check?(color)
pieces.each do |piece|
valid_moves = piece.valid_moves
if piece.color == color && valid_moves.length > 0
return false
end
end
else
return false
end
return true
end
def pieces
piece_arr = []
@grid.each do |row|
row.each { |piece| piece_arr << piece if !piece.empty? }
end
piece_arr
end
def dup
dup_board = Board.new(true)
pieces.each do |piece|
class_type = piece.class
dup_pos = [piece.pos[0], piece.pos[1]]
new_piece = class_type.new(piece.color, dup_board, dup_pos)
dup_board.add_piece(new_piece, dup_pos)
end
dup_board
end
def move_piece! (color, start_pos, end_pos)
start_piece = self[start_pos]
end_piece = self[end_pos]
if start_piece.empty?
raise "No piece at #{start_pos}!"
elsif !end_piece.empty? && end_piece.color == color
raise "Cannot move to #{end_pos}. Occupied by same-colored piece."
end
add_piece(start_piece, end_pos)
self[start_pos] = NullPiece.instance
end
end