-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathchess_validator.rb
222 lines (170 loc) · 5.37 KB
/
chess_validator.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
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
require 'pry'
require 'rspec'
module Movements
def horizontal coordinate_ini, coordinate_end
coordinate_ini[0] == coordinate_end[0]
end
def vertical coordinate_ini, coordinate_end
coordinate_ini[1] == coordinate_end[1]
end
def diagonal coordinate_ini, coordinate_end
(coordinate_ini[0] - coordinate_end[0]).abs == (coordinate_ini[1] - coordinate_end[1]).abs
end
def one_step_horizontal coordinate_ini, coordinate_end
horizontal(coordinate_ini, coordinate_end) && (coordinate_ini[1] - coordinate_end[1]).abs == 1
end
def one_step_vertical coordinate_ini, coordinate_end
vertical(coordinate_ini, coordinate_end) && (coordinate_ini[0] - coordinate_end[0]).abs == 1
end
def two_steps_vertical coordinate_ini, coordinate_end
vertical(coordinate_ini, coordinate_end) && (coordinate_ini[0] - coordinate_end[0]).abs == 2
end
def one_step_diagonal coordinate_ini, coordinate_end
diagonal(coordinate_ini, coordinate_end) && (coordinate_ini[0] - coordinate_end[0]).abs == 1
end
def up coordinate_ini, coordinate_end
coordinate_ini[0] > coordinate_end[0]
end
def down coordinate_ini, coordinate_end
coordinate_ini[0] < coordinate_end[0]
end
end
class Board
def initialize coordinate_ini, coordinate_end, list_pieces
@board = Array.new(8) { Array.new(8) }
@coordinate_ini = coordinate_ini
@coordinate_end = coordinate_end
@list_pieces = list_pieces
@board[4][0] = :wR
@board[6][3] = :bR
check_move
end
def check_move
select_piece_on_board
create_piece_with_position_and_color
if @piece.rule_movement?(@coordinate_end) && destination_empty?
puts "LEGAL"
else
puts "ILEGAL"
end
end
def select_piece_on_board
@piece_selected = @board[@coordinate_ini[0]][@coordinate_ini[1]]
end
def create_piece_with_position_and_color
if @piece_selected[0] == "b"
color = "black"
elsif @piece_selected[0] == "w"
color = "white"
end
@piece = @list_pieces[@piece_selected].new(@coordinate_ini, color)
puts @piece
puts @piece.color
puts @coordinate_ini
puts @coordinate_end
end
def destination_empty?
@board[@coordinate_end[0]][@coordinate_end[1]] == nil
end
end
class ChessValidator
attr_accessor :list_pieces, :coordinate_ini, :coordinate_end
def initialize list_pieces
@list_pieces = list_pieces
end
def make_move string_coordinates
string_to_coordinate string_coordinates
@coordinate_ini = convert_coordinate(@coordinate_ini)
@coordinate_end = convert_coordinate(@coordinate_end)
@board = Board.new(@coordinate_ini, @coordinate_end, @list_pieces)
end
def string_to_coordinate string
@coordinate_ini = string.split(" ")[0].split("")
@coordinate_end = string.split(" ")[1].split("")
end
def convert_coordinate coordinate
convert_coordinate = []
convert_coordinate[0] = 8 - coordinate[1].to_i
convert_coordinate[1] = coordinate[0].ord - 97
convert_coordinate
end
end
class Piece
include Movements
attr_accessor :color
def initialize coordinate_ini, color
@coordinate_ini = coordinate_ini
@color = color
end
end
class Rook < Piece
def rule_movement? coordinate_end
horizontal(@coordinate_ini, coordinate_end) || vertical(@coordinate_ini, coordinate_end)
end
end
class Queen < Piece
def rule_movement? coordinate_end
horizontal(@coordinate_ini, coordinate_end) || vertical(@coordinate_ini, coordinate_end) || diagonal(@coordinate_ini, coordinate_end)
end
end
class Bishop < Piece
def rule_movement? coordinate_end
diagonal(@coordinate_ini, coordinate_end)
end
end
class King < Piece
def rule_movement? coordinate_end
one_step_horizontal(@coordinate_ini, coordinate_end) || one_step_vertical(@coordinate_ini, coordinate_end) || one_step_diagonal(@coordinate_ini, coordinate_end)
end
end
class Pawn < Piece
def rule_movement? coordinate_end
case @color
when "black" then
if @coordinate_ini[0] == 1
two_steps_vertical(@coordinate_ini, coordinate_end) || one_step_vertical(@coordinate_ini, coordinate_end) && down(@coordinate_ini, coordinate_end)
else
one_step_vertical(@coordinate_ini, coordinate_end) && down(@coordinate_ini, coordinate_end)
end
when "white" then
if @coordinate_ini[0] == 6
two_steps_vertical(@coordinate_ini, coordinate_end) || one_step_vertical(@coordinate_ini, coordinate_end) && up(@coordinate_ini, coordinate_end)
else
one_step_vertical(@coordinate_ini, coordinate_end) && up(@coordinate_ini, coordinate_end)
end
end
true
end
end
list_pieces = {
bR: Rook,
wR: Rook,
bQ: Queen,
wQ: Queen,
bB: Bishop,
wB: Bishop,
bK: King,
wK: King,
bP: Pawn,
wP: Pawn,
}
RSpec.describe "Chess Validator" do
it "Rook moves from d4 to d6 returns true" do
expect(ChessValidator.new(list_pieces).make_move("d4 d6")).to be_truthy
end
end
RSpec.describe "Rook movement" do
it "Rook moves from [4, 3] to [1, 3] returns true" do
expect(Rook.new([4, 3], "white").rule_movement?([1, 3])).to be true
end
it "Rook moves from [4, 3] to [1, 0] returns false" do
expect(Rook.new([4, 3], "white").rule_movement?([1, 0])).to be false
end
end
validate = ChessValidator.new(list_pieces).make_move("d4 d6")
# KING –> REY
# ROOK –> TORRE
# PAWN –> PEÓN
# KNIGHT –> CABALLO
# QUEEN –> DAMA
# BISHOP –> ALFIL