1

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.

2
  • I suggest you try another naming convention than lower / upper case as you use some .lower() in your code that seems to be a probleme here. Maybee adding a letter for the color like : pb / pw . I have not all the files so i cannot test. Commented Dec 22, 2023 at 10:49
  • could it be that since each player has 16 pieces, you simply never update the second loop to start from 15 and instead just place images starting from the beginning again, resulting in the same images for the other player too? Commented Dec 22, 2023 at 19:37

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.