/
board.rb
142 lines (109 loc) · 2.91 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
require_relative 'pieces/piece_junction'
require_relative 'keypress'
class InvalidMove < StandardError
end
class InvalidSelection < StandardError
end
class Board
attr_accessor :cursor, :move_in_process, :selected_piece, :grid
def initialize(fill_board = true)
@grid = Array.new(8) { Array.new(8) { EmptySquare.new } }
@cursor = [7, 0]
@move_in_process = false
populate_board if fill_board
end
def [](row, col)
@grid[row][col]
end
def []=(row, col, mark)
@grid[row][col] = mark
end
def populate_board
p "populating board"
grid[0] = populate_royalty(:black, 0)
grid[1] = populate_pawns(:black, 1)
grid[6] = populate_pawns(:white, 6)
grid[7] = populate_royalty(:white, 7)
end
def populate_royalty(color, row)
[
Rook.new(color, self, [row, 0]),
Knight.new(color, self, [row, 1]),
Bishop.new(color, self, [row, 2]),
Queen.new(color, self, [row, 3]),
King.new(color, self, [row, 4]),
Bishop.new(color, self, [row, 5]),
Knight.new(color, self, [row, 6]),
Rook.new(color, self, [row, 7])
]
end
def populate_pawns(color, row)
arr = []
0.upto(7) do |col|
arr << Pawn.new(color, self, [row, col])
end
arr
end
def move(color, start_pos, end_pos)
piece = self[*start_pos]
if !(piece.valid_moves.include?(end_pos))
raise InvalidMove, "you can't move into check"
end
move_piece!(start_pos, end_pos)
end
def move_piece!(start_pos, end_pos)
piece = self[*start_pos]
end_piece = self[*end_pos]
self[*start_pos] = EmptySquare.new
self[*end_pos] = piece
piece.pos = end_pos
if piece.is_a?(Pawn)
piece.moved = true
end
end
def find_king(color)
pieces.each do |piece|
if ((piece.class == King) && (piece.color == color))
return piece.pos
end
end
raise 'no king on board'
end
def in_check?(color)
king_pos = find_king(color)
pieces.each do |piece|
moves = []
moves = piece.all_moves
if moves.include?(king_pos)
return true
end
end
false
end
def checkmate?(current_player)
color = current_player.color
return false unless in_check?(color)
all_pieces_of_current_player = pieces.select { |piece| piece.color == color }
all_pieces_of_current_player.all? { |piece| piece.valid_moves.empty? }
end
def on_board?(potential_move)
potential_move.all? { |pos| pos.between?(0, 7) }
end
def valid_move?(potential_move, color)
on_board?(potential_move) && (!is_piece?(potential_move) )
end
def pieces
grid.flatten.reject { |piece| !piece.color }
end
def dup
new_board = Board.new(false)
pieces.each do |piece|
dup_piece = piece.class.new(piece.color, new_board, piece.pos)
new_board.grid[piece.pos[0]][piece.pos[1]] = dup_piece
end
new_board
end
def is_piece?(position)
self[*position].color
end
end