Script for Chess GUI not loading the right images when execute?

41 Views Asked by At

I have this simple code using Python that will allow me to play chess against Stockfish. I also implemented a simple GUI that helps visualize the pieces easier. I have name the black pieces images "p", "r", "n", "b", "q", "k", and for the white pieces: "P", "R", "N", "B", "Q", "K". However, at first the script was loading the black pieces for both sides, so I figured the problem was with the naming of the white pieces, as Windows inserted (2) after the file names. I changed the code a little bit, but now it's only loading the images of white pieces for both sides.

import chess
import chess.engine
import tkinter as tk
from tkinter import simpledialog, messagebox
from PIL import Image, ImageTk
import os
import fnmatch


class ChessGUI(tk.Tk):
    def __init__(self):
        super().__init__()

        self.title("Chess Game")
        self.geometry("600x600")

        self.canvas = tk.Canvas(self, width=600, height=600, bg="white")
        self.canvas.pack(fill=tk.BOTH, expand=True)

        self.board = chess.Board()
        self.load_piece_images()

        self.draw_board()
 

    def load_piece_images(self):
        self.piece_images = {}
        piece_symbols = ["p", "r", "n", "b", "q", "k", "P", "R", "N", "B", "Q", "K"]

        for piece_symbol in piece_symbols:
            try:
            # Use fnmatch to perform case-insensitive matching
                files = [f for f in os.listdir("pieces") if fnmatch.fnmatch(f, f"{piece_symbol}*") and f.lower().endswith(".png")]
                if files:
                    img_path = f"pieces/{files[0]}"
                    img = Image.open(img_path)
                    img = img.resize((75, 75), Image.BILINEAR)
                    key = piece_symbol.lower()
                    self.piece_images[key] = ImageTk.PhotoImage(img)
                    print(f"Loaded image for {piece_symbol} from {img_path}")
                else:
                    print(f"No matching image found for {piece_symbol}. Skipping.")
            except FileNotFoundError:
                print(f"Error loading image for {piece_symbol}. Skipping.")





    def draw_board(self):
        self.canvas.delete("all")

        for square in chess.SQUARES:
            rank, file = chess.square_rank(square), chess.square_file(square)
            color = "white" if (rank + file) % 2 == 0 else "black"
            x, y = file * 75, (7 - rank) * 75

            self.canvas.create_rectangle(x, y, x + 75, y + 75, fill=color)

            piece = self.board.piece_at(square)
            if piece:
            # Print the piece symbol for troubleshooting
                print(piece.symbol())
            # Convert the piece symbol to lowercase for dictionary access
                piece_image = self.piece_images[piece.symbol().lower()]
                self.canvas.create_image(x + 37.5, y + 37.5, image=piece_image)


    def get_user_move(self):
        user_move = simpledialog.askstring("Your Move", "Enter your move (in UCI format, e.g., e2e4):")
        try:
            self.board.push_uci(user_move)
            self.draw_board()
        except ValueError:
            messagebox.showerror("Invalid Move", "Invalid move. Try again.")
            self.get_user_move()

    def get_stockfish_move(self):
        stockfish_path = "D:/Test/stockfish/stockfish.exe"  # Replace with the actual path to Stockfish
        with chess.engine.SimpleEngine.popen_uci(stockfish_path) as engine:
            result = engine.play(self.board, chess.engine.Limit(time=2.0))
            return result.move

    def play_game(self):
        while not self.board.is_game_over():
            self.draw_board()

            if self.board.turn == chess.WHITE:
                self.get_user_move()
            else:
                stockfish_move = self.get_stockfish_move()
                self.board.push(stockfish_move)

        self.draw_board()
        messagebox.showinfo("Game Over", f"Game Over!\nResult: {self.board.result()}")

if __name__ == "__main__":
    chess_gui = ChessGUI()
    chess_gui.play_game()
    chess_gui.mainloop()

I tried changing the load_piece_images part, but the only thing that changed was that instead of using black pieces for both sides, the white pieces images loaded instead. I also tried changing the draw_board part, but things didn't change. I expected that both sides would be loaded with their respective color, but it only loads either of them. I changed the file names too, but then the GUI wouldn't even start.

0

There are 0 best solutions below