You are on page 1of 67

______________________________________________________________________________________________________________________

DELHI PUBLIC SCHOOL, AGRA


Computer Science Project
______________________________________________________________________________________________________________________

Chess
Using Python

______________________________________________________________________________________________________________________

Submitted By Saksham
Class XII
Section B
______________________________________________________________________________________________________________________

1
______________________________________________________________________________________________________________________

INDEX
______________________________________________________________________________________________________________________

Certificate 3
Acknowledgment 4
About 5
Software and Hardware Requirements 6
Source Code 7
Output Screen 64
Bibliography 67

2
______________________________________________________________________________________________________________________

CERTIFICATE
______________________________________________________________________________________________________________________

This is to certify that Saksham of class XII B of Delhi


Public School, Agra has completed his Computer
Science Project under my supervision and has taken
proper care and displayed utmost sincerity in
completion of this project.

His project is up to the standard both in respect of its


contents & form as per CBSE norms and this is his
original work as per my knowledge.

______________________________________________________________________________________________________________________

Ms. Nidhi Jain


(Subject Teacher) (External Examiner)

Ms. Meghana Sorick Mr. R.K. Pandey


(IC – Senior Secondary) (Principal)
______________________________________________________________________________________________________________________

3
______________________________________________________________________________________________________________________

ACKNOWLEDGEMENT
______________________________________________________________________________________________________________________

It is my privilege to offer special veneration and


heartiest gratitude to my valuable teacher Ms. Nidhi
Jain without whose encouraging attitude, sagacious
guidance and constant relevant help this project
could never have come out with flying colors.

Words are not enough to express my sense of


gratitude towards Chemistry Department, the
Principal and I/C Senior Secondary of Delhi Public
School Agra for their relevant support in the
fulfilment of my objective.

______________________________________________________________________________________________________________________

(Signature of Student)
______________________________________________________________________________________________________________________

4
______________________________________________________________________________________________________________________

ABOUT
______________________________________________________________________________________________________________________

The core objective of this chess game is to deploy a


user-friendly interface to a very simple yet
complicated game of chess into a computer system
with minimum problems and requirement.

The solution to that was to make a terminal-based


interface which is as minimalistic as it gets, we give
the user a very friendly gameplay which makes them
enter the position of a piece they want to move via
the keyboard.

The tracking of the moves is done by a database


created on MySQL which is linked to an algorithm
made to cross-check the moves of a piece taking
every permutation and combination possible which
doesn’t violate the rules of chess.

We also inserted a feature to host a game which


another player can join and enjoy the 1v1 game.
This is just the base idea of the Game the real fun is
when you play and finally understand it all and get
hooked to the fun that is awaiting you.

5
______________________________________________________________________________________________________________________

SOFTWARE
AND HARDWARE REQUIREMENTS
______________________________________________________________________________________________________________________

Processor
Intel Core i3-2310m (Any dual core would Work)

Memory
A minimum of 2Gb

Storage
A minimum of 2Gb

Software
Command Prompt
Python 3.8 or Higher
Python IDLE

6
SOURCE CODE
STARTS HERE

7
File Structure
│ board_image.png
│ start.py
│ __init__.py

├───classes
│ │ board.py
│ │ piece.py
│ │ position.py
│ │ vars.py
│ │ __init__.py
│ │
│ └───pieces
│ bishop.py
│ king.py
│ knight.py
│ pawn.py
│ queen.py
│ rook.py
│ __init__.py

├───database
│ config.py
│ connect.py
│ create.py
│ get.py
│ setup.py
│ update.py

└───ui
auth.py
classes.py
game.py
__init__.py

8
9
start.py

1 from .ui import start


2
3 start()

10
__init__.py

1 from .ui import start

11
classes/board.py

from .vars import pos_tuple


from .position import Position
1 from .pieces.pawn import Pawn
2 from .pieces.king import King
3 from .pieces.queen import Queen
4 from .pieces.knight import Knight
5 from .pieces.bishop import Bishop
6 from .pieces.rook import Rook
7
8
9 class Board:
10 """
11 Creates a board object
12 """
13
14 # Pawn positions
15 white_pawn_positions = ("a2", "b2", "c2", "d2", "e2", "f2", "g2", "h2")
16 black_pawn_positions = ("a7", "b7", "c7", "d7", "e7", "f7", "g7", "h7")
17 # Knight Positions
18 white_knight_positions = ("b1", "g1")
19 black_knight_positions = ("b8", "g8")
20 # Bishop Positions
21 white_bishop_positions = ("c1", "f1")
22 black_bishop_positions = ("c8", "f8")
23 # Rook Positions
24 white_rook_positions = ("a1", "h1")
25 black_rook_positions = ("a8", "h8")
26 # Queen Positions
27 white_queen_positions = ("d1",)
28 black_queen_positions = ("d8",)
29 # King Positions
30 white_king_positions = ("e1",)
31 black_king_positions = ("e8",)
32
33 def __init__(self):
34 self.position_dict = {}
35 # Creating Positions
36 for pos in pos_tuple:
37 self.position_dict[pos] = Position(pos)
38
39 # Creating Pawns
40 for pos in Board.white_pawn_positions:
41 piece = Pawn(self, "white", pos)
42 self.position_dict[pos].piece = piece
43 for pos in Board.black_pawn_positions:
44 piece = Pawn(self, "black", pos)
45 self.position_dict[pos].piece = piece
46
47 # Creating Bishops
48 for pos in Board.white_bishop_positions:
49 piece = Bishop(self, "white", pos)
50 self.position_dict[pos].piece = piece
51 for pos in Board.black_bishop_positions:
52
piece = Bishop(self, "black", pos)
53
self.position_dict[pos].piece = piece
54
55
# Creating Rooks
56
for pos in Board.white_rook_positions:
57
piece = Rook(self, "white", pos)
58
self.position_dict[pos].piece = piece
59
for pos in Board.black_rook_positions:
60
piece = Rook(self, "black", pos)
61
self.position_dict[pos].piece = piece
62 12
63
classes/board.py
64 # Creating Queens
65 for pos in Board.white_queen_positions:
66 piece = Queen(self, "white", pos)
67 self.position_dict[pos].piece = piece
68 for pos in Board.black_queen_positions:
69 piece = Queen(self, "black", pos)
70 self.position_dict[pos].piece = piece
71
72 # Creating Kings
73 for pos in Board.white_king_positions:
74 piece = King(self,"white", pos)
75 self.position_dict[pos].piece = piece
76 for pos in Board.black_king_positions:
77 piece = King(self,"black", pos)
78 self.position_dict[pos].piece = piece
79
80 # Creating Knights
81 for pos in Board.white_knight_positions:
82 piece = Knight(self, "white", pos)
83 self.position_dict[pos].piece = piece
84 for pos in Board.black_knight_positions:
85 piece = Knight(self,"black", pos)
86 self.position_dict[pos].piece = piece
87
88 def is_game_over(self, color):
89
for pos in pos_tuple:
90
if self.position_dict[pos].piece == None:
91
continue
92
93
94 piece_at_pos = self.position_dict[pos].piece
95
96 if type(piece_at_pos) == King:
97 if piece_at_pos.piece_color == color:
98 my_king = piece_at_pos
99 if my_king.is_in_mate():
100 return True, "lost"
101 else:
102 opp_king = piece_at_pos
103 if opp_king.is_in_mate():
104 return True, "won"
105
106 stalemate = True
107 for color in ["white", "black"]:
108 for pos in pos_tuple:
109 if self.position_dict[pos].piece == None:
110 continue
111
112 piece_at_pos = self.position_dict[pos].piece
113
114 if piece_at_pos.piece_color != color:
115 continue
116
117
if piece_at_pos.get_moves() != []:
118
stalemate = False
119
break
120
121
if not stalemate:
122
123 return False, None
124
125 if stalemate:
126 return True, "stalemate"
127
128 return False, None
129
13
def play_move(self, move_notation):
classes/board.py
130 move_list = move_notation.split("_")
131 from_pos = move_list[0]
132 to_pos = move_list[1]
133
134 if from_pos not in pos_tuple or to_pos not in pos_tuple:
135 raise ValueError("Invalid move")
136
137 if self.position_dict[from_pos].piece == None:
138 raise ValueError("Invalid move")
139
140 self.position_dict[from_pos].piece.move(to_pos)
141
142 def print_board(self, color):
143 '''
144 Prints the chess board for the given color in the terminal
145 '''
146
147 if color == "white":
148
print(" -" + ("-----" * 8))
149
print(" |", "Chess Board".center(39), "|", sep="")
150
for i in range(8, 0, -1):
151
152 print(" -" + ("-----" * 8))
153 print(f" {i} ", end="")
154 for j in range(97, 105):
155 pos = self.position_dict[f"{chr(j)}{i}"]
156 if pos.piece is None:
157 res = " "
158 else:
159 res = str(pos.piece)
160 print("| " + res, end = " ")
161 print("|")
162 print(" -" + ("-----" * 8))
163 print(end=" ")
164 for i in range(97, 105):
165 print(f"{chr(i)}".center(5), end="")
166 print()
167 elif color == "black":
168
print(" -" + ("-----" * 8))
169
print(" |", "Chess Board".center(39), "|", sep="")
170
for i in range(1, 9):
171
172 print(" -" + ("-----" * 8))
173 print(f" {i} ", end="")
174 for j in range(97, 105):
175 pos = self.position_dict[f"{chr(j)}{i}"]
176 if pos.piece is None:
177 res = " "
178 else:
179 res = str(pos.piece)
180 print("| " + res, end = " ")
181 print("|")
182 print(" -" + ("-----" * 8))
183 print(end=" ")
184 for i in range(97, 105):
print(f"{chr(i)}".center(5), end="")
print()

14
classes/peice.py

1 class Piece :
2 def __init__(self, board, piece_color, piece_position):
3 self.board = board # Board on which the piece is put
4 self.piece_color = piece_color # Color of the piece
5 self.piece_position = piece_position # Code of the position at which the piece is put
6
7 def forced_move(self, to):
8 """
9 Move piece from self.piece_position to given position even if given position is not in valid moves
10 """
11
12 # Remove the piece from it's original position
13 self.board.position_dict[self.piece_position].piece = None
14 # Put the piece on thr given 'to' position
15 self.board.position_dict[to].piece = self
16 # Update the name of the position at which the piece is
17 self.piece_position = to
18
19 def move(self, to):
20 """
21 Move piece from self.piece_position to given position if given position is in valid moves
22 """
23
24 # Check if the given 'to' position is a valid move
25 if to not in self.get_moves():
26 raise ValueError("Not a valid move!! ")
27
28 #generate notations for moves
29 notation = f"{self.piece_position}_{to} "
30
31 # Move the piece
32 self.forced_move(to)
33
34 return notation
35
36

15
classes/position.py

1 from .vars import position_color_relation


2
3 class Position:
4 """
5 Creates a position object with given code, generates the position color automatically
6 """
7
8 def __init__(self, code):
9 """
10 code: code of the position on board
11 """
12
13 self.position_code = code.lower() # Code of the position
14 self.position_color = position_color_relation[code] # Color of the position
15 self.piece = None # Piece that is kept at the position
16
17

16
classes/vars.py

1 # Tuple of all position codes


2 pos_tuple = tuple()
3 for i in range(1, 9):
4 for j in range(97, 105):
5 pos_tuple += (f"{chr(j).lower()}{i}",)
6
7 # Relation (dictionary) between a position code and it's color
8 position_color_relation = {}
9 color = "black"
10 count = 0
11 for pos in pos_tuple:
12 position_color_relation[pos] = color
13 count += 1
14
15 # If row is finished, set count to 0, else switch color
16 if count == 8:
17 count = 0
18 else:
19 if color == "black":
20 color = "white"
21 elif color == "white":
22 color = "black"

17
classes/pieces/bishop.py

from ..vars import pos_tuple


from ..piece import Piece
from .king import King

1
class Bishop(Piece):
2
"""
3
Creates a bishop object for given board, with given piece color and piece position
4
"""
5
def __init__(self, board, piece_color, piece_position):
6
"""
7
board: board object
8
piece_color: color of the piece
9
piece_position: position code of the piece
10
"""
11
super().__init__(board, piece_color, piece_position)
12
13
def get_moves(self):
14
15 """
16 Get all possible moves of the piece
17 """
18
19 valid_moves_bishop = []
20 x = ord(self.piece_position[0])
21 y = int(self.piece_position[1])
22
23 if self.piece_color == "white":
24 # up left loop
25 new_x = x
26 new_y = y
27 while True:
28 new_x = new_x - 1
29 new_y = new_y + 1
30 new_pos = f"{chr(new_x)}{new_y}"
31 if new_pos not in pos_tuple:
32 break
33 piece_at_new_position = self.board.position_dict[new_pos].piece
34 if piece_at_new_position is None:
35 valid_moves_bishop.append(new_pos)
36 continue
37 if piece_at_new_position.piece_color == "black" and type(piece_at_new_position) != King:
38 valid_moves_bishop.append(new_pos)
39 break
40
41 # up right loop
42 new_x = x
43 new_y = y
44 while True:
45 new_x = new_x + 1
46 new_y = new_y + 1
47 new_pos = f"{chr(new_x)}{new_y}"
48 if new_pos not in pos_tuple:
49 break
50 piece_at_new_position = self.board.position_dict[new_pos].piece
51 if piece_at_new_position is None:
52 valid_moves_bishop.append(new_pos)
53 continue
54
if piece_at_new_position.piece_color == "black" and type(piece_at_new_position) != King:
55
valid_moves_bishop.append(new_pos)
56
break
57
58
# down right loop
59
new_x = x
60
61
new_y = y 18
while True:
62
classes/pieces/bishop.py
63 new_x = new_x + 1
64 new_y = new_y - 1
65 new_pos = f"{chr(new_x)}{new_y}"
66 if new_pos not in pos_tuple:
67 break
68 piece_at_new_position = self.board.position_dict[new_pos].piece
69 if piece_at_new_position is None:
70 valid_moves_bishop.append(new_pos)
71 continue
72 if piece_at_new_position.piece_color == "black" and type(piece_at_new_position) != King:
73 valid_moves_bishop.append(new_pos)
74 break
75
76 # down left loop
77 new_x = x
78 new_y = y
79 while True:
80
new_x = new_x - 1
81
new_y = new_y -1
82
new_pos = f"{chr(new_x)}{new_y}"
83
if new_pos not in pos_tuple:
84
break
85
piece_at_new_position = self.board.position_dict[new_pos].piece
86
if piece_at_new_position is None:
87
88 valid_moves_bishop.append(new_pos)
89 continue
90 if piece_at_new_position.piece_color == "black" and type(piece_at_new_position) != King:
91 valid_moves_bishop.append(new_pos)
92 break
93
94 if self.piece_color == "black":
95 # up left loop
96 new_x = x
97 new_y = y
98 while True:
99 new_x = new_x - 1
100 new_y = new_y - 1
101 new_pos = f"{chr(new_x)}{new_y}"
102 if new_pos not in pos_tuple:
103 break
104 piece_at_new_position = self.board.position_dict[new_pos].piece
105 if piece_at_new_position is None:
106 valid_moves_bishop.append(new_pos)
107 continue
108 if piece_at_new_position.piece_color == "white" and type(piece_at_new_position) != King:
109 valid_moves_bishop.append(new_pos)
110 break
111
112 # up right loop
113 new_x = x
114 new_y = y
115 while True:
116 new_x = new_x + 1
117 new_y = new_y - 1
118 new_pos = f"{chr(new_x)}{new_y}"
119 if new_pos not in pos_tuple:
120
break
121
piece_at_new_position = self.board.position_dict[new_pos].piece
122
if piece_at_new_position is None:
123
valid_moves_bishop.append(new_pos)
124
continue
125
126 if piece_at_new_position.piece_color == "white" and type(piece_at_new_position) != King:
127 valid_moves_bishop.append(new_pos)
128 break 19
classes/pieces/bishop.py
129 # down right loop
130 new_x = x
131 new_y = y
132 while True:
133 new_x = new_x + 1
134 new_y = new_y + 1
135 new_pos = f"{chr(new_x)}{new_y}"
136 if new_pos not in pos_tuple:
137 break
138 piece_at_new_position = self.board.position_dict[new_pos].piece
139 if piece_at_new_position is None:
140 valid_moves_bishop.append(new_pos)
141 continue
142 if piece_at_new_position.piece_color == "white" and type(piece_at_new_position) != King:
143 valid_moves_bishop.append(new_pos)
144 break
145
146
# down left loop
147
new_x = x
148
new_y = y
149
while True:
150
new_x = new_x - 1
151
new_y = new_y + 1
152
new_pos = f"{chr(new_x)}{new_y}"
153
if new_pos not in pos_tuple:
154
break
155
156 piece_at_new_position = self.board.position_dict[new_pos].piece
157 if piece_at_new_position is None:
158 valid_moves_bishop.append(new_pos)
159 continue
160 if piece_at_new_position.piece_color == "white" and type(piece_at_new_position) != King:
161 valid_moves_bishop.append(new_pos)
162 break
163
164 # Select same color king
165 for pos in pos_tuple:
166 position = self.board.position_dict[pos]
167 if position.piece is not None and type(position.piece) == King and position.piece.piece_color == self.piece_color:
168 my_king = position.piece
169 break
170
171 # If king is in check, allow only those moves which prevent the check
172 if my_king.is_in_check():
173 # Play every valid move and see if king is still in check.
174 # If king remains in check, then that valid move is removed
175 new_valid_moves_bishop = []
176 initial_position = self.piece_position
177 for final_position in valid_moves_bishop:
178 piece_already_at_final_position = self.board.position_dict[final_position].piece
179 self.forced_move(final_position)
180 if not my_king.is_in_check():
181 new_valid_moves_bishop.append(final_position)
182 self.forced_move(initial_position)
183 self.board.position_dict[final_position].piece = piece_already_at_final_position
184 return new_valid_moves_bishop
185
186 return valid_moves_bishop
187
188 def get_invalid_moves_for_opposite_king(self):
189
"""
190
Get the moves where opposite color king cannot move
191
"""
192
193
194
invalid_moves_for_king = [] 20
x = ord(self.piece_position[0])
classes/pieces/bishop.py
195 y = int(self.piece_position[1])
196
197 # Includes every possible move of the piece
198 # If it encounters a piece loop terminates , unless ->
199 # If it encounters a opposite color king , then it continues to get invalid moves for opposite king
200
201 if self.piece_color == "white":
202 # up left loop
203 new_x = x
204 new_y = y
205 while True:
206 new_x = new_x - 1
207 new_y = new_y + 1
208 new_pos = f"{chr(new_x)}{new_y}"
209 if new_pos not in pos_tuple:
210 break
211 invalid_moves_for_king.append(new_pos)
212 piece_at_new_position = self.board.position_dict[new_pos].piece
213 if piece_at_new_position is not None :
214 if type(piece_at_new_position) == King:
215 if piece_at_new_position.piece_color == "black":
216
continue
217
break
218
break
219
220
221 # up right loop
222 new_x = x
223 new_y = y
224 while True:
225 new_x = new_x + 1
226 new_y = new_y + 1
227 new_pos = f"{chr(new_x)}{new_y}"
228 if new_pos not in pos_tuple:
229 break
230 invalid_moves_for_king.append(new_pos)
231 piece_at_new_position = self.board.position_dict[new_pos].piece
232 if piece_at_new_position is not None:
233 if type(piece_at_new_position) == King:
234 if piece_at_new_position.piece_color == "black":
235 continue
236 break
237 break
238 # down right loop
239 new_x = x
240 new_y = y
241 while True:
242 new_x = new_x + 1
243 new_y = new_y - 1
244 new_pos = f"{chr(new_x)}{new_y}"
245 if new_pos not in pos_tuple:
246 break
247 invalid_moves_for_king.append(new_pos)
248 piece_at_new_position = self.board.position_dict[new_pos].piece
249 if piece_at_new_position is not None :
250
if type(piece_at_new_position) == King:
251
if piece_at_new_position.piece_color == "black":
252
continue
253
254 break
255 break
256
257 # down left loop
258 new_x = x
259 new_y = y
260 while True: 21
new_x = new_x - 1
classes/pieces/bishop.py
261 new_y = new_y -1
262 new_pos = f"{chr(new_x)}{new_y}"
263 if new_pos not in pos_tuple:
264 break
265 invalid_moves_for_king.append(new_pos)
266 piece_at_new_position = self.board.position_dict[new_pos].piece
267 if piece_at_new_position is not None :
268 if type(piece_at_new_position) == King:
269 if piece_at_new_position.piece_color == "black":
270 continue
271 break
272
break
273
274
if self.piece_color == "black":
275
# up left loop
276
new_x = x
277
new_y = y
278
while True:
279
280 new_x = new_x - 1
281 new_y = new_y - 1
282 new_pos = f"{chr(new_x)}{new_y}"
283 if new_pos not in pos_tuple:
284 break
285 invalid_moves_for_king.append(new_pos)
286 piece_at_new_position = self.board.position_dict[new_pos].piece
287 if piece_at_new_position is not None :
288 if type(piece_at_new_position) == King:
289 if piece_at_new_position.piece_color == "white":
290 continue
291 break
292 break
293 # up right loop
294 new_x = x
295 new_y = y
296 while True:
297 new_x = new_x + 1
298 new_y = new_y - 1
299 new_pos = f"{chr(new_x)}{new_y}"
300 if new_pos not in pos_tuple:
301 break
302 invalid_moves_for_king.append(new_pos)
303 piece_at_new_position = self.board.position_dict[new_pos].piece
304 if piece_at_new_position is not None :
305 if type(piece_at_new_position) == King:
306
if piece_at_new_position.piece_color == "white":
307
continue
308
break
309
310 break
311 # down right loop
312 new_x = x
313 new_y = y
314 while True:
315 new_x = new_x + 1
316 new_y = new_y + 1
317 new_pos = f"{chr(new_x)}{new_y}"
318 if new_pos not in pos_tuple:
319 break
320 invalid_moves_for_king.append(new_pos)
321 piece_at_new_position = self.board.position_dict[new_pos].piece
322 if piece_at_new_position is not None:
323 if type(piece_at_new_position) == King:
324 if piece_at_new_position.piece_color == "white":
325 continue
326
22
break
classes/pieces/bishop.py
327 break
328
329 # down left loop
330 new_x = x
331 new_y = y
332 while True:
333 new_x = new_x - 1
334 new_y = new_y + 1
335 new_pos = f"{chr(new_x)}{new_y}"
336 if new_pos not in pos_tuple:
337 break
338 invalid_moves_for_king.append(new_pos)
339 piece_at_new_position = self.board.position_dict[new_pos].piece
340 if piece_at_new_position is not None :
341 if type(piece_at_new_position) == King:
342 if piece_at_new_position.piece_color == "white":
343
continue
344
break
345
break
346
347
return invalid_moves_for_king

def __str__(self):
return f"{self.piece_color[0]}b"

23
classes/pieces/king.py

from ..vars import pos_tuple


from ..piece import Piece
1
2 class King(Piece):
3 """
4 Creates a king object for given board, with given piece color and piece position
5 """
6 def __init__(self, board, piece_color, piece_position):
7 """
8 board: board object
9 piece_color: color of the piece
10 piece_position: position code of the piece
11 """
12 super().__init__(board, piece_color, piece_position)
13
14 def get_moves(self):
15 """
16 Get all possible moves of the piece
17 """
18
19 valid_moves_king = []
20 x = ord(self.piece_position[0])
21 y = int(self.piece_position[1])
22
23 if self.piece_color == "white":
24 left = f"{chr(x-1)}{y}"
25 right = f"{chr(x+1)}{y}"
26 up = f"{chr(x)}{y+1}"
27 down = f"{chr(x)}{y-1}"
28 up_left = f"{chr(x-1)}{y+1}"
29 up_right = f"{chr(x+1)}{y+1}"
30 down_left = f"{chr(x-1)}{y-1}"
31 down_right = f"{chr(x+1)}{y-1}"
32
33 invalid_moves = []
34 for pos in pos_tuple:
35 piece_at_pos = self.board.position_dict[pos].piece
36 if piece_at_pos is None:
37 continue
38 elif piece_at_pos.piece_color == "black":
39 invalid_moves.extend(piece_at_pos.get_invalid_moves_for_opposite_king())
40 if left in pos_tuple and left not in invalid_moves:
41 l = self.board.position_dict[left]
42 if l.piece is None or l.piece.piece_color == "black":
43 valid_moves_king.append(left)
44
45 if right in pos_tuple and right not in invalid_moves:
46 r = self.board.position_dict[right]
47 if r.piece is None or r.piece.piece_color == "black":
48 valid_moves_king.append(right)
49
50 if up in pos_tuple and up not in invalid_moves:
51
u = self.board.position_dict[up]
52
if u.piece is None or u.piece.piece_color == "black":
53
valid_moves_king.append(up)
54
55
if down in pos_tuple and down not in invalid_moves:
56
d = self.board.position_dict[down]
57
if d.piece is None or d.piece.piece_color == "black":
58
59 valid_moves_king.append(down)
60
61 if up_left in pos_tuple and up_left not in invalid_moves:
62 ul = self.board.position_dict[up_left] 24
63 if ul.piece is None or ul.piece.piece_color == "black":
classes/pieces/king.py
64 valid_moves_king.append(up_left)
65
66 if up_right in pos_tuple and up_right not in invalid_moves:
67 ur = self.board.position_dict[up_right]
68 if ur.piece is None or ur.piece.piece_color == "black":
69 valid_moves_king.append(up_right)
70
71 if down_left in pos_tuple and down_left not in invalid_moves:
72 dl = self.board.position_dict[down_left]
73 if dl.piece is None or dl.piece.piece_color == "black":
74 valid_moves_king.append(down_left)
75
76 if down_right in pos_tuple and down_right not in invalid_moves:
77 dr = self.board.position_dict[down_right]
78 if dr.piece is None or dr.piece.piece_color == "black":
79 valid_moves_king.append(down_right)
80
81 if self.piece_color == "black":
82
left = f"{chr(x-1)}{y}"
83
right = f"{chr(x+1)}{y}"
84
up = f"{chr(x)}{y-1}"
85
down = f"{chr(x)}{y+1}"
86
up_left = f"{chr(x-1)}{y-1}"
87
up_right = f"{chr(x+1)}{y-1}"
88
down_left = f"{chr(x-1)}{y+1}"
89
down_right = f"{chr(x+1)}{y+1}"
90
91
invalid_moves = []
92
for pos in pos_tuple:
93
piece_at_pos = self.board.position_dict[pos].piece
94
if piece_at_pos is None:
95
continue
96
97 if piece_at_pos.piece_color == "white":
98 invalid_moves.extend(piece_at_pos.get_invalid_moves_for_opposite_king())
99
100 if left in pos_tuple and left not in invalid_moves:
101 l = self.board.position_dict[left]
102 if l.piece is None or l.piece.piece_color == "white":
103 valid_moves_king.append(left)
104
105 if right in pos_tuple and right not in invalid_moves:
106 r = self.board.position_dict[right]
107 if r.piece is None or r.piece.piece_color == "white":
108 valid_moves_king.append(right)
109
110 if up in pos_tuple and up not in invalid_moves:
111 u = self.board.position_dict[up]
112 if u.piece is None or u.piece.piece_color == "white":
113 valid_moves_king.append(up)
114
115 if down in pos_tuple and down not in invalid_moves:
116 d = self.board.position_dict[down]
117 if d.piece is None or d.piece.piece_color == "white":
118 valid_moves_king.append(down)
119
120 if up_left in pos_tuple and up_left not in invalid_moves:
121 ul = self.board.position_dict[up_left]
122 if ul.piece is None or ul.piece.piece_color == "white":
123 valid_moves_king.append(up_left)
124
125 if up_right in pos_tuple and up_right not in invalid_moves:
126 ur = self.board.position_dict[up_right]
127 if ur.piece is None or ur.piece.piece_color == "white":
128
129
valid_moves_king.append(up_right) 25
classes/pieces/king.py
130 if down_left in pos_tuple and down_left not in invalid_moves:
131 dl = self.board.position_dict[down_left]
132 if dl.piece is None or dl.piece.piece_color == "white":
133 valid_moves_king.append(down_left)
134
135 if down_right in pos_tuple and down_right not in invalid_moves:
136 dr = self.board.position_dict[down_right]
137 if dr.piece is None or dr.piece.piece_color == "white":
138 valid_moves_king.append(down_right)
139
140 return valid_moves_king
141
142 def get_invalid_moves_for_opposite_king(self):
143 """
144 Get the moves where opposite color king cannot move
145 """
146
147 invalid_moves_for_king = []
148 x = ord(self.piece_position[0])
149 y = int(self.piece_position[1])
150
151 if self.piece_color == "white":
152
left = f"{chr(x-1)}{y}"
153
right = f"{chr(x+1)}{y}"
154
up = f"{chr(x)}{y-1}"
155
down = f"{chr(x)}{y+1}"
156
up_left = f"{chr(x-1)}{y-1}"
157
up_right = f"{chr(x+1)}{y-1}"
158
down_left = f"{chr(x-1)}{y+1}"
159
down_right = f"{chr(x+1)}{y+1}"
160
elif self.piece_color == "black":
161
left = f"{chr(x-1)}{y}"
162
right = f"{chr(x+1)}{y}"
163
up = f"{chr(x)}{y-1}"
164
down = f"{chr(x)}{y+1}"
165
up_left = f"{chr(x-1)}{y-1}"
166
up_right = f"{chr(x+1)}{y-1}"
167
down_left = f"{chr(x-1)}{y+1}"
168
down_right = f"{chr(x+1)}{y+1}"
169
170
if left in pos_tuple:
171
invalid_moves_for_king.append(left)
172
if right in pos_tuple:
173
174 invalid_moves_for_king.append(right)
175 if up in pos_tuple:
176 invalid_moves_for_king.append(up)
177 if down in pos_tuple:
178 invalid_moves_for_king.append(down)
179 if up_left in pos_tuple:
180 invalid_moves_for_king.append(up_left)
181 if up_right in pos_tuple:
182 invalid_moves_for_king.append(up_right)
183 if down_left in pos_tuple:
184 invalid_moves_for_king.append(down_left)
185 if down_right in pos_tuple:
186 invalid_moves_for_king.append(down_right)
187
188 return invalid_moves_for_king
189
190 def is_in_check(self):
191 """
192 Returns True if the king is in check or False
193 """
194
195
26
in_check = False
classes/pieces/king.py
196
197 # Iterate through every position, if the king's position is included
198 # in return value of get_invalid_moves_for_opposite_king() of any of the opposite color
199 # piece, set in_check to True
200 if self.piece_color == "white":
201 for pos in pos_tuple:
202 position = self.board.position_dict[pos]
203 if position.piece is not None and position.piece.piece_color == "black":
204 invalid_moves = position.piece.get_invalid_moves_for_opposite_king()
205 if self.piece_position in invalid_moves:
206 in_check = True
207 break
208
209 if self.piece_color == "black":
210 for pos in pos_tuple:
211
position = self.board.position_dict[pos]
212
if position.piece is not None and position.piece.piece_color == "white":
213
invalid_moves = position.piece.get_invalid_moves_for_opposite_king()
214
if self.piece_position in invalid_moves:
215
in_check = True
216
break
217
218
219 return in_check
220
221 def is_in_mate(self):
222 """
223 Returns True if king is in mate else False
224 """
225
226
227 # Check if king is in check
228 if not self.is_in_check():
229 return False
230
231 # Check if king can move to get out of check
232 if self.get_moves() != []:
233 return False
234
235 in_mate = True
236
237 # Iterate through every position, if a move of a same colored piece
238 # is found such that it removes the king from check, set in_mate to False
239 if self.piece_color == "white":
240 for pos in pos_tuple:
241 position = self.board.position_dict[pos] # position object of the positoin 'pos'
242 # If there is no piece on the position or the piece is of opposite color, continue
243 if position.piece is None or position.piece.piece_color == "black":
244 continue
245 # Get the moves of the piece on the position
246 piece_moves = position.piece.get_moves()
247 # Save the original position of the piece
248 initial_position = position.piece.piece_position
249 # Iterate through all the moves of the piece
250 # Play them one by one and check if king is still under check
251 for final_position in piece_moves:
252 # Forcecully move the piece to final_position
253 position.piece.forced_move(final_position)
254 # If after moving the piece, the king is no longer in check
255 # set in_mate = False
256 # Else undo the move made by the piece and move on to the
257 # next move of the piece
258 if not self.is_in_check():
259 in_mate = False
260
261
break 27
else:
classes/pieces/king.py
262 # Take the new position of the piece
263 new_position = self.board.position_dict[final_position]
264 # Move the piece from new_position to initial_position
265 new_position.piece.forced_move(initial_position)
266 # If the king is not in mate, break the loop
267 if not in_mate:
268 break
269
270 if self.piece_color == "black":
271 for pos in pos_tuple:
272 position = self.board.position_dict[pos]
273 if position.piece is None or position.piece.piece_color == "white":
274 continue
275 piece_moves = position.piece.get_moves()
276 initial_position = position.piece.piece_position
277 for final_position in piece_moves:
278
position.piece.forced_move(final_position)
279
if not self.is_in_check():
280
281
in_mate = False
282
break
283
else:
284
285 new_position = self.board.position_dict[final_position]
286 new_position.piece.forced_move(initial_position)
287 if not in_mate:
288 break
289
290 return in_mate

def __str__(self):
return f"{self.piece_color[0]}k"

28
classes/pieces/knight.py

from ..vars import pos_tuple


from ..piece import Piece
1 from .king import King
2
3 class Knight(Piece):
4 """
5 Creates a knight object for given board, with given piece color and piece position
6 """
7 def __init__(self, board, piece_color, piece_position):
8 """
9 board: board object
10 piece_color: color of the piece
11 piece_position: position code of the piece
12 """
13 super().__init__(board, piece_color, piece_position)
14
15 def get_moves(self):
16
"""
17
Get all possible moves of the piece
18
"""
19
20
valid_moves_knight = []
21
x = ord(self.piece_position[0])
22
y = int(self.piece_position[1])
23
if self.piece_color == "white":
24
up_left = f"{chr(x-1)}{y+2}"
25
up_right = f"{chr(x+1)}{y+2}"
26
left_up = f"{chr(x-2)}{y+1}"
27
right_up = f"{chr(x+2)}{y+1}"
28
29
down_left = f"{chr(x-1)}{y-2}"
30
down_right = f"{chr(x+1)}{y-2}"
31
left_down = f"{chr(x-2)}{y-1}"
32
right_down = f"{chr(x+2)}{y-1}"
33
34
if up_left in pos_tuple:
35
ul = self.board.position_dict[up_left]
36
if ul.piece is None or ul.piece.piece_color == "black" and type(ul.piece) != King :
37
38 valid_moves_knight.append(up_left)
39
40 if up_right in pos_tuple:
41 ur = self.board.position_dict[up_right]
42 if ur.piece is None or ur.piece.piece_color == "black" and type(ur.piece) != King :
43 valid_moves_knight.append(up_right)
44
45 if left_up in pos_tuple:
46 lu = self.board.position_dict[left_up]
47 if lu.piece is None or lu.piece.piece_color == "black" and type(lu.piece) != King:
48 valid_moves_knight.append(left_up)
49
50 if right_up in pos_tuple:
51 ru = self.board.position_dict[right_up]
52 if ru.piece is None or ru.piece.piece_color == "black" and type(ru.piece) != King :
53 valid_moves_knight.append(right_up)
54
55 if down_left in pos_tuple:
56 dl = self.board.position_dict[down_left]
57 if dl.piece is None or dl.piece.piece_color == "black" and type(dl.piece) != King:
58 valid_moves_knight.append(down_left)
59
60 if down_right in pos_tuple:
61 dr = self.board.position_dict[down_right]
62 if dr.piece is None or dr.piece.piece_color == "black" and type(dr.piece) != King:
63 29
valid_moves_knight.append(down_right)
classes/pieces/knight.py
64
65 if left_down in pos_tuple:
66 ld = self.board.position_dict[left_down]
67 if ld.piece is None or ld.piece.piece_color == "black" and type(ld.piece) != King:
68 valid_moves_knight.append(left_down)
69
70 if right_down in pos_tuple:
71 rd = self.board.position_dict[right_down]
72 if rd.piece is None or rd.piece.piece_color == "black" and type(rd.piece) != King:
73 valid_moves_knight.append(right_down)
74
75 if self.piece_color == "black":
76 up_left = f"{chr(x-1)}{y-2}"
77 up_right = f"{chr(x+1)}{y-2}"
78 left_up = f"{chr(x-2)}{y-1}"
79 right_up = f"{chr(x+2)}{y-1}"
80
81 down_left = f"{chr(x-1)}{y+2}"
82 down_right = f"{chr(x+1)}{y+2}"
83 left_down = f"{chr(x-2)}{y+1}"
84 right_down = f"{chr(x+2)}{y+1}"
85
86 if up_left in pos_tuple:
87 ul = self.board.position_dict[up_left]
88 if ul.piece is None or ul.piece.piece_color == "white" and type(ul.piece) != King:
89
valid_moves_knight.append(up_left)
90
91
if up_right in pos_tuple:
92
ur = self.board.position_dict[up_right]
93
if ur.piece is None or ur.piece.piece_color == "white" and type(ur.piece) != King:
94
valid_moves_knight.append(up_right)
95
96
if left_up in pos_tuple:
97
98 lu = self.board.position_dict[left_up]
99 if lu.piece is None or lu.piece.piece_color == "white" and type(lu.piece) != King:
100 valid_moves_knight.append(left_up)
101
102 if right_up in pos_tuple:
103 ru = self.board.position_dict[right_up]
104 if ru.piece is None or ru.piece.piece_color == "white" and type(ru.piece) != King:
105 valid_moves_knight.append(right_up)
106
107 if down_left in pos_tuple:
108 dl = self.board.position_dict[down_left]
109 if dl.piece is None or dl.piece.piece_color == "white" and type(dl.piece) != King:
110 valid_moves_knight.append(down_left)
111
112 if down_right in pos_tuple:
113 dr = self.board.position_dict[down_right]
114 if dr.piece is None or dr.piece.piece_color == "white" and type(dr.piece) != King:
115 valid_moves_knight.append(down_right)
116
117 if left_down in pos_tuple:
118 ld = self.board.position_dict[left_down]
119 if ld.piece is None or ld.piece.piece_color == "white" and type(ld.piece) != King:
120 valid_moves_knight.append(left_down)
121
122 if right_down in pos_tuple:
123 rd = self.board.position_dict[right_down]
124 if rd.piece is None or rd.piece.piece_color == "white" and type(rd.piece) != King:
125 valid_moves_knight.append(right_down)
126
127 # Select same color king
128
129
for pos in pos_tuple: 30
position = self.board.position_dict[pos]
classes/pieces/knight.py
130 if position.piece is not None and type(position.piece) == King and position.piece.piece_color == self.piece_color:
131 my_king = position.piece
132 break
133
134 # If king is in check, allow only those moves which prevent the check
135 if my_king.is_in_check():
136 # Play every valid move and see if king is still in check.
137 # If king remains in check, then that valid move is removed
138 new_valid_moves_knight = []
139 initial_position = self.piece_position
140 for final_position in valid_moves_knight:
141 piece_already_at_final_position = self.board.position_dict[final_position].piece
142 self.forced_move(final_position)
143 if not my_king.is_in_check():
144 new_valid_moves_knight.append(final_position)
145 self.forced_move(initial_position)
146 self.board.position_dict[final_position].piece = piece_already_at_final_position
147 return new_valid_moves_knight
148
149 return valid_moves_knight
150
151
def get_invalid_moves_for_opposite_king(self):
152
"""
153
Get the moves where opposite color king cannot move
154
"""
155
156
invalid_moves_for_king = []
157
x = ord(self.piece_position[0])
158
y = int(self.piece_position[1])
159
160
# Includes every possible move of the piece
161
# If it encounters a piece loop terminates , unless ->
162
# If it encounters a opposite color king , then it continues to get invalid moves for opposite king
163
164
if self.piece_color == "white":
165
up_left = f"{chr(x-1)}{y+2}"
166
up_right = f"{chr(x+1)}{y+2}"
167
left_up = f"{chr(x-2)}{y+1}"
168
right_up = f"{chr(x+2)}{y+1}"
169
170
down_left = f"{chr(x-1)}{y-2}"
171
down_right = f"{chr(x+1)}{y-2}"
172
left_down = f"{chr(x-2)}{y-1}"
173
right_down = f"{chr(x+2)}{y-1}"
174
175
if up_left in pos_tuple:
176
177 invalid_moves_for_king.append(up_left)
178 if up_right in pos_tuple:
179 invalid_moves_for_king.append(up_right)
180 if left_up in pos_tuple:
181 invalid_moves_for_king.append(left_up)
182 if right_up in pos_tuple:
183 invalid_moves_for_king.append(right_up)
184
185 if down_left in pos_tuple:
186 invalid_moves_for_king.append(down_left)
187 if down_right in pos_tuple:
188 invalid_moves_for_king.append(down_right)
189 if left_down in pos_tuple:
190 invalid_moves_for_king.append(left_down)
191 if right_down in pos_tuple:
192 invalid_moves_for_king.append(right_down)
193
194 if self.piece_color == "black":
195
31
classes/pieces/knight.py
196 up_left = f"{chr(x-1)}{y-2}"
197 up_right = f"{chr(x+1)}{y-2}"
198 left_up = f"{chr(x-2)}{y-1}"
199 right_up = f"{chr(x+2)}{y-1}"
200
201 down_left = f"{chr(x-1)}{y+2}"
202 down_right = f"{chr(x+1)}{y+2}"
203 left_down = f"{chr(x-2)}{y+1}"
204 right_down = f"{chr(x+2)}{y+1}"
205
206 if up_left in pos_tuple:
207 invalid_moves_for_king.append(up_left)
208 if up_right in pos_tuple:
209 invalid_moves_for_king.append(up_right)
210 if left_up in pos_tuple:
211 invalid_moves_for_king.append(left_up)
212 if right_up in pos_tuple:
213 invalid_moves_for_king.append(right_up)
214
215 if down_left in pos_tuple:
216 invalid_moves_for_king.append(down_left)
217 if down_right in pos_tuple:
218 invalid_moves_for_king.append(down_right)
219 if left_down in pos_tuple:
220
invalid_moves_for_king.append(left_down)
221
if right_down in pos_tuple:
222
invalid_moves_for_king.append(right_down)
223
224
return invalid_moves_for_king
225
226
def __str__(self):
return f"{self.piece_color[0]}h"

32
classes/pieces/pawn.py

from ..vars import pos_tuple


1 from ..piece import Piece
2 from .king import King
3
4 class Pawn(Piece):
5 """
6 Creates a pawn object for given board, with given piece color and piece position
7 """
8
9 def __init__(self, board, piece_color, piece_position):
10 """
11 board: board object
12 piece_color: color of the piece
13 piece_position: position code of the piece
14 """
15
16 super().__init__(board, piece_color, piece_position)
17
18
19 def get_moves(self):
20 """
21 Get all possible moves of the piece
22 """
23
24 valid_moves_pawn = []
25 x = ord(self.piece_position[0])
26 y = int(self.piece_position[1])
27
28 if self.piece_color == "white":
29
30 front_position = f"{chr(x)}{y+1}"
31 left_diagonal_position = f"{chr(x-1)}{y+1}"
32 right_diagonal_position = f"{chr(x+1)}{y+1}"
33
34 if front_position in pos_tuple:
35 fp = self.board.position_dict[front_position]
36 if fp.piece is None:
37 valid_moves_pawn.append(front_position)
38
39 if left_diagonal_position in pos_tuple:
40 ldp = self.board.position_dict[left_diagonal_position]
41 if ldp.piece is not None and ldp.piece.piece_color == "black" and type(ldp.piece) != King:
42 valid_moves_pawn.append(left_diagonal_position)
43
44 if right_diagonal_position in pos_tuple:
45
rdp = self.board.position_dict[right_diagonal_position]
46
if rdp.piece is not None and rdp.piece.piece_color == "black" and type(rdp.piece) != King:
47
valid_moves_pawn.append(right_diagonal_position)
48
49
# Allows two step front move to the pawn for its 1st move
50
if y == 2:
51
fp = self.board.position_dict[front_position]
52
if fp.piece is None:
53
54 fmp = self.board.position_dict[f"{chr(x)}{y + 2}"]
55 if fmp.piece is None and type(fp.piece != King):
56 valid_moves_pawn.append(f"{chr(x)}{y + 2}")
57
58 elif self.piece_color == "black":
59 front_position = f"{chr(x)}{y-1}"
60 left_diagonal_position = f"{chr(x-1)}{y-1}"
61 right_diagonal_position = f"{chr(x+1)}{y-1}"
62
if front_position in pos_tuple:
63 33
64 fp = self.board.position_dict[front_position]
classes/pieces/pawn.py
65 if fp.piece is None:
66 valid_moves_pawn.append(front_position)
67
68 if left_diagonal_position in pos_tuple:
69 ldp = self.board.position_dict[left_diagonal_position]
70 if ldp.piece is not None and ldp.piece.piece_color == "white" and type(ldp.piece) != King:
71 valid_moves_pawn.append(left_diagonal_position)
72
73 if right_diagonal_position in pos_tuple:
74 rdp = self.board.position_dict[right_diagonal_position]
75 if rdp.piece is not None and rdp.piece.piece_color == "white" and type(rdp.piece) != King:
76 valid_moves_pawn.append(right_diagonal_position)
77
78 # Allows two step front move to the pawn for its 1st move
79 if y == 7:
80 fp = self.board.position_dict[front_position]
81 if fp.piece is None:
82
fmp = self.board.position_dict[f"{chr(x)}{y - 2}"]
83
if fmp.piece is None:
84
valid_moves_pawn.append(f"{chr(x)}{y - 2}")
85
86
# Select same color king
87
for pos in pos_tuple:
88
position = self.board.position_dict[pos]
89
if position.piece is not None and type(position.piece) == King and position.piece.piece_color == self.piece_color:
90
91 my_king = position.piece
92 break
93
94 # If king is in check, allow only those moves which prevent the check
95 if my_king.is_in_check():
96 # Play every valid move and see if king is still in check.
97 # If king remains in check, then that valid move is removed
98 new_valid_moves_pawn = []
99 initial_position = self.piece_position
100 for final_position in valid_moves_pawn:
101 piece_already_at_final_position = self.board.position_dict[final_position].piece
102 self.forced_move(final_position)
103 if not my_king.is_in_check():
104 new_valid_moves_pawn.append(final_position)
105 self.forced_move(initial_position)
106 self.board.position_dict[final_position].piece = piece_already_at_final_position
107 return new_valid_moves_pawn
108
109 return valid_moves_pawn
110
111 def get_invalid_moves_for_opposite_king(self):
112 """
113 Get the moves where opposite color king cannot move
114 """
115
116 invalid_moves_for_king = []
117 x = ord(self.piece_position[0])
118 y = int(self.piece_position[1])
119
120 # Includes every possible move of the piece
121 # If it encounters a piece loop terminates , unless ->
122 # If it encounters a opposite color king , then it continues to get invalid moves for opposite king
123
124 if self.piece_color == "white":
125 left_diagonal_position = f"{chr(x-1)}{y+1}"
126 right_diagonal_position = f"{chr(x+1)}{y+1}"
127
128 if self.piece_color == "black":
129 left_diagonal_position = f"{chr(x-1)}{y-1}"
130
34
right_diagonal_position = f"{chr(x+1)}{y-1}"
classes/pieces/pawn.py
131
132 if left_diagonal_position in pos_tuple:
133 invalid_moves_for_king.append(left_diagonal_position)
134 if right_diagonal_position in pos_tuple:
135 invalid_moves_for_king.append(right_diagonal_position)
136
137 return invalid_moves_for_king
138
139 def __str__(self):
return f"{self.piece_color[0]}p"

35
classes/pieces/queen.py

from ..vars import pos_tuple


from ..piece import Piece
from .king import King

class Queen(Piece):
"""
Creates a queen object for given board, with given piece color and piece position
1 """
2 def __init__(self, board, piece_color, piece_position):
3 """
4 board: board object
5 piece_color: color of the piece
6 piece_position: position code of the piece
7 """
8 super().__init__(board, piece_color, piece_position)
9
10 def get_moves(self):
11 valid_moves_queen = []
12 x = ord(self.piece_position[0])
13 y = int(self.piece_position[1])
14
15 if self.piece_color == "white":
16
# up left loop
17
new_x = x
18
new_y = y
19
while True:
20
new_x = new_x - 1
21
new_y = new_y + 1
22
new_pos = f"{chr(new_x)}{new_y}"
23
if new_pos not in pos_tuple:
24
break
25
26 piece_at_new_position = self.board.position_dict[new_pos].piece
27 if piece_at_new_position is None:
28 valid_moves_queen.append(new_pos)
29 continue
30 if piece_at_new_position.piece_color == "black" and type(piece_at_new_position) != King:
31 valid_moves_queen.append(new_pos)
32 break
33 # up right loop
34 new_x = x
35 new_y = y
36 while True:
37 new_x = new_x + 1
38 new_y = new_y + 1
39 new_pos = f"{chr(new_x)}{new_y}"
40 if new_pos not in pos_tuple:
41 break
42 piece_at_new_position = self.board.position_dict[new_pos].piece
43 if piece_at_new_position is None:
44 valid_moves_queen.append(new_pos)
45 continue
46 if piece_at_new_position.piece_color == "black" and type(piece_at_new_position) != King:
47 valid_moves_queen.append(new_pos)
48 break
49 #down right loop
50 new_x = x
51 new_y = y
52 while True:
53 new_x = new_x + 1
54 new_y = new_y - 1
55 new_pos = f"{chr(new_x)}{new_y}"
56 if new_pos not in pos_tuple:
57
58
break 36
piece_at_new_position = self.board.position_dict[new_pos].piece
classes/pieces/queen.py
59 if piece_at_new_position is None:
60 valid_moves_queen.append(new_pos)
61 continue
62 if piece_at_new_position.piece_color == "black" and type(piece_at_new_position) != King:
63 valid_moves_queen.append(new_pos)
64 break
65 #down left loop
66 new_x = x
67 new_y = y
68 while True:
69 new_x = new_x - 1
70 new_y = new_y -1
71 new_pos = f"{chr(new_x)}{new_y}"
72 if new_pos not in pos_tuple:
73 break
74
piece_at_new_position = self.board.position_dict[new_pos].piece
75
if piece_at_new_position is None:
76
valid_moves_queen.append(new_pos)
77
continue
78
if piece_at_new_position.piece_color == "black" and type(piece_at_new_position) != King:
79
80 valid_moves_queen.append(new_pos)
81 break
82
83 #up loop
84 new_x = x
85 new_y = y
86 while True:
87 new_x = new_x
88 new_y = new_y + 1
89 new_pos = f"{chr(new_x)}{new_y}"
90 if new_pos not in pos_tuple:
91 break
92 piece_at_new_position = self.board.position_dict[new_pos].piece
93 if piece_at_new_position is None:
94 valid_moves_queen.append(new_pos)
95 continue
96 if piece_at_new_position.piece_color == "black" and type(piece_at_new_position) != King:
97 valid_moves_queen.append(new_pos)
98 break
99
100 #down loop
101 new_x = x
102 new_y = y
103 while True:
104 new_x = new_x
105 new_y = new_y + 1
106 new_pos = f"{chr(new_x)}{new_y}"
107 if new_pos not in pos_tuple:
108 break
109 piece_at_new_position = self.board.position_dict[new_pos].piece
110 if piece_at_new_position is None:
111 valid_moves_queen.append(new_pos)
112 continue
113
if piece_at_new_position.piece_color == "black" and type(piece_at_new_position) != King:
114
valid_moves_queen.append(new_pos)
115
break
116
117
# right loop
118
new_x = x
119
new_y = y
120
while True:
121
122 new_x = new_x + 1
123 new_y = new_y
124 new_pos = f"{chr(new_x)}{new_y}" 37
if new_pos not in pos_tuple:
classes/pieces/queen.py
125 break
126 piece_at_new_position = self.board.position_dict[new_pos].piece
127 if piece_at_new_position is None:
128 valid_moves_queen.append(new_pos)
129 continue
130 if piece_at_new_position.piece_color == "black" and type(piece_at_new_position) != King:
131 valid_moves_queen.append(new_pos)
132 break
133 # left loop
134 new_x = x
135 new_y = y
136 while True:
137 new_x = new_x - 1
138 new_y = new_y
139 new_pos = f"{chr(new_x)}{new_y}"
140 if new_pos not in pos_tuple:
141
break
142
piece_at_new_position = self.board.position_dict[new_pos].piece
143
if piece_at_new_position is None:
144
valid_moves_queen.append(new_pos)
145
continue
146
147 if piece_at_new_position.piece_color == "black" and type(piece_at_new_position) != King:
148 valid_moves_queen.append(new_pos)
149 break
150
151
152 if self.piece_color == "black":
153 # up left loop
154 new_x = x
155 new_y = y
156 while True:
157 new_x = new_x - 1
158 new_y = new_y - 1
159 new_pos = f"{chr(new_x)}{new_y}"
160 if new_pos not in pos_tuple:
161 break
162 piece_at_new_position = self.board.position_dict[new_pos].piece
163 if piece_at_new_position is None:
164 valid_moves_queen.append(new_pos)
165 continue
166 if piece_at_new_position.piece_color == "white" and type(piece_at_new_position) != King:
167 valid_moves_queen.append(new_pos)
168 break
169 # up right loop
170 new_x = x
171 new_y = y
172 while True:
173 new_x = new_x + 1
174 new_y = new_y - 1
175 new_pos = f"{chr(new_x)}{new_y}"
176 if new_pos not in pos_tuple:
177 break
178
piece_at_new_position = self.board.position_dict[new_pos].piece
179
if piece_at_new_position is None:
180
valid_moves_queen.append(new_pos)
181
continue
182
if piece_at_new_position.piece_color == "white" and type(piece_at_new_position) != King:
183
184 valid_moves_queen.append(new_pos)
185 break
186
187 #down right loop
188 new_x = x
189 new_y = y
190 while True: 38
new_x = new_x + 1
classes/pieces/queen.py
191 new_y = new_y + 1
192 new_pos = f"{chr(new_x)}{new_y}"
193 if new_pos not in pos_tuple:
194 break
195 piece_at_new_position = self.board.position_dict[new_pos].piece
196 if piece_at_new_position is None:
197 valid_moves_queen.append(new_pos)
198 continue
199 if piece_at_new_position.piece_color == "white" and type(piece_at_new_position) != King:
200 valid_moves_queen.append(new_pos)
201 break
202
203 #down left loop
204 new_x = x
205 new_y = y
206 while True:
207
new_x = new_x - 1
208
new_y = new_y + 1
209
new_pos = f"{chr(new_x)}{new_y}"
210
if new_pos not in pos_tuple:
211
break
212
piece_at_new_position = self.board.position_dict[new_pos].piece
213
if piece_at_new_position is None:
214
215 valid_moves_queen.append(new_pos)
216 continue
217 if piece_at_new_position.piece_color == "white" and type(piece_at_new_position) != King:
218 valid_moves_queen.append(new_pos)
219 break
220
221 # up loop
222 new_x = x
223 new_y = y
224 while True:
225 new_x = new_x
226 new_y = new_y - 1
227 new_pos = f"{chr(new_x)}{new_y}"
228 if new_pos not in pos_tuple:
229 break
230 piece_at_new_position = self.board.position_dict[new_pos].piece
231 if piece_at_new_position is None:
232 valid_moves_queen.append(new_pos)
233 continue
234 if piece_at_new_position.piece_color == "white" and type(piece_at_new_position) != King:
235 valid_moves_queen.append(new_pos)
236 break
237
238 #down loop
239 new_x = x
240 new_y = y
241 while True:
242 new_x = new_x
243 new_y = new_y + 1
244 new_pos = f"{chr(new_x)}{new_y}"
245 if new_pos not in pos_tuple:
246 break
247
piece_at_new_position = self.board.position_dict[new_pos].piece
248
if piece_at_new_position is None:
249
valid_moves_queen.append(new_pos)
250
continue
251
if piece_at_new_position.piece_color == "white" and type(piece_at_new_position) != King:
252
253 valid_moves_queen.append(new_pos)
254 break
255
256 # right loop 39
new_x = x
classes/pieces/queen.py
257 new_y = y
258 while True:
259 new_x = new_x + 1
260 new_y = new_y
261 new_pos = f"{chr(new_x)}{new_y}"
262 if new_pos not in pos_tuple:
263 break
264 piece_at_new_position = self.board.position_dict[new_pos].piece
265 if piece_at_new_position is None:
266 valid_moves_queen.append(new_pos)
267 continue
268 if piece_at_new_position.piece_color == "white" and type(piece_at_new_position) != King:
269 valid_moves_queen.append(new_pos)
270 break
271
# left loop
272
new_x = x
273
new_y = y
274
while True:
275
new_x = new_x - 1
276
new_y = new_y
277
new_pos = f"{chr(new_x)}{new_y}"
278
if new_pos not in pos_tuple:
279
break
280
281 piece_at_new_position = self.board.position_dict[new_pos].piece
282 if piece_at_new_position is None:
283 valid_moves_queen.append(new_pos)
284 continue
285 if piece_at_new_position.piece_color == "white" and type(piece_at_new_position) != King:
286 valid_moves_queen.append(new_pos)
287 break
288
289 # Select same color king
290 for pos in pos_tuple:
291 position = self.board.position_dict[pos]
292 if position.piece is not None and type(position.piece) == King and position.piece.piece_color == self.piece_color:
293 my_king = position.piece
294 break
295
296 # If king is in check, allow only those moves which prevent the check
297 if my_king.is_in_check():
298 # Play every valid move and see if king is still in check.
299 # If king remains in check, then that valid move is removed
300 new_valid_moves_queen = []
301 initial_position = self.piece_position
302 for final_position in valid_moves_queen:
303 piece_already_at_final_position = self.board.position_dict[final_position].piece
304 self.forced_move(final_position)
305 if not my_king.is_in_check():
306 new_valid_moves_queen.append(final_position)
307 self.forced_move(initial_position)
308 self.board.position_dict[final_position].piece = piece_already_at_final_position
309 return new_valid_moves_queen
310
311 return valid_moves_queen
312
313
314 def get_invalid_moves_for_opposite_king(self):
315
"""
316
Get the moves where opposite color king cannot move
317
"""
318
319
invalid_moves_for_king = []
320
x = ord(self.piece_position[0])
321
322
y = int(self.piece_position[1]) 40
classes/pieces/queen.py
323 # Includes every possible move of the piece
324 # If it encounters a piece loop terminates , unless ->
325 # If it encounters a opposite color king , then it continues to get invalid moves for opposite king
326
327 if self.piece_color == "white":
328 # up loop
329 new_x = x
330 new_y = y
331 # Includes every move and breaks the loop when a piece is encountered
332 while True:
333 new_x = new_x
334 new_y = new_y + 1
335 new_pos = f"{chr(new_x)}{new_y}"
336 if new_pos not in pos_tuple:
337 break
338 invalid_moves_for_king.append(new_pos)
339 piece_at_new_position = self.board.position_dict[new_pos].piece
340 if piece_at_new_position is not None:
341 if type(piece_at_new_position) == King:
342 if piece_at_new_position.piece_color == "black":
343
continue
344
break
345
break
346
347 # right loop
348 new_x = x
349 new_y = y
350 while True:
351 new_x = new_x + 1
352 new_y = new_y
353 new_pos = f"{chr(new_x)}{new_y}"
354 if new_pos not in pos_tuple:
355 break
356 invalid_moves_for_king.append(new_pos)
357 piece_at_new_position = self.board.position_dict[new_pos].piece
358 if piece_at_new_position is not None:
359 if type(piece_at_new_position) == King:
360 if piece_at_new_position.piece_color == "black":
361 continue
362 break
363 break
364
365 # down loop
366 new_x = x
367 new_y = y
368 while True:
369 new_x = new_x
370 new_y = new_y - 1
371 new_pos = f"{chr(new_x)}{new_y}"
372 if new_pos not in pos_tuple:
373 break
374 invalid_moves_for_king.append(new_pos)
375 piece_at_new_position = self.board.position_dict[new_pos].piece
376 if piece_at_new_position is not None:
377
if type(piece_at_new_position) == King:
378
if piece_at_new_position.piece_color == "black":
379
continue
380
381 break
382 break
383 # left loop
384 new_x = x
385 new_y = y
386 while True:
387 new_x = new_x - 1
388 new_y = new_y 41
new_pos = f"{chr(new_x)}{new_y}"
classes/pieces/queen.py
389 if new_pos not in pos_tuple:
390 break
391 invalid_moves_for_king.append(new_pos)
392 piece_at_new_position = self.board.position_dict[new_pos].piece
393 if piece_at_new_position is not None:
394 if type(piece_at_new_position) == King:
395 if piece_at_new_position.piece_color == "black":
396 continue
397 break
398
break
399
# up left loop
400
new_x = x
401
new_y = y
402
# Includes every move and breaks the loop when a piece is encountered
403
while True:
404
new_x = new_x - 1
405
new_y = new_y + 1
406
new_pos = f"{chr(new_x)}{new_y}"
407
if new_pos not in pos_tuple:
408
409 break
410 invalid_moves_for_king.append(new_pos)
411 piece_at_new_position = self.board.position_dict[new_pos].piece
412 if piece_at_new_position is not None:
413 if type(piece_at_new_position) == King:
414 if piece_at_new_position.piece_color == "black":
415 continue
416 break
417 break
418
419 # up right loop
420 new_x = x
421 new_y = y
422 while True:
423 new_x = new_x + 1
424 new_y = new_y + 1
425 new_pos = f"{chr(new_x)}{new_y}"
426 if new_pos not in pos_tuple:
427 break
428 invalid_moves_for_king.append(new_pos)
429 piece_at_new_position = self.board.position_dict[new_pos].piece
430 if piece_at_new_position is not None:
431 if type(piece_at_new_position) == King:
432 if piece_at_new_position.piece_color == "black":
433
continue
434
break
435
break
436
437 # down right loop
438 new_x = x
439 new_y = y
440 while True:
441 new_x = new_x + 1
442 new_y = new_y - 1
443 new_pos = f"{chr(new_x)}{new_y}"
444 if new_pos not in pos_tuple:
445 break
446 invalid_moves_for_king.append(new_pos)
447 piece_at_new_position = self.board.position_dict[new_pos].piece
448 if piece_at_new_position is not None:
449 if type(piece_at_new_position) == King:
450 if piece_at_new_position.piece_color == "black":
451 continue
452 break
453 break
454
42
# down left loop
classes/pieces/queen.py
455 new_x = x
456 new_y = y
457 while True:
458 new_x = new_x - 1
459 new_y = new_y -1
460 new_pos = f"{chr(new_x)}{new_y}"
461 if new_pos not in pos_tuple:
462 break
463 invalid_moves_for_king.append(new_pos)
464 piece_at_new_position = self.board.position_dict[new_pos].piece
465 if piece_at_new_position is not None:
466 if type(piece_at_new_position) == King:
467 if piece_at_new_position.piece_color == "black":
468 continue
469
break
470
break
471
472
if self.piece_color == "black":
473
474 # up loop
475 new_x = x
476 new_y = y
477 # Includes every move and breaks the loop when a piece is encountered
478 while True:
479 new_x = new_x
480 new_y = new_y - 1
481 new_pos = f"{chr(new_x)}{new_y}"
482 if new_pos not in pos_tuple:
483 break
484 invalid_moves_for_king.append(new_pos)
485 piece_at_new_position = self.board.position_dict[new_pos].piece
486 if piece_at_new_position is not None:
487 if type(piece_at_new_position) == King:
488 if piece_at_new_position.piece_color == "white":
489 continue
490 break
491 break
492
493 # right loop
494 new_x = x
495 new_y = y
496 while True:
497 new_x = new_x + 1
498 new_y = new_y
499 new_pos = f"{chr(new_x)}{new_y}"
500 if new_pos not in pos_tuple:
501 break
502 invalid_moves_for_king.append(new_pos)
503 piece_at_new_position = self.board.position_dict[new_pos].piece
504 if piece_at_new_position is not None:
505
if type(piece_at_new_position) == King:
506
if piece_at_new_position.piece_color == "white":
507
continue
508
509 break
510 break
511 # down loop
512 new_x = x
513 new_y = y
514 while True:
515 new_x = new_x
516 new_y = new_y + 1
517 new_pos = f"{chr(new_x)}{new_y}"
518 if new_pos not in pos_tuple:
519 break
520 invalid_moves_for_king.append(new_pos) 43
classes/pieces/queen.py
521 piece_at_new_position = self.board.position_dict[new_pos].piece
522 if piece_at_new_position is not None:
523 if type(piece_at_new_position) == King:
524 if piece_at_new_position.piece_color == "white":
525 continue
526 break
527 break
528
529 # left loop
530 new_x = x
531 new_y = y
532 while True:
533
new_x = new_x - 1
534
new_y = new_y
535
new_pos = f"{chr(new_x)}{new_y}"
536
if new_pos not in pos_tuple:
537
break
538
invalid_moves_for_king.append(new_pos)
539
piece_at_new_position = self.board.position_dict[new_pos].piece
540
if piece_at_new_position is not None :
541
542 if type(piece_at_new_position) == King:
543 if piece_at_new_position.piece_color == "white":
544 continue
545 break
546 break
547
548 # up left loop
549 new_x = x
550 new_y = y
551 # Includes every move and breaks the loop when a piece is encountered
552 while True:
553 new_x = new_x - 1
554 new_y = new_y - 1
555 new_pos = f"{chr(new_x)}{new_y}"
556 if new_pos not in pos_tuple:
557 break
558 invalid_moves_for_king.append(new_pos)
559 piece_at_new_position = self.board.position_dict[new_pos].piece
560 if piece_at_new_position is not None:
561 if type(piece_at_new_position) == King:
562 if piece_at_new_position.piece_color == "white":
563 continue
564 break
565
break
566
567
# up right loop
568
new_x = x
569
new_y = y
570
while True:
571
new_x = new_x + 1
572
new_y = new_y - 1
573
new_pos = f"{chr(new_x)}{new_y}"
574
if new_pos not in pos_tuple:
575
576 break
577 invalid_moves_for_king.append(new_pos)
578 piece_at_new_position = self.board.position_dict[new_pos].piece
579 if piece_at_new_position is not None:
580 if type(piece_at_new_position) == King:
581 if piece_at_new_position.piece_color == "white":
582 continue
583 break
584 break
585 # down right loop
586
44
new_x = x
classes/pieces/queen.py
587 new_y = y
588 while True:
589 new_x = new_x + 1
590 new_y = new_y + 1
591 new_pos = f"{chr(new_x)}{new_y}"
592 if new_pos not in pos_tuple:
593 break
594 invalid_moves_for_king.append(new_pos)
595 piece_at_new_position = self.board.position_dict[new_pos].piece
596 if piece_at_new_position is not None:
597 if type(piece_at_new_position) == King:
598 if piece_at_new_position.piece_color == "white":
599 continue
600
break
601
break
602
# down left loop
603
new_x = x
604
new_y = y
605
while True:
606
607 new_x = new_x - 1
608 new_y = new_y + 1
609 new_pos = f"{chr(new_x)}{new_y}"
610 if new_pos not in pos_tuple:
611 break
612 invalid_moves_for_king.append(new_pos)
613 piece_at_new_position = self.board.position_dict[new_pos].piece
614 if piece_at_new_position is not None:
615 if type(piece_at_new_position) == King:
616 if piece_at_new_position.piece_color == "white":
617 continue
618 break
619 break
620
return invalid_moves_for_king

def __str__(self):
return f"{self.piece_color[0]}q"

45
classes/pieces/rook.py

from ..vars import pos_tuple


from ..piece import Piece
from .king import King

1 class Rook(Piece):
2
"""
3
Creates a rook object for given board, with given piece color and piece position
4
"""
5
def __init__(self, board, piece_color, piece_position):
6
"""
7
board: board object
8
piece_color: color of the piece
9
piece_position: position code of the piece
10
"""
11
super().__init__(board, piece_color, piece_position)
12
13
def get_moves(self):
14
"""
15
Get all possible moves of the piece
16
"""
17
valid_moves_rook = []
18
x = ord(self.piece_position[0])
19
y = int(self.piece_position[1])
20
21
if self.piece_color == "white":
22
23 # up loop
24 new_x = x
25 new_y = y
26 while True:
27 new_x = new_x
28 new_y = new_y + 1
29 new_pos = f"{chr(new_x)}{new_y}"
30 if new_pos not in pos_tuple:
31 break
32 piece_at_new_position = self.board.position_dict[new_pos].piece
33 if piece_at_new_position is None:
34 valid_moves_rook.append(new_pos)
35 continue
36 if piece_at_new_position.piece_color == "black" and type(piece_at_new_position) != King:
37 valid_moves_rook.append(new_pos)
38 break
39
40 #down loop
41 new_x = x
42 new_y = y
43 while True:
44 new_x = new_x
45 new_y = new_y - 1
46 new_pos = f"{chr(new_x)}{new_y}"
47 if new_pos not in pos_tuple:
48 break
49 piece_at_new_position = self.board.position_dict[new_pos].piece
50 if piece_at_new_position is None:
51 valid_moves_rook.append(new_pos)
52 continue
53 if piece_at_new_position.piece_color == "black" and type(piece_at_new_position) != King:
54
valid_moves_rook.append(new_pos)
55
break
56
57
# right loop
58
new_x = x
59
new_y = y
60
61
while True: 46
new_x = new_x + 1
62
classes/pieces/rook.py
63 new_y = new_y
64 new_pos = f"{chr(new_x)}{new_y}"
65 if new_pos not in pos_tuple:
66 break
67 piece_at_new_position = self.board.position_dict[new_pos].piece
68
69 if piece_at_new_position is None:
70 valid_moves_rook.append(new_pos)
71 continue
72 if piece_at_new_position.piece_color == "black" and type(piece_at_new_position) != King:
73 valid_moves_rook.append(new_pos)
74 break
75 # left loop
76 new_x = x
77 new_y = y
78 while True:
79
new_x = new_x - 1
80
new_y = new_y
81
new_pos = f"{chr(new_x)}{new_y}"
82
if new_pos not in pos_tuple:
83
break
84
piece_at_new_position = self.board.position_dict[new_pos].piece
85
86
if piece_at_new_position is None:
87
88 valid_moves_rook.append(new_pos)
89 continue
90 if piece_at_new_position.piece_color == "black" and type(piece_at_new_position) != King:
91 valid_moves_rook.append(new_pos)
92 break
93
94 elif self.piece_color == "black":
95 # up loop
96 new_x = x
97 new_y = y
98 while True:
99 new_x = new_x
100 new_y = new_y - 1
101 new_pos = f"{chr(new_x)}{new_y}"
102 if new_pos not in pos_tuple:
103 break
104 piece_at_new_position = self.board.position_dict[new_pos].piece
105 if piece_at_new_position is None:
106 valid_moves_rook.append(new_pos)
107 continue
108 if piece_at_new_position.piece_color == "white" and type(piece_at_new_position) != King:
109 valid_moves_rook.append(new_pos)
110 break
111
112 #down loop
113 new_x = x
114 new_y = y
115 while True:
116 new_x = new_x
117 new_y = new_y + 1
118 new_pos = f"{chr(new_x)}{new_y}"
119 if new_pos not in pos_tuple:
120
break
121
piece_at_new_position = self.board.position_dict[new_pos].piece
122
if piece_at_new_position is None:
123
valid_moves_rook.append(new_pos)
124
continue
125
126 if piece_at_new_position.piece_color == "white" and type(piece_at_new_position) != King:
127 valid_moves_rook.append(new_pos)
128 break 47
classes/pieces/rook.py
129 # right loop
130 new_x = x
131 new_y = y
132 while True:
133 new_x = new_x + 1
134 new_y = new_y
135 new_pos = f"{chr(new_x)}{new_y}"
136 if new_pos not in pos_tuple:
137 break
138 piece_at_new_position = self.board.position_dict[new_pos].piece
139 if piece_at_new_position is None:
140 valid_moves_rook.append(new_pos)
141 continue
142 if piece_at_new_position.piece_color == "white" and type(piece_at_new_position) != King:
143 valid_moves_rook.append(new_pos)
144 break
145
# left loop
146
new_x = x
147
new_y = y
148
while True:
149
new_x = new_x - 1
150
new_y = new_y
151
new_pos = f"{chr(new_x)}{new_y}"
152
if new_pos not in pos_tuple:
153
break
154
155 piece_at_new_position = self.board.position_dict[new_pos].piece
156 if piece_at_new_position is None:
157 valid_moves_rook.append(new_pos)
158 continue
159 if piece_at_new_position.piece_color == "white" and type(piece_at_new_position) != King :
160 valid_moves_rook.append(new_pos)
161 break
162
163 # Select same color king
164 for pos in pos_tuple:
165 position = self.board.position_dict[pos]
166 if position.piece is not None and type(position.piece) == King and position.piece.piece_color == self.piece_color:
167 my_king = position.piece
168 break
169
170 # If king is in check, allow only those moves which prevent the check
171 if my_king.is_in_check():
172 # Play every valid move and see if king is still in check.
173 # If king remains in check, then that valid move is removed
174 new_valid_moves_rook = []
175 initial_position = self.piece_position
176 for final_position in valid_moves_rook:
177 piece_already_at_final_position = self.board.position_dict[final_position].piece
178 self.forced_move(final_position)
179 if not my_king.is_in_check():
180 new_valid_moves_rook.append(final_position)
181 self.forced_move(initial_position)
182 self.board.position_dict[final_position].piece = piece_already_at_final_position
183 return new_valid_moves_rook
184
185 return valid_moves_rook
186
187 def get_invalid_moves_for_opposite_king(self):
188
"""
189
Get the moves where opposite color king cannot move
190
"""
191
192
invalid_moves_for_king = []
193
194
x = ord(self.piece_position[0]) 48
y = int(self.piece_position[1])
classes/pieces/rook.py
195
196 # Includes every possible move of the piece
197 # If it encounters a piece loop terminates , unless ->
198 # If it encounters a opposite color king , then it continues to get invalid moves for opposite king
199
200 if self.piece_color == "white":
201 # up loop
202 new_x = x
203 new_y = y
204 while True:
205 new_x = new_x
206 new_y = new_y + 1
207 new_pos = f"{chr(new_x)}{new_y}"
208 if new_pos not in pos_tuple:
209 break
210 invalid_moves_for_king.append(new_pos)
211 piece_at_new_position = self.board.position_dict[new_pos].piece
212 if piece_at_new_position is not None :
213 if type(piece_at_new_position) == King:
214 if piece_at_new_position.piece_color == "black":
215
continue
216
break
217
break
218
219
220 # right loop
221 new_x = x
222 new_y = y
223 while True:
224 new_x = new_x + 1
225 new_y = new_y
226 new_pos = f"{chr(new_x)}{new_y}"
227 if new_pos not in pos_tuple:
228 break
229 invalid_moves_for_king.append(new_pos)
230 piece_at_new_position = self.board.position_dict[new_pos].piece
231 if piece_at_new_position is not None :
232 if type(piece_at_new_position) == King:
233 if piece_at_new_position.piece_color == "black":
234 continue
235 break
236 break
237
238 # down loop
239 new_x = x
240 new_y = y
241 while True:
242 new_x = new_x
243 new_y = new_y - 1
244 new_pos = f"{chr(new_x)}{new_y}"
245 if new_pos not in pos_tuple:
246 break
247 invalid_moves_for_king.append(new_pos)
248 piece_at_new_position = self.board.position_dict[new_pos].piece
249 if piece_at_new_position is not None :
250
if type(piece_at_new_position) == King:
251
if piece_at_new_position.piece_color == "black":
252
continue
253
254 break
255 break
256 # left loop
257 new_x = x
258 new_y = y
259 while True:
260 new_x = new_x - 1 49
new_y = new_y
classes/pieces/rook.py
261 new_pos = f"{chr(new_x)}{new_y}"
262 if new_pos not in pos_tuple:
263 break
264 invalid_moves_for_king.append(new_pos)
265 piece_at_new_position = self.board.position_dict[new_pos].piece
266 if piece_at_new_position is not None :
267 if type(piece_at_new_position) == King:
268 if piece_at_new_position.piece_color == "black":
269 continue
270 break
271
break
272
273
if self.piece_color == "black":
274
# up loop
275
new_x = x
276
new_y = y
277
# Includes every move and breaks the loop when a piece is encountered
278
while True:
279
280 new_x = new_x
281 new_y = new_y - 1
282 new_pos = f"{chr(new_x)}{new_y}"
283 if new_pos not in pos_tuple:
284 break
285 invalid_moves_for_king.append(new_pos)
286 piece_at_new_position = self.board.position_dict[new_pos].piece
287 if piece_at_new_position is not None :
288 if type(piece_at_new_position) == King:
289 if piece_at_new_position.piece_color == "white":
290 continue
291 break
292 break
293 break
294
295 # right loop
296 new_x = x
297 new_y = y
298 while True:
299 new_x = new_x + 1
300 new_y = new_y
301 new_pos = f"{chr(new_x)}{new_y}"
302 if new_pos not in pos_tuple:
303 break
304 invalid_moves_for_king.append(new_pos)
305 piece_at_new_position = self.board.position_dict[new_pos].piece
306 if piece_at_new_position is not None:
307
if type(piece_at_new_position) == King:
308
if piece_at_new_position.piece_color == "white":
309
continue
310
311 break
312 break
313 # down loop
314 new_x = x
315 new_y = y
316 while True:
317 new_x = new_x
318 new_y = new_y + 1
319 new_pos = f"{chr(new_x)}{new_y}"
320 if new_pos not in pos_tuple:
321 break
322 invalid_moves_for_king.append(new_pos)
323 piece_at_new_position = self.board.position_dict[new_pos].piece
324 if piece_at_new_position is not None :
325 if type(piece_at_new_position) == King:
326
50
if piece_at_new_position.piece_color == "white":
classes/pieces/rook.py
327 continue
328 break
329 break
330
331
332 # left loop
333 new_x = x
334 new_y = y
335 while True:
336 new_x = new_x - 1
337 new_y = new_y
338 new_pos = f"{chr(new_x)}{new_y}"
339 if new_pos not in pos_tuple:
340 break
341 invalid_moves_for_king.append(new_pos)
342 piece_at_new_position = self.board.position_dict[new_pos].piece
343 if piece_at_new_position is not None :
344
if type(piece_at_new_position) == King:
345
if piece_at_new_position.piece_color == "white":
346
continue
347
348 break
349 break
350
return invalid_moves_for_king

def __str__(self):
return f"{self.piece_color[0]}r"

51
database/config.py

1 #VARIABLES FOR DATABASE CONNECTION


2
3 DATABASE = "chess_db"
4 HOST = "localhost"
5 USER = ""
6 PASSWORD = ""

52
database/connect.py

1 from .config import *


2 import mysql.connector
3
4
5 CONNECTION = None
6
7 def connect():
8 '''
9 Connects to local host of this machine
10 '''
11 global CONNECTION
12
13
14 if CONNECTION is not None: return CONNECTION
15
16 CONNECTION = mysql.connector.connect(
17 database = DATABASE,
18 user = USER,
19 passwd = PASSWORD,
20 host = HOST
21 )
22
23 return CONNECTION

53
database/create.py

1 from .connect import connect


2 from .get import get
3 from random import randint
4
5 def create_user(new_username, new_password):
6 '''
7 Creates a user with given user and password
8 It raises error if the username is already used
9 '''
10
11 new_username = new_username.lower()
12 res = get("users", f"username = '{new_username}'")
13
14 if len(res) > 0:
15 raise ValueError("username already used")
16
17 command = f"INSERT INTO users (username,password) VALUES ('{new_username}', '{new_password}')"
18 connection = connect()
19 cursor = connection.cursor()
20
21 cursor.execute(command)
22 connection.commit()
23
24 def create_game(user):
25 '''
26 Create a game with given user
27 '''
28
29 while True:
30 game_id = randint(111111, 999999)
31 res = get("games", f"id = {game_id}")
32 if len(res) == 0:
33 break
34
35 command = f"INSERT INTO games(id, status, user1, moves) VALUES({game_id}, 'open', '{user.username}', '');"
36
37 connection = connect()
38 cursor = connection.cursor()
39 cursor.execute(command)
40 connection.commit()
41
42 return game_id

54
database/get.py

1 from .connect import connect


2
3
4 def get(table, conditions, limit = 1):
5 '''
6 Get results from the selected table with specified conditions upto a given limit
7 '''
8
9 connection = connect()
10 cursor = connection.cursor()
11
12 command = f"SELECT * FROM {table} WHERE {conditions} LIMIT {limit}"
13 cursor.execute(command)
14 result = cursor.fetchall()
15 connection.commit()
16
17 return result

55
database/setup.py
1 # Database Setup
2
3 from .config import DATABASE, HOST, USER, PASSWORD
4 from .connect import connect
5
6
7 def setup():
8 connection = connect()
9 cursor = connection.cursor()
10
11 # Check if users table exists
12 command = f"SELECT COUNT(*) FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = '{DATABASE}' AND TABLE_NAME = 'users' LIMIT 1"
13 cursor.execute(command)
14 results = cursor.fetchone()
15 if results[0] != 1:
16 # Table doesn't exist, create it
17 command = f"CREATE TABLE users (id INT NOT NULL AUTO_INCREMENT, username VARCHAR(20) NOT NULL UNIQUE, password TEXT NOT NULL, PRIMARY KEY (id))"
18 cursor.execute(command)
19 connection.commit()
20
21 # Check if games table exists
22 command = f"SELECT COUNT(*) FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = '{DATABASE}' AND TABLE_NAME = 'games' LIMIT 1"
23 cursor.execute(command)
24 results = cursor.fetchone()
25 if results[0] != 1:
26 # Table doesn't exist, create one
27 command = f"CREATE TABLE games (id INT NOT NULL AUTO_INCREMENT, status VARCHAR(10), user1 VARCHAR(20), user2 VARCHAR(20) DEFAULT '', moves TEXT, result VARCHAR(20) DEF
28 cursor.execute(command)
29 connection.commit()

56
database/update.py

1 from .connect import connect


2 from .get import get
3
4
5 def join_game(game_id, user):
6 '''
7 Join a game using given game_id and user (also game_pass if mode = 'private')
8 '''
9
10 res = get("games", f"ID = {game_id} and status = 'open'")
11 if len(res) != 1:
12 raise ValueError("Invald Game")
13
14 command = f"UPDATE games SET status = 'running', user2 = '{user.username}' WHERE ID = {game_id}"
15
16 connection = connect()
17 cursor = connection.cursor()
18 cursor.execute(command)
19 connection.commit()
20
21 def update_game(game_ID, updates):
22 '''
23 Updates the moves of the game of given ID
24 Shows error if game ID is invalid
25 '''
26
27 res = get("games",f"ID = {game_ID}")
28 if len(res) != 1:
29 raise ValueError("invalid game ID")
30
31 command = f"UPDATE games SET {updates} WHERE ID = {game_ID}"
32
33 connection = connect()
34 cursor = connection.cursor()
35 cursor.execute(command)
36 connection.commit()

57
ui/auth.py

from .classes import User


1 from ..database.create import create_game, create_user
2
from ..database.get import get
3
4
def authenticate():
5
while True:
6
7 option = input("""Enter 1 to login
8 2 to signup
9 3 to exit
10
11 > """)
12
13 if option in ['1', '2', '3']:
14 break
15
16 if option == '3':
17 exit()
18
19 if option == '2':
20 username = input("Enter Username: ")
21 password = input("Enter Password: ")
22
23 while True:
24 try:
25 create_user(username, password)
26 except ValueError as e:
27 print("\n", e, "\n", sep="")
28 return authenticate()
29 else:
30 break
31
32 return User(username)
33
34 if option == '1':
35
username = input("Enter Username: ")
36
password = input("Enter Password: ")
37
38
res = get("users", f"username = '{username}' and password = '{password}'")
39
40
if len(res) != 1:
41
print("\nInvalid Credentials\n")
42
return authenticate()
43
44
return User(username)

58
ui/classes.py

1 class User:
2 def __init__(self, username):
3 self.username = username

59
ui/game.py
from ..database.update import join_game, update_game
from ..database.create import create_game
from ..database.get import get
from ..classes.board import Board
1 from ..classes.vars import pos_tuple
2 import os
3 from time import sleep
4
5
6 def playing_loop(game_data, game_board, my_color, mode):
7
game_board.print_board(my_color)
8
while True:
9
print("\nYour Color:", my_color)
10
while True:
11
12 from_pos = input("\nMove from: ")
13 if from_pos in pos_tuple and game_board.position_dict[from_pos].piece is not None and game_board.position_dict[from_pos].piece.piece_color == my_color:
14 valid_moves = game_board.position_dict[from_pos].piece.get_moves()
15 else:
16 print("\nInvalid Piece!")
17 continue
18 if valid_moves == []:
19 print(f"\nThe piece at {from_pos} cannot move, choose a different piece.")
20 continue
21 change_piece = False
22 while True:
23 print(f"\nValid Moves for piece at {from_pos}:", *valid_moves)
24 to_pos = input("\nMove to (leave empty to move a different piece): ")
25 if to_pos == "":
26 change_piece = True
27 break
28
if to_pos in pos_tuple and to_pos in valid_moves:
29
break
30
print("\nInvalid Move!")
31
32 if not change_piece:
33 break
34
35 game_board.play_move(f"{from_pos}_{to_pos}")
36
37 res = get("games", f"id = {game_data[0]} and status = 'running'")
38 if len(res) != 1:
39 raise ValueError("Ivalid game")
40
41 old_game_data = res[0]
42
43 old_moves = old_game_data[4]
44
45 new_moves = old_moves + f" {from_pos}_{to_pos}"
46 status_tuple = game_board.is_game_over(my_color)
47 if status_tuple[0]:
48 new_status = 'ended'
49 if status_tuple[1] == "won":
50 if mode == "hosted":
51 new_result = "user1"
52 else:
53 new_result = "user2"
54 elif status_tuple[1] == "lost":
55 if mode == "hosted":
56 new_result = "user2"
57 else:
58 new_result = "user1"
59 else:
60 new_result = "stalemate"
61 else:
62 new_status = old_game_data[1]
63 new_result = old_game_data[5]
64
65 update_game(game_data[0], f"moves = '{new_moves}', status = '{new_status}', result = '{new_result}'")
66
67 new_game_data = list(old_game_data)
68 new_game_data[4] = new_moves
69 new_game_data[1] = new_status
70 new_game_data[5] = new_result
71 break
72
73 return tuple(new_game_data)
74
75 def waiting_loop(game_data, game_board, my_color, moves):
76 while True:
77 os.system('cls' if os.name == 'nt' else 'clear')
78 game_board.print_board(my_color)
79 if my_color == "white":
80 print(f"\nWaiting for {game_data[3]}'s move...")
81
82
else: 60
print(f"\nWaiting for {game_data[2]}'s move...")
83
res = get("games", f"id = {game_data[0]}")
84
res = get("games", f"id = {game_data[0]}") ui/game.py
84
if len(res) != 1:
85
86 raise ValueError("Ivalid game")
87
88 new_game_data = res[0]
89
90 if moves == new_game_data[4]:
91 continue
92
93 new_move_notation = new_game_data[4].replace(moves, '').strip()
94 game_board.play_move(new_move_notation)
95 break
96
97 return new_game_data
98
99 def start_game(myuser):
100 os.system('cls' if os.name == 'nt' else 'clear')
101 while True:
102 option = input(f"""Welcome {myuser.username}
103 Enter 1 to join a game
104 2 to host a game
105 3 to quit
106
107 > """)
108 if option in ['1', '2', '3']:
109 break
110
111 print("\nInvalid option\n")
112
113 os.system('cls' if os.name == 'nt' else 'clear')
114
115 if option == '3':
116
return
117
118
if option == '1':
119
print("Searching for games...")
120
121 res = get("games", f"status = 'open' and user1 <> '{myuser.username}'")
122 print("\tDone.")
123 if len(res) == 0:
124 print("No open public game found, try hosting one.")
125 print("Returning to menu...")
126 sleep(3)
127 return start_game(myuser)

128 else:
129 sleep(1)
130
131 game_data = res[0]
132 print(f"Joining game with {game_data[2]}...")
133 join_game(game_data[0], myuser)
134 print("\tDone.")
135 sleep(1)
136
137 os.system('cls' if os.name == 'nt' else 'clear')
138
139 game_board = Board()
140 my_color = "black"
141 moves = ''
142
143 while True:
144 game_data = waiting_loop(game_data, game_board, my_color, moves)
145 moves = game_data[4]
146
147 os.system('cls' if os.name == 'nt' else 'clear')
148
149 game_board.print_board(my_color)
150 if game_data[1] == 'ended':
151
print()
152
if game_data[5] == 'user2':
153
print("You won!")
154
155 elif game_data[5] == 'user1':
156 print("You lost!")
157 else:
158 print("The game was a draw!")
159
160 input("Press Enter to continue\n")
161 return start_game(myuser)
162
163 os.system('cls' if os.name == 'nt' else 'clear')
164
165 game_data = playing_loop(game_data, game_board, my_color, "joined")
166
167 os.system('cls' if os.name == 'nt' else 'clear')
168
169 game_board.print_board(my_color)
170 moves = game_data[4] 61
171 if game_data[1] == 'ended':
172 print()
172
ui/game.py
print()
173 if game_data[5] == 'user2':
174 print("You won!")
175 elif game_data[5] == 'user1':
176
print("You lost!")
177
else:
178
print("The game was a draw!")
179
180
181 input("Press Enter to continue\n")
182 return start_game(myuser)
183 elif option == '2':
184 print("Creating game...")
185 game_id = create_game(myuser)
186 print("\tDone.")
187 sleep(0.5)
188
189 game_board = Board()
190 my_color = "white"
191 moves = ''
192
193 while True:

194
195 os.system('cls' if os.name == 'nt' else 'clear')
196
197 game_board.print_board(my_color)
198 print("\nWaiting for someone to join the game...")
199 res = get("games", f"id = {game_id}")
200 game_data = res[0]
201 if game_data[1] == 'running':
202 break
203 sleep(0.1)
204
205 print("\tDone.")
206 print(f"{game_data[3]} joined the game")
207 print("Loading...")
208
sleep(1)
209
210
while True:
211
212
os.system('cls' if os.name == 'nt' else 'clear')
213
214
game_data = playing_loop(game_data, game_board, my_color, "joined")
215
216
os.system('cls' if os.name == 'nt' else 'clear')
217
218
219 game_board.print_board(my_color)
220 moves = game_data[4]
221 if game_data[1] == 'ended':
222 print()
223 if game_data[5] == 'user1':
224 print("You won!")
225 elif game_data[5] == 'user2':
226 print("You lost!")
227 else:
228 print("The game was a draw!")
229
230 input("Press Enter to continue\n")
231 return start_game(myuser)
232
233 os.system('cls' if os.name == 'nt' else 'clear')
234
235 game_data = waiting_loop(game_data, game_board, my_color, moves)
236 moves = game_data[4]
237
238 os.system('cls' if os.name == 'nt' else 'clear')
239
240 game_board.print_board(my_color)
241 if game_data[1] == 'ended':
242
print()
243
if game_data[5] == 'user1':
244
print("You won!")
245
246 elif game_data[5] == 'user2':
247 print("You lost!")
248 else:
print("The game was a draw!")

input("Press Enter to continue\n")


return start_game(myuser)

62
ui/__init__.py

1 from ..database.setup import setup


2 from .auth import authenticate
3 from .game import start_game
4
5 def start():
6 setup()
7 myuser = authenticate()
8 start_game(myuser)

63
______________________________________________________________________________________________________________________

OUTPUT SCREEN
______________________________________________________________________________________________________________________

64
65
66
______________________________________________________________________________________________________________________

BIBLIOGRAPHY
______________________________________________________________________________________________________________________

• https://python.org/
• https://mysql.com/
• https://stackoverflow.com/
• https://geeksforgeeks.org/

67

You might also like