-
Notifications
You must be signed in to change notification settings - Fork 0
/
validate_move.py
executable file
·305 lines (271 loc) · 8.69 KB
/
validate_move.py
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
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
"""
validate_move.py - Defines the checks which prevent non-valid moves in chess
By: Runaal Parmar
Dec 17, 2018
"""
from termcolor import colored
from copy import deepcopy
from piece import Piece
import checks
def is_valid_pawn_move(board, cords, player, row_vec, col_vec, prev_board):
"""
Checks if the requested move is valid for a pawn
"""
# Define default return
vec = [True]
# Determine if the move/attack is valid for either player
if player == "black" and col_vec == 0 and row_vec == 1:
black_move = True
else:
black_move = False
if player == "white" and col_vec == 0 and row_vec == -1:
white_move = True
else:
white_move = False
if player == "black" and abs(col_vec) == 1 and row_vec == 1:
black_attacking = True
else:
black_attacking = False
if player == "white" and abs(col_vec) == 1 and row_vec == -1:
white_attacking = True
else:
white_attacking = False
# Either color moving the pawn 2 steps
if col_vec == 0 and abs(row_vec) == 2:
if board.map[cords[2]][cords[3]].get_symbol() == " ":
if cords[0] != 1 and cords[0] != 6:
vec = [False, "Pawn can only move 2 spaces on its first move!"]
else:
vec = [False, "Pawn cannot walk into opposing piece!"]
# Either color moving the pawn 1 step
elif white_move or black_move:
if board.map[cords[2]][cords[3]].get_symbol() == " ":
if cords[2] == 7 or cords[2] == 0:
board.map[cords[0]][cords[1]].promote(cords, player)
else:
vec = [False, "Pawn cannot walk into opposing piece!"]
# Either color attacking with the pawn
elif white_attacking or black_attacking:
if board.map[cords[2]][cords[3]].get_type() == " ":
# En passant for white pawn
if white_attacking:
if board.map[cords[2]+1][cords[3]].get_type() == "pawn":
if board.map[cords[2]+1][cords[3]].get_color() == "black":
if prev_board.map[cords[2]+1][cords[3]].get_type() == " ":
if prev_board.map[cords[2]][cords[3]].get_type() == " ":
vec = [True]
board.map[cords[2]+1][cords[3]] = Piece(" ", " ", " ", " ")
return vec
# En passant for black pawn
elif black_attacking:
if board.map[cords[2]-1][cords[3]].get_type() == "pawn":
if board.map[cords[2]-1][cords[3]].get_color() == "white":
if prev_board.map[cords[2]-1][cords[3]].get_type() == " ":
if prev_board.map[cords[2]][cords[3]].get_type() == " ":
vec = [True]
board.map[cords[2]-1][cords[3]] = Piece(" ", " ", " ", " ")
return vec
# No valid piece to attack!
vec = [False, "No pieces for the pawn to attack!"]
# Found a piece for the pawn to attack
elif board.map[cords[2]][cords[3]].get_color() != player:
if cords[2] == 7 or cords[2] == 0:
board.map[cords[0]][cords[1]].promote(cords, player)
# Invalid move for the pawn
else:
vec = [False, "This is not a valid move for a pawn!"]
return vec
def is_valid_king_move(board, cords, row_vec, col_vec, player):
"""
Checks if the requested move is valid for the king
"""
# The King can move one step in any direction
if abs(row_vec) <= 1 and abs(col_vec) <= 1:
vec = [True]
return vec
# Check if castling
if abs(col_vec) == 2:
if board.map[cords[0]][cords[1]].get_has_moved() == False:
if col_vec < 0:
col = 0
else:
col = 7
mid_col = cords[1] + (col_vec//2)
if board.map[cords[0]][mid_col].get_type() == " ":
if board.map[cords[0]][col].get_has_moved() == False:
if checks.is_king_in_check(board, player) == True:
vec = [False, "Cannot castle while in check!"]
return vec
test_board = deepcopy(board)
test_board.map[cords[0]][mid_col] = test_board.map[cords[0]][cords[1]]
test_board.map[cords[0]][cords[1]] = Piece(" ", " ", " ", " ")
if checks.is_king_in_check(test_board, player) == True:
vec = [False, "Cannot castle through a check!"]
return vec
test_board = deepcopy(board)
test_board.map[cords[0]][cords[3]] = test_board.map[cords[0]][cords[1]]
test_board.map[cords[0]][cords[1]] = Piece(" ", " ", " ", " ")
if checks.is_king_in_check(test_board, player) == True:
vec = [False, "Cannot castle into a check!"]
return vec
# If this point is reached, the castle move is valid
board.map[cords[0]][mid_col] = board.map[cords[0]][col]
board.map[cords[0]][mid_col].set_has_moved()
board.map[cords[0]][col] = Piece(" ", " ", " ", " ")
vec = [True]
return vec
else:
vec = [False, "Cannot castle through a piece!"]
return vec
vec = [False, "This is not a valid move for a King!"]
return vec
def is_valid_knight_move(board, row_vec, col_vec):
"""
Checks if the requested move is valid for the knight
"""
# Define default return
vec = [True]
# Checks all 8 moves for the knight
if abs(row_vec) == 2 and abs(col_vec) == 1:
return vec
elif abs(row_vec) == 1 and abs(col_vec) == 2:
return vec
vec = [False, "This is not a valid move for a Knight!"]
return vec
def is_valid_queen_move(board, cords, row_vec, col_vec):
"""
Checks if the requested move is valid for the queen
"""
# Define default return
vec = [True]
collision = None
# Checks diagonal 1
if row_vec == col_vec:
row1 = min(cords[0], cords[2]) + 1
col1 = min(cords[1], cords[3]) + 1
row2 = max(cords[0], cords[2])
while row1 < row2:
if board.map[row1][col1].get_symbol() != " ":
collision = "yes"
row1 += 1
col1 += 1
# Checks diagonal 2
elif row_vec*-1 == col_vec:
row1 = min(cords[0], cords[2]) + 1
col1 = max(cords[1], cords[3]) - 1
row2 = max(cords[0], cords[2])
while row1 < row2:
if board.map[row1][col1].get_symbol() != " ":
collision = "yes"
row1 += 1
col1 -= 1
# Checks the row if the move is valid
elif row_vec == 0:
start = min(cords[1], cords[3]) + 1
end = max(cords[1], cords[3])
while start < end:
if board.map[cords[0]][start].get_symbol() != " ":
collision = "yes"
start += 1
# Checks the column if the move is valid
elif col_vec == 0:
start = min(cords[0], cords[2]) + 1
end = max(cords[0], cords[2])
while start < end:
if board.map[start][cords[1]].get_symbol() != " ":
collision = "yes"
start += 1
else:
vec = [False, "This is not a valid move for a Queen!"]
return vec
# If collisions occured, move is bad!
if collision == "yes":
vec = [False, "The Queen cannot pass through pieces!"]
return vec
def is_valid_bishop_move(board, cords, row_vec, col_vec):
"""
Checks if the requested move is valid for the bishop
"""
# Define default return
vec = [True]
collision = None
# Checks the diagonal if the move is valid
if row_vec == col_vec:
row1 = min(cords[0], cords[2]) + 1
col1 = min(cords[1], cords[3]) + 1
row2 = max(cords[0], cords[2])
while row1 < row2:
if board.map[row1][col1].get_symbol() != " ":
collision = "yes"
row1 += 1
col1 += 1
# Checks the other diagonal if the move is valid
elif row_vec*-1 == col_vec:
row1 = min(cords[0], cords[2]) + 1
col1 = max(cords[1], cords[3]) - 1
row2 = max(cords[0], cords[2])
while row1 < row2:
if board.map[row1][col1].get_symbol() != " ":
collision = "yes"
row1 += 1
col1 -= 1
else:
vec = [False, "This is not a valid move for a Bishop!"]
return vec
# If collisions occured, move is bad!
if collision == "yes":
vec = [False, "The bishop cannot pass through pieces!"]
return vec
def is_valid_rook_move(board, cords, row_vec, col_vec):
"""
Checks if the requested move is valid for the rook
"""
# Define default return
vec = [True]
collision = None
# Checks the row if the move is valid
if row_vec == 0:
start = min(cords[1], cords[3]) + 1
end = max(cords[1], cords[3])
while start < end:
if board.map[cords[0]][start].get_symbol() != " ":
collision = "yes"
start += 1
# Checks the column if the move is valid
elif col_vec == 0:
start = min(cords[0], cords[2]) + 1
end = max(cords[0], cords[2])
while start < end:
if board.map[start][cords[1]].get_symbol() != " ":
collision = "yes"
start += 1
else:
vec = [False, "This is not a valid move for a Rook!"]
return vec
# If no collisions, move is good!
if collision == "yes":
vec = [False, "The rook cannot pass through pieces!"]
return vec
def is_attacking_own_piece(board, cords):
"""
Checks if the player is attempting to attack their own piece
Returns True
"""
atk_piece_color = board.map[cords[0]][cords[1]].get_color()
def_piece_color = board.map[cords[2]][cords[3]].get_color()
if atk_piece_color == " " or def_piece_color == " ":
return False
elif atk_piece_color is def_piece_color:
return True
else:
return False
def is_own_piece(board, cords, player):
"""
Ensures the player is moving their own piece.
Returns True if acceptable move
"""
# If player is attacking self, return true
if board.map[cords[0]][cords[1]].get_color() == player:
return True
else:
return False