├── Chess Program ├── Black │ ├── b.png │ ├── blank.png │ ├── k.png │ ├── n.png │ ├── p.png │ ├── q.png │ └── r.png ├── Chess.py └── White │ ├── b.png │ ├── blank.png │ ├── k.png │ ├── n.png │ ├── p.png │ ├── q.png │ └── r.png └── README.md /Chess Program/Black/b.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ransurf/pythonchessprogram/d4fa3f4b07d03291c6c75441e54fe901dedc5814/Chess Program/Black/b.png -------------------------------------------------------------------------------- /Chess Program/Black/blank.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ransurf/pythonchessprogram/d4fa3f4b07d03291c6c75441e54fe901dedc5814/Chess Program/Black/blank.png -------------------------------------------------------------------------------- /Chess Program/Black/k.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ransurf/pythonchessprogram/d4fa3f4b07d03291c6c75441e54fe901dedc5814/Chess Program/Black/k.png -------------------------------------------------------------------------------- /Chess Program/Black/n.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ransurf/pythonchessprogram/d4fa3f4b07d03291c6c75441e54fe901dedc5814/Chess Program/Black/n.png -------------------------------------------------------------------------------- /Chess Program/Black/p.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ransurf/pythonchessprogram/d4fa3f4b07d03291c6c75441e54fe901dedc5814/Chess Program/Black/p.png -------------------------------------------------------------------------------- /Chess Program/Black/q.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ransurf/pythonchessprogram/d4fa3f4b07d03291c6c75441e54fe901dedc5814/Chess Program/Black/q.png -------------------------------------------------------------------------------- /Chess Program/Black/r.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ransurf/pythonchessprogram/d4fa3f4b07d03291c6c75441e54fe901dedc5814/Chess Program/Black/r.png -------------------------------------------------------------------------------- /Chess Program/Chess.py: -------------------------------------------------------------------------------- 1 | import tkinter as tk 2 | import string #for a string to store alphabet 3 | import os, sys #help with importing images 4 | from PIL import Image, ImageTk #help with implementing images into GUI 5 | from PIL.ImageTk import PhotoImage 6 | 7 | class Board(tk.Frame): 8 | 9 | def __init__(self, parent, length, width): #self=Frame, parent=root 10 | 11 | tk.Frame.__init__(self, parent) 12 | self.parent = parent 13 | self.length = length 14 | self.width = width 15 | self.config(height=100*self.length, width=100*self.width) 16 | self.pack() 17 | 18 | self.square_color = None 19 | self.squares = {} #stores squares with pos as key and button as value 20 | self.ranks = string.ascii_lowercase 21 | self.white_images = {} #stores images of pieces 22 | self.black_images = {} 23 | self.white_pieces = ["pyimage1", "pyimage3", "pyimage4", "pyimage5", "pyimage6", "pyimage7"] #for convenience when calling all white pieces 24 | self.black_pieces = ["pyimage8", "pyimage10", "pyimage11", "pyimage12", "pyimage13", "pyimage14"] 25 | self.buttons_pressed = 0 26 | self.turns = 0 27 | self.sq1 = None #first square clicked 28 | self.sq2 = None 29 | self.sq1_button = None #button associated with the square clicked 30 | self.sq2_button = None 31 | self.piece_color = None 32 | self.wk_moved = False #for castling 33 | self.bk_moved = False 34 | self.wr1_moved = False 35 | self.wr2_moved = False 36 | self.br1_moved = False 37 | self.br2_moved = False 38 | self.castled = False 39 | self.set_squares() 40 | 41 | def select_piece(self, button): #called when a square button is pressed, consists of majority of the movement code 42 | if button["image"] in self.white_pieces and self.buttons_pressed == 0: #checks color of first piece 43 | self.piece_color = "white" 44 | elif button["image"] in self.black_pieces and self.buttons_pressed == 0: 45 | self.piece_color = "black" 46 | 47 | if (self.piece_color == "white" and self.turns % 2 == 0) or (self.piece_color == "black" and self.turns % 2 == 1) or self.buttons_pressed == 1: #prevents people from moving their pieces when it's not their turn 48 | if self.buttons_pressed == 0: #stores square and button of first square selected 49 | self.sq1 = list(self.squares.keys())[list(self.squares.values()).index(button)] #retrieves pos of piece 50 | self.sq1_button = button 51 | self.buttons_pressed += 1 52 | 53 | elif self.buttons_pressed==1: #stores square and button of second square selected 54 | self.sq2 = list(self.squares.keys())[list(self.squares.values()).index(button)] 55 | self.sq2_button = button 56 | if self.sq2 == self.sq1: #prevents self-destruction and allows the user to choose a new piece 57 | self.buttons_pressed = 0 58 | return 59 | 60 | if self.allowed_piece_move() and self.friendly_fire() == False: #makes sure the move is legal 61 | prev_sq1 = self.sq1 62 | prev_sq1_button_piece = self.sq1_button["image"] 63 | prev_sq2 = self.sq2 64 | prev_sq2_button_piece = self.sq2_button["image"] 65 | self.squares[self.sq2].config(image=self.sq1_button["image"]) #moves pice in sq1 to sq2 66 | self.squares[self.sq2].image = self.sq1_button["image"] 67 | self.squares[self.sq1].config(image=self.white_images["blank.png"]) #clears sq1 68 | self.squares[self.sq1].image = self.white_images["blank.png"] 69 | if self.in_check() == True and self.castled == False: #for some reason it says king is in check after a castle so I set up a variable here that would prevent this code from running 70 | self.squares[prev_sq2].config(image=prev_sq2_button_piece) #reverts movement since king is or would be put into check because of move 71 | self.squares[prev_sq2].image = prev_sq2_button_piece 72 | self.squares[prev_sq1].config(image=prev_sq1_button_piece) 73 | self.squares[prev_sq1].image = prev_sq1_button_piece 74 | self.buttons_pressed = 0 75 | return 76 | else: #runs if king is not in check, checks if kings or rooks have moved, preventing castling in the future 77 | if prev_sq1_button_piece == "pyimage3": 78 | self.wk_moved = True 79 | if prev_sq1_button_piece == "pyimage10": 80 | self.bk_moved = True 81 | if prev_sq1_button_piece == "pyimage7" and prev_sq1 == "a1": 82 | self.wr1_moved = True 83 | if prev_sq1_button_piece == "pyimage7" and prev_sq1 == "h1": 84 | self.wr2_moved = True 85 | if prev_sq1_button_piece == "pyimage14" and prev_sq1 == "a8": 86 | self.br1_moved = True 87 | if prev_sq1_button_piece == "pyimage14" and prev_sq1 == "h8": 88 | self.br2_moved = True 89 | self.buttons_pressed = 0 90 | self.turns += 1 91 | if (button["image"] == "pyimage5" and prev_sq2.count("8")==1) or (button["image"] == "pyimage12" and prev_sq2.count("1")==1): #checks for possible pawn promotion 92 | self.promotion_menu(self.piece_color) 93 | self.castled = False 94 | else: 95 | self.buttons_pressed = 0 96 | return 97 | 98 | def promotion_menu(self, color): #creates menu to choose what piece to change the pawn to 99 | def return_piece(piece): #function called by buttons to make the change and destroy window 100 | self.squares[self.sq2].config(image=piece) 101 | self.squares[self.sq2].image = piece 102 | promo.destroy() 103 | return 104 | 105 | promo = tk.Tk() #creates a new menu with buttons depending on pawn color 106 | promo.title("Choose what to promote your pawn to") 107 | if color=="white": 108 | promo_knight = tk.Button(promo, text="Knight", command=lambda: return_piece("pyimage4")) #triggers return_piece function when selected 109 | promo_knight.grid(row=0, column=0) 110 | promo_bishop = tk.Button(promo, text="Bishop", command=lambda: return_piece("pyimage1")) 111 | promo_bishop.grid(row=0, column=1) 112 | promo_rook = tk.Button(promo, text="Rook", command=lambda: return_piece("pyimage7")) 113 | promo_rook.grid(row=1, column=0) 114 | promo_queen = tk.Button(promo, text="Queen", command=lambda: return_piece("pyimage6")) 115 | promo_queen.grid(row=1, column=1) 116 | elif color=="black": 117 | promo_knight = tk.Button(promo, text="Knight", command=lambda: return_piece("pyimage11")) 118 | promo_knight.grid(row=0, column=0) 119 | promo_bishop = tk.Button(promo, text="Bishop", command=lambda: return_piece("pyimage8")) 120 | promo_bishop.grid(row=0, column=1) 121 | promo_rook = tk.Button(promo, text="Rook", command=lambda: return_piece("pyimage14")) 122 | promo_rook.grid(row=1, column=0) 123 | promo_queen = tk.Button(promo, text="Queen", command=lambda: return_piece("pyimage13")) 124 | promo_queen.grid(row=1, column=1) 125 | promo.mainloop() 126 | return 127 | 128 | def friendly_fire(self): #prevents capturing your own pieces 129 | piece_2_color = self.sq2_button["image"] 130 | if self.piece_color == "white" and piece_2_color in self.white_pieces: 131 | return True 132 | if self.piece_color == "black" and piece_2_color in self.black_pieces: 133 | return True 134 | else: 135 | return False 136 | 137 | def clear_path(self, piece): #makes sure that the squares in between sq1 and sq2 aren't occupied 138 | if piece == "rook" or piece == "queen": 139 | if self.sq1[0] == self.sq2[0]: #for vertical movement 140 | pos1 = min(int(self.sq1[1]), int(self.sq2[1])) 141 | pos2 = max(int(self.sq1[1]), int(self.sq2[1])) 142 | for i in range(pos1+1, pos2): 143 | square_on_path = self.squares[self.sq1[0]+str(i)].cget("image") 144 | if square_on_path != "pyimage2": 145 | return False 146 | 147 | elif self.sq1[1] == self.sq2[1]: #for horizontal movement 148 | pos1 = min(self.ranks.find(self.sq1[0]), self.ranks.find(self.sq2[0])) 149 | pos2 = max(self.ranks.find(self.sq1[0]), self.ranks.find(self.sq2[0])) 150 | 151 | for i in range(pos1+1, pos2): 152 | square_on_path = self.squares[self.ranks[i]+self.sq1[1]].cget("image") 153 | if square_on_path != "pyimage2": 154 | return False 155 | 156 | if piece == "bishop" or piece == "queen": #for diagonal movement 157 | x1 = self.ranks.find(self.sq1[0]) 158 | x2 = self.ranks.find(self.sq2[0]) 159 | y1 = int(self.sq1[1]) 160 | y2 = int(self.sq2[1]) 161 | 162 | if y1x2: #NW direction 170 | for x in range(x1-1, x2, -1): 171 | y1 += 1 172 | square_on_path = self.squares[self.ranks[x]+str(y1)].cget("image") 173 | if square_on_path != "pyimage2": 174 | return False 175 | elif y1>y2: 176 | if x1x2: #SW direction 183 | for x in range(x1-1, x2, -1): 184 | y1 -= 1 185 | square_on_path = self.squares[self.ranks[x]+str(y1)].cget("image") 186 | if square_on_path != "pyimage2": 187 | return False 188 | return True 189 | 190 | 191 | def allowed_piece_move(self): #checks whether the piece can move to square 2 with respect to their movement capabilities 192 | wb, wk, wn, wp, wq, wr = "pyimage1", "pyimage3", "pyimage4", "pyimage5", "pyimage6", "pyimage7" #redefining pyimages for readability 193 | bb, bk, bn, bp, bq, br = "pyimage8", "pyimage10", "pyimage11", "pyimage12", "pyimage13", "pyimage14" 194 | 195 | if self.sq1_button["image"] == "pyimage2" or self.sq1_button["image"] == "pyimage9": #for when this function is called for check 196 | return False 197 | 198 | if (self.sq1_button["image"] == wb or self.sq1_button["image"] == bb) and self.clear_path("bishop"): #bishop movement 199 | if abs(int(self.sq1[1]) - int(self.sq2[1])) == abs(self.ranks.find(self.sq1[0]) - self.ranks.find(self.sq2[0])): #makes sure there is equal change between file and rank movement 200 | return True 201 | 202 | if self.sq1_button["image"] == wn or self.sq1_button["image"] == bn: #knight movement 203 | if (abs(int(self.sq1[1]) - int(self.sq2[1])) == 2) and (abs(self.ranks.find(self.sq1[0]) - self.ranks.find(self.sq2[0])) == 1): #allows tall L moves 204 | return True 205 | if (abs(int(self.sq1[1]) - int(self.sq2[1])) == 1) and (abs(self.ranks.find(self.sq1[0]) - self.ranks.find(self.sq2[0])) == 2): #allows wide L moves 206 | return True 207 | 208 | if self.sq1_button["image"] == wk or self.sq1_button["image"] == bk: #king movement 209 | if (abs(int(self.sq1[1]) - int(self.sq2[1])) < 2) and (abs(self.ranks.find(self.sq1[0]) - self.ranks.find(self.sq2[0]))) < 2: #allows 1 square moves 210 | return True 211 | if self.castle() is True: 212 | return True 213 | 214 | if self.sq1_button["image"] == wp: #white pawn movement 215 | if "2" in self.sq1: #allows for 2 space jump from starting pos 216 | if (int(self.sq1[1])+1 == int(self.sq2[1]) or int(self.sq1[1])+2 == int(self.sq2[1])) and self.sq1[0] == self.sq2[0] and self.sq2_button["image"] == "pyimage2": #allows 2 sq movement 217 | in_front = self.squares[self.sq1[0] + str(int(self.sq1[1])+1)] 218 | if in_front["image"] == "pyimage2": #makes sure that there is no piece blocking path 219 | return True 220 | if int(self.sq1[1])+1 == int(self.sq2[1]) and self.sq1[0] == self.sq2[0] and self.sq2_button["image"] == "pyimage2": #allows 1 sq movement 221 | return True 222 | if int(self.sq1[1])+1 == int(self.sq2[1]) and (abs(self.ranks.find(self.sq1[0]) - self.ranks.find(self.sq2[0]))) == 1 and self.sq2_button["image"] != "pyimage2": #allows the capturing of diagonal pieces 223 | return True 224 | 225 | 226 | if self.sq1_button["image"] == bp: #black pawn movement 227 | if "7" in self.sq1: #allows for 2 space jump from starting pos 228 | if (int(self.sq1[1]) == int(self.sq2[1])+1 or int(self.sq1[1]) == int(self.sq2[1])+2) and self.sq1[0] == self.sq2[0] and self.sq2_button["image"] == "pyimage2": #only allows it to move straight 1 or 2 sq 229 | return True 230 | if int(self.sq1[1]) == int(self.sq2[1])+1 and self.sq1[0] == self.sq2[0] and self.sq2_button["image"] == "pyimage2": 231 | return True 232 | if int(self.sq1[1]) == int(self.sq2[1])+1 and abs(self.ranks.find(self.sq1[0]) - self.ranks.find(self.sq2[0])) == 1 and self.sq2_button["image"] != "pyimage2": #allows the capturing of diagonal pieces if there is an opponent piece there 233 | return True 234 | 235 | if (self.sq1_button["image"] == wq or self.sq1_button["image"] == bq) and self.clear_path("queen"): #queen movement 236 | if int(self.sq1[1]) == int(self.sq2[1]) or self.sq1[0] == self.sq2[0]: #only allows movement within same rank or file 237 | return True 238 | if abs(int(self.sq1[1]) - int(self.sq2[1])) == abs(self.ranks.find(self.sq1[0]) - self.ranks.find(self.sq2[0])): 239 | return True 240 | 241 | if self.sq1_button["image"] == wr or self.sq1_button["image"] == br: #rook movement 242 | if (int(self.sq1[1]) == int(self.sq2[1]) or self.sq1[0] == self.sq2[0]) and self.clear_path("rook"): #only allows movement within same rank or file 243 | return True 244 | return False 245 | 246 | def castle(self): #checks to see if the move entails a castle, and if a castle is allowed 247 | if self.wk_moved == False: #makes sure king hasn't moved 248 | if self.wr1_moved == False and self.sq2 == "c1": #finds out which way user wants to castle and if the rook has moved (in this case white would want to castle to the left) 249 | for x in range(1,4): #checks to see if squares in between rook and king are empty and are not a possible move for opponent 250 | square_button = self.squares[self.ranks[x]+str(1)] 251 | if square_button["image"] != "pyimage2": 252 | return False 253 | self.squares["a1"].config(image="pyimage2") 254 | self.squares["a1"].image = "pyimage2" 255 | self.squares["d1"].config(image="pyimage7") 256 | self.squares["d1"].image = ("pyimage7") 257 | self.castled = True 258 | return True 259 | if self.wr2_moved == False and self.sq2 == "g1": 260 | for x in range(5,7): #checks to see if squares in between rook and king are empty and are not a possible move for opponent 261 | square_button = self.squares[self.ranks[x]+str(1)] 262 | if square_button["image"] != "pyimage2": 263 | return False 264 | self.squares["h1"].config(image="pyimage2") 265 | self.squares["h1"].image = "pyimage2" 266 | self.squares["f1"].config(image="pyimage7") 267 | self.squares["f1"].image = ("pyimage7") 268 | self.castled = True 269 | return True 270 | if self.bk_moved == False: 271 | if self.br1_moved == False and self.sq2 == "c8": 272 | for x in range(1,3): #checks to see if squares in between rook and king are empty and are not a possible move for opponent 273 | square_button = self.squares[self.ranks[x]+str(8)] 274 | if square_button["image"] != "pyimage2": 275 | return False 276 | self.squares["a8"].config(image="pyimage2") 277 | self.squares["a8"].image = "pyimage2" 278 | self.squares["d8"].config(image="pyimage14") 279 | self.squares["d8"].image = ("pyimage14") 280 | self.castled = True 281 | return True 282 | if self.br2_moved == False and self.sq2 == "g8": 283 | for x in range(5,7): #checks to see if squares in between rook and king are empty and are not a possible move for opponent 284 | square_button = self.squares[self.ranks[x]+str(8)] 285 | if square_button["image"] != "pyimage2": 286 | return False 287 | self.squares["h8"].config(image="pyimage2") 288 | self.squares["h8"].image = "pyimage2" 289 | self.squares["f8"].config(image="pyimage14") 290 | self.squares["f8"].image = ("pyimage14") 291 | self.castled = True 292 | return True 293 | else: 294 | return False 295 | 296 | self.bk_moved = False 297 | self.wr1_moved = False 298 | self.wr2_moved = False 299 | self.br1_moved = False 300 | self.br2_moved = False 301 | 302 | def in_check(self): #prevents a move if king is under attack 303 | previous_sq1 = self.sq1 #stores current values assigned to values 304 | previous_sq1_button = self.sq1_button 305 | previous_sq2 = self.sq2 306 | previous_sq2_button = self.sq2_button 307 | 308 | def return_previous_values(): 309 | self.sq1 = previous_sq1 310 | self.sq1_button = previous_sq1_button 311 | self.sq2 = previous_sq2 312 | self.sq2_button = previous_sq2_button 313 | 314 | if self.piece_color == "white": 315 | self.sq2 = self.find_king("pyimage3") #calls find_king function to find pos of king 316 | for key in self.squares: #iterates through each square 317 | self.sq1 = key 318 | self.sq1_button = self.squares[self.sq1] 319 | if self.sq1_button["image"] in self.black_pieces: 320 | if self.allowed_piece_move(): #checks to see if the king's current pos is a possible move for the piece 321 | return True 322 | if self.piece_color == "black": 323 | self.sq2 = self.find_king("pyimage10") 324 | for key in self.squares: 325 | self.sq1 = key 326 | self.sq1_button = self.squares[self.sq1] 327 | if self.sq1_button["image"] in self.white_pieces: 328 | if self.allowed_piece_move(): 329 | return True 330 | return_previous_values() 331 | return False 332 | 333 | def find_king(self, king): #finds the square where the king is currently on 334 | for square in self.squares: 335 | button = self.squares[square] 336 | if button["image"] == king: 337 | return square 338 | 339 | def set_squares(self): #fills frame with buttons representing squares 340 | 341 | for x in range(8): 342 | for y in range(8): 343 | if x%2==0 and y%2==0: #alternates between dark/light tiles 344 | self.square_color="tan4" 345 | elif x%2==1 and y%2==1: 346 | self.square_color="tan4" 347 | else: 348 | self.square_color="burlywood1" 349 | 350 | B = tk.Button(self, bg=self.square_color, activebackground="lawn green") 351 | B.grid(row=8-x, column=y) 352 | pos = self.ranks[y]+str(x+1) 353 | self.squares.setdefault(pos, B) #creates list of square positions 354 | self.squares[pos].config(command= lambda key=self.squares[pos]: self.select_piece(key)) 355 | 356 | def import_pieces(self): #opens and stores images of pieces and prepares the pieces for the game for both sides 357 | path = os.path.join(os.path.dirname(__file__), "White") #stores white pieces images into dicts 358 | w_dirs = os.listdir(path) 359 | for file in w_dirs: 360 | img = Image.open(path+"\\"+file) 361 | img = img.resize((80,80), Image.ANTIALIAS) 362 | img = ImageTk.PhotoImage(image=img) 363 | self.white_images.setdefault(file, img) 364 | 365 | path = os.path.join(os.path.dirname(__file__), "Black") #stores black pieces images into dicts 366 | b_dirs = os.listdir(path) 367 | for file in b_dirs: 368 | img = Image.open(path+"\\"+file) 369 | img = img.resize((80,80), Image.ANTIALIAS) 370 | img = ImageTk.PhotoImage(image=img) 371 | self.black_images.setdefault(file, img) 372 | 373 | def set_pieces(self): #places pieces in starting positions 374 | dict_rank1_pieces = {"a1":"r.png", "b1":"n.png", "c1":"b.png", "d1":"q.png", "e1":"k.png", "f1":"b.png", "g1":"n.png", "h1":"r.png"} #assigning positions with their default pieces 375 | dict_rank2_pieces = {"a2":"p.png", "b2":"p.png", "c2":"p.png", "d2":"p.png", "e2":"p.png", "f2":"p.png", "g2":"p.png", "h2":"p.png"} 376 | dict_rank7_pieces = {"a7":"p.png", "b7":"p.png", "c7":"p.png", "d7":"p.png", "e7":"p.png", "f7":"p.png", "g7":"p.png", "h7":"p.png"} 377 | dict_rank8_pieces = {"a8":"r.png", "b8":"n.png", "c8":"b.png", "d8":"q.png", "e8":"k.png", "f8":"b.png", "g8":"n.png", "h8":"r.png"} 378 | 379 | for key in dict_rank1_pieces: #inserts images into buttons 380 | starting_piece = dict_rank1_pieces[key] 381 | self.squares[key].config(image=self.white_images[starting_piece]) 382 | self.squares[key].image = self.white_images[starting_piece] 383 | 384 | for key in dict_rank2_pieces: 385 | starting_piece = dict_rank2_pieces[key] 386 | self.squares[key].config(image=self.white_images[starting_piece]) 387 | self.squares[key].image = self.white_images[starting_piece] 388 | 389 | for key in dict_rank7_pieces: 390 | starting_piece = dict_rank7_pieces[key] 391 | self.squares[key].config(image=self.black_images[starting_piece]) 392 | self.squares[key].image = self.black_images[starting_piece] 393 | 394 | for key in dict_rank8_pieces: 395 | starting_piece = dict_rank8_pieces[key] 396 | self.squares[key].config(image=self.black_images[starting_piece]) 397 | self.squares[key].image = self.black_images[starting_piece] 398 | 399 | for rank in range(3,7): #fill rest with blank pieces 400 | for file in range(8): 401 | starting_piece = "blank.png" 402 | pos = self.ranks[file]+str(rank) 403 | self.squares[pos].config(image=self.white_images[starting_piece]) 404 | self.squares[pos].image = self.white_images[starting_piece] 405 | 406 | root = tk.Tk() #creates main window with the board and creates board object 407 | root.geometry("800x800") 408 | board = Board(root, 8, 8) 409 | board.import_pieces() 410 | board.set_pieces() 411 | board.mainloop() 412 | -------------------------------------------------------------------------------- /Chess Program/White/b.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ransurf/pythonchessprogram/d4fa3f4b07d03291c6c75441e54fe901dedc5814/Chess Program/White/b.png -------------------------------------------------------------------------------- /Chess Program/White/blank.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ransurf/pythonchessprogram/d4fa3f4b07d03291c6c75441e54fe901dedc5814/Chess Program/White/blank.png -------------------------------------------------------------------------------- /Chess Program/White/k.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ransurf/pythonchessprogram/d4fa3f4b07d03291c6c75441e54fe901dedc5814/Chess Program/White/k.png -------------------------------------------------------------------------------- /Chess Program/White/n.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ransurf/pythonchessprogram/d4fa3f4b07d03291c6c75441e54fe901dedc5814/Chess Program/White/n.png -------------------------------------------------------------------------------- /Chess Program/White/p.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ransurf/pythonchessprogram/d4fa3f4b07d03291c6c75441e54fe901dedc5814/Chess Program/White/p.png -------------------------------------------------------------------------------- /Chess Program/White/q.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ransurf/pythonchessprogram/d4fa3f4b07d03291c6c75441e54fe901dedc5814/Chess Program/White/q.png -------------------------------------------------------------------------------- /Chess Program/White/r.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ransurf/pythonchessprogram/d4fa3f4b07d03291c6c75441e54fe901dedc5814/Chess Program/White/r.png -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # pythonchessprogram 2 | Very scuffed python chess program I made for a high school project 3 | 4 | ## Missing features: 5 | - Preventing castling when tiles on path are under attack by opposing pieces 6 | - Preventing castling when king is in check 7 | - En passant 8 | - Organization lul 9 | --------------------------------------------------------------------------------