-
Notifications
You must be signed in to change notification settings - Fork 0
/
board.rb
149 lines (111 loc) · 2.82 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
# encoding: utf-8
require_relative "piece"
require_relative "knight"
require_relative "rook"
require_relative "queen"
require_relative "bishop"
require_relative "king"
require_relative "pawn"
require_relative "slider"
class Board
attr_accessor :size, :grid
BACK_ROW = [Rook, Knight,
Bishop, Queen,
King, Bishop,
Knight, Rook]
def initialize(size = 8)
@size = size
@grid = Array.new(size) {Array.new(size)}
end
def board_setup
set_pawns
set_backrows
end
def set_pawns
self.size.times do |i|
Pawn.new([1,i], :white, self)
Pawn.new([self.size-2,i], :black, self)
end
end
def set_backrows
self.size.times do |i|
BACK_ROW[i].new([0,i], :white, self)
BACK_ROW[i].new([self.size-1,i], :black, self)
end
end
def display
puts "xy|" + ([email protected]).map {|i| i.to_s}.join(" ")
@grid.size.times {|i| puts i.to_s.ljust(3) + print_row(i)}
end
def print_row(i)
@grid[i].map {|el| el ? el.display.ljust(2) : " "}.join("")
end
def try_move(from_pos, to_pos)
piece = self.dup.get_spot(from_pos)
raise IllegalMove.new("No Piece Found") unless piece
raise IllegalMove.new("You Cheater!") unless piece.moves.include?(to_pos)
raise IllegalMove.new("Revealed Check") if self.dup.reveal_check?(from_pos, to_pos)
self.move(from_pos, to_pos)
end
def move(from_pos, to_pos)
piece = get_spot(from_pos)
self.set_spot(piece, to_pos)
self.nil_spot(from_pos)
piece.pos = to_pos
self
end
def nil_spot(pos)
self.set_spot(nil, pos)
self
end
def set_spot(to_put, pos)
x,y = pos
self.grid[x][y] = to_put
self
end
def get_spot(pos)
if in_board?(pos)
x, y = pos
self.grid[x][y]
else
nil
end
end
def in_board?(pos)
pos.all? {|el| ([email protected]).include?(el)}
end
def in_check?(color)
king_spot = get_king_spot(color)
whole_grid = @grid.flatten.compact
whole_grid.any? {|piece| piece.moves.include?(king_spot)}
end
def check_mate?(color)
boards = []
pieces = self.pieces.select {|piece| piece.color == color}
pieces.each do |piece|
piece.moves.each { |move| boards << self.dup.move(piece.pos, move)}
end
boards.all? { |board| board.in_check?(color) }
end
def reveal_check?(from_pos, to_pos)
piece = self.get_spot(from_pos)
self.move(from_pos, to_pos)
self.in_check?(piece.color)
end
def get_king_spot(color)
self.pieces.find {|piece| self.right_king?(piece, color)}.pos
end
def right_king?(piece, color)
piece.class == King && piece.color == color
end
def dup
new_board = Board.new
self.pieces.each { |piece| piece.dup(new_board) }
new_board
end
def pieces
@grid.flatten.compact
end
end
class IllegalMove < StandardError
end