Simran's Chess
Simran's Chess
from PIL import Image, ImageTk #help with implementing images into GUI
class Board(tk.Frame):
tk.Frame.__init__(self, parent)
self.parent = parent
self.length = length
self.width = width
self.config(height=100*self.length, width=100*self.width)
self.pack()
self.square_color = None
self.ranks = string.ascii_lowercase
self.black_images = {}
self.buttons_pressed = 0
self.turns = 0
self.sq2 = None
self.sq2_button = None
self.piece_color = None
self.bk_moved = False
self.wr1_moved = False
self.wr2_moved = False
self.br1_moved = False
self.br2_moved = False
self.castled = False
self.set_squares()
def select_piece(self, button): #called when a square button is pressed, consists of majority of the
movement code
self.piece_color = "white"
self.piece_color = "black"
self.sq1_button = button
self.buttons_pressed += 1
self.sq2 = list(self.squares.keys())[list(self.squares.values()).index(button)]
self.sq2_button = button
if self.sq2 == self.sq1: #prevents self-destruction and allows the user to choose a new piece
self.buttons_pressed = 0
return
if self.allowed_piece_move() and self.friendly_fire() == False: #makes sure the move is legal
prev_sq1 = self.sq1
prev_sq1_button_piece = self.sq1_button["image"]
prev_sq2 = self.sq2
prev_sq2_button_piece = self.sq2_button["image"]
self.squares[self.sq2].image = self.sq1_button["image"]
self.squares[self.sq1].image = self.white_images["blank.png"]
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
self.squares[prev_sq2].image = prev_sq2_button_piece
self.squares[prev_sq1].config(image=prev_sq1_button_piece)
self.squares[prev_sq1].image = prev_sq1_button_piece
self.buttons_pressed = 0
return
else: #runs if king is not in check, checks if kings or rooks have moved, preventing castling
in the future
if prev_sq1_button_piece == "pyimage3":
self.wk_moved = True
if prev_sq1_button_piece == "pyimage10":
self.bk_moved = True
self.wr1_moved = True
self.wr2_moved = True
self.br1_moved = True
self.buttons_pressed = 0
self.turns += 1
self.promotion_menu(self.piece_color)
self.castled = False
else:
self.buttons_pressed = 0
return
def promotion_menu(self, color): #creates menu to choose what piece to change the pawn to
def return_piece(piece): #function called by buttons to make the change and destroy window
self.squares[self.sq2].config(image=piece)
self.squares[self.sq2].image = piece
promo.destroy()
return
promo = tk.Tk() #creates a new menu with buttons depending on pawn color
if color=="white":
promo_knight.grid(row=0, column=0)
promo_bishop.grid(row=0, column=1)
promo_rook.grid(row=1, column=0)
promo_queen.grid(row=1, column=1)
elif color=="black":
promo_knight.grid(row=0, column=0)
promo_bishop.grid(row=0, column=1)
promo_rook.grid(row=1, column=0)
promo_queen.grid(row=1, column=1)
promo.mainloop()
return
piece_2_color = self.sq2_button["image"]
return True
return True
else:
return False
def clear_path(self, piece): #makes sure that the squares in between sq1 and sq2 aren't occupied
square_on_path = self.squares[self.sq1[0]+str(i)].cget("image")
if square_on_path != "pyimage2":
return False
square_on_path = self.squares[self.ranks[i]+self.sq1[1]].cget("image")
if square_on_path != "pyimage2":
return False
x1 = self.ranks.find(self.sq1[0])
x2 = self.ranks.find(self.sq2[0])
y1 = int(self.sq1[1])
y2 = int(self.sq2[1])
if y1<y2:
y1 += 1
square_on_path = self.squares[self.ranks[x]+str(y1)].cget("image")
if square_on_path != "pyimage2":
return False
y1 += 1
square_on_path = self.squares[self.ranks[x]+str(y1)].cget("image")
if square_on_path != "pyimage2":
return False
elif y1>y2:
if x1<x2: #SE direction
y1 -= 1
square_on_path = self.squares[self.ranks[x]+str(y1)].cget("image")
if square_on_path != "pyimage2":
return False
y1 -= 1
square_on_path = self.squares[self.ranks[x]+str(y1)].cget("image")
if square_on_path != "pyimage2":
return False
return True
def allowed_piece_move(self): #checks whether the piece can move to square 2 with respect to
their movement capabilities
wb, wk, wn, wp, wq, wr = "pyimage1", "pyimage3", "pyimage4", "pyimage5", "pyimage6",
"pyimage7" #redefining pyimages for readability
bb, bk, bn, bp, bq, br = "pyimage8", "pyimage10", "pyimage11", "pyimage12", "pyimage13",
"pyimage14"
return False
return True
return True
return True
return True
if self.castle() is True:
return True
return True
return True
return True
return True
return True
return True
return True
return True
return True
return False
def castle(self): #checks to see if the move entails a castle, and if a castle is allowed
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)
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
square_button = self.squares[self.ranks[x]+str(1)]
if square_button["image"] != "pyimage2":
return False
self.squares["a1"].config(image="pyimage2")
self.squares["a1"].image = "pyimage2"
self.squares["d1"].config(image="pyimage7")
self.squares["d1"].image = ("pyimage7")
self.castled = True
return True
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
square_button = self.squares[self.ranks[x]+str(1)]
if square_button["image"] != "pyimage2":
return False
self.squares["h1"].config(image="pyimage2")
self.squares["h1"].image = "pyimage2"
self.squares["f1"].config(image="pyimage7")
self.squares["f1"].image = ("pyimage7")
self.castled = True
return True
if self.bk_moved == False:
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
square_button = self.squares[self.ranks[x]+str(8)]
if square_button["image"] != "pyimage2":
return False
self.squares["a8"].config(image="pyimage2")
self.squares["a8"].image = "pyimage2"
self.squares["d8"].config(image="pyimage14")
self.squares["d8"].image = ("pyimage14")
self.castled = True
return True
if self.br2_moved == False and self.sq2 == "g8":
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
square_button = self.squares[self.ranks[x]+str(8)]
if square_button["image"] != "pyimage2":
return False
self.squares["h8"].config(image="pyimage2")
self.squares["h8"].image = "pyimage2"
self.squares["f8"].config(image="pyimage14")
self.squares["f8"].image = ("pyimage14")
self.castled = True
return True
else:
return False
self.bk_moved = False
self.wr1_moved = False
self.wr2_moved = False
self.br1_moved = False
self.br2_moved = False
previous_sq1_button = self.sq1_button
previous_sq2 = self.sq2
previous_sq2_button = self.sq2_button
def return_previous_values():
self.sq1 = previous_sq1
self.sq1_button = previous_sq1_button
self.sq2 = previous_sq2
self.sq2_button = previous_sq2_button
if self.piece_color == "white":
self.sq1 = key
self.sq1_button = self.squares[self.sq1]
if self.sq1_button["image"] in self.black_pieces:
return True
if self.piece_color == "black":
self.sq2 = self.find_king("pyimage10")
self.sq1 = key
self.sq1_button = self.squares[self.sq1]
if self.sq1_button["image"] in self.white_pieces:
if self.allowed_piece_move():
return True
return_previous_values()
return False
def find_king(self, king): #finds the square where the king is currently on
button = self.squares[square]
if button["image"] == king:
return square
for x in range(8):
for y in range(8):
self.square_color="tan4"
self.square_color="tan4"
else:
self.square_color="burlywood1"
B.grid(row=8-x, column=y)
pos = self.ranks[y]+str(x+1)
def import_pieces(self): #opens and stores images of pieces and prepares the pieces for the game
for both sides
w_dirs = os.listdir(path)
img = Image.open(path+"\\"+file)
img = ImageTk.PhotoImage(image=img)
self.white_images.setdefault(file, img)
b_dirs = os.listdir(path)
img = Image.open(path+"\\"+file)
img = ImageTk.PhotoImage(image=img)
self.black_images.setdefault(file, img)
def set_pieces(self): #places pieces in starting positions
starting_piece = dict_rank1_pieces[key]
self.squares[key].config(image=self.white_images[starting_piece])
self.squares[key].image = self.white_images[starting_piece]
starting_piece = dict_rank2_pieces[key]
self.squares[key].config(image=self.white_images[starting_piece])
self.squares[key].image = self.white_images[starting_piece]
starting_piece = dict_rank7_pieces[key]
self.squares[key].config(image=self.black_images[starting_piece])
self.squares[key].image = self.black_images[starting_piece]
starting_piece = dict_rank8_pieces[key]
self.squares[key].config(image=self.black_images[starting_piece])
self.squares[key].image = self.black_images[starting_piece]
starting_piece = "blank.png"
pos = self.ranks[file]+str(rank)
self.squares[pos].config(image=self.white_images[starting_piece])
self.squares[pos].image = self.white_images[starting_piece]
root = tk.Tk() #creates main window with the board and creates board object
root.geometry("800x800")
board = Board(root, 8, 8)
board.import_pieces()
board.set_pieces()
board.mainloop()