-1

My application is written using the latest versions of Python 3.7, PyQt5 and python-chess. I have an SVG chessboard, produced by python-chess itself. My application handles mouse clicks on the chessboard which highlight the clicked square. I have a problem with precision. Sometimes the adjacent square is highlighted. I also have the chessboard coordinates on the left and on the top of the chessboard which are the root cause of my bug. Without the chessboard coordinates it works perfectly.

If anyone is interested in helping me, here's the code.

import chess
import chess.svg

from PyQt5.QtCore import pyqtSlot
from PyQt5.QtSvg import QSvgWidget


COORDINATES = True
FLIPPED = False


class Chessboard(QSvgWidget):

    def __init__(self):
        super().__init__()

        self.clicked_square = -20
        self.move_from_square = -20
        self.move_to_square = -20
        self.piece_to_move = [None, None]

        viewbox_size = 400
        self.margin = chess.svg.MARGIN * 800 / viewbox_size if COORDINATES else 0
        self.file_size = chess.svg.SQUARE_SIZE * 800 / viewbox_size
        self.rank_size = chess.svg.SQUARE_SIZE * 800 / viewbox_size

        self.chessboard = chess.Board()
        self.draw_chessboard()

    @pyqtSlot(QSvgWidget)
    def mousePressEvent(self, event):
        x_coordinate = event.x()
        y_coordinate = event.y()

        file = int(x_coordinate / 800 * 8)
        rank = 7 - int(y_coordinate / 800 * 8)

        if file < 0:
            file = 0

        if rank < 0:
            rank = 0

        if file > 7:
            file = 7

        if rank > 7:
            rank = 7

        self.clicked_square = chess.square(file, rank)
        piece = self.chessboard.piece_at(self.clicked_square)

        file_character = chr(file + 97)
        rank_number = str(rank + 1)
        ply = f"{file_character}{rank_number}"

        if self.piece_to_move[0]:
            move = chess.Move.from_uci(f"{self.piece_to_move[1]}{ply}")
            if move in self.chessboard.legal_moves:
                self.chessboard.push(move)

                self.move_from_square = move.from_square
                self.move_to_square = move.to_square

                piece = None
                ply = None

        self.piece_to_move = [piece, ply]
        self.draw_chessboard()

    def draw_chessboard(self):
        is_it_check = self.chessboard.king(self.chessboard.turn) \
                      if self.chessboard.is_check() \
                      else None
        self.svg_chessboard = chess.svg.board(board=self.chessboard,
                                              lastmove=chess.Move(from_square=self.move_from_square,
                                                                  to_square=self.move_to_square),
                                              arrows=[(self.clicked_square, self.clicked_square),
                                                      (self.move_from_square, self.move_to_square)],
                                              check=is_it_check,
                                              flipped=FLIPPED,
                                              coordinates=COORDINATES,
                                              size=800)
        self.svg_chessboard_encoded = self.svg_chessboard.encode("utf-8")
        self.load(self.svg_chessboard_encoded)
Boštjan Mejak
  • 827
  • 9
  • 23

1 Answers1

-1

My solution I ended up with is this:

"""
Docstring.
"""

import chess
import chess.svg

from PyQt5.QtCore import pyqtSlot
from PyQt5.QtSvg import QSvgWidget

COORDINATES = True
FLIPPED = False


class Chessboard(QSvgWidget):
    """
    Docstring.
    """

    def __init__(self):
        """
        Docstring.
        """
        super().__init__()

        self.clicked_square = -20
        self.move_from_square = -20
        self.move_to_square = -20
        self.piece_to_move = [None, None]

        self.chessboard = chess.Board()
        self.draw_chessboard()

    @pyqtSlot(QSvgWidget)
    def mousePressEvent(self, event):
        """
        Docstring.
        """
        x_position = event.x()
        y_position = event.y()

        file_a = x_position in range(40, 131)
        file_b = x_position in range(130, 221)
        file_c = x_position in range(220, 311)
        file_d = x_position in range(310, 401)
        file_e = x_position in range(400, 491)
        file_f = x_position in range(490, 581)
        file_g = x_position in range(580, 671)
        file_h = x_position in range(670, 761)

        rank_1 = y_position in range(670, 761)
        rank_2 = y_position in range(580, 671)
        rank_3 = y_position in range(490, 581)
        rank_4 = y_position in range(400, 491)
        rank_5 = y_position in range(310, 401)
        rank_6 = y_position in range(220, 311)
        rank_7 = y_position in range(130, 221)
        rank_8 = y_position in range(40, 131)

        a1 = file_a and rank_1
        b1 = file_b and rank_1
        c1 = file_c and rank_1
        d1 = file_d and rank_1
        e1 = file_e and rank_1
        f1 = file_f and rank_1
        g1 = file_g and rank_1
        h1 = file_h and rank_1

        a2 = file_a and rank_2
        b2 = file_b and rank_2
        c2 = file_c and rank_2
        d2 = file_d and rank_2
        e2 = file_e and rank_2
        f2 = file_f and rank_2
        g2 = file_g and rank_2
        h2 = file_h and rank_2

        a3 = file_a and rank_3
        b3 = file_b and rank_3
        c3 = file_c and rank_3
        d3 = file_d and rank_3
        e3 = file_e and rank_3
        f3 = file_f and rank_3
        g3 = file_g and rank_3
        h3 = file_h and rank_3

        a4 = file_a and rank_4
        b4 = file_b and rank_4
        c4 = file_c and rank_4
        d4 = file_d and rank_4
        e4 = file_e and rank_4
        f4 = file_f and rank_4
        g4 = file_g and rank_4
        h4 = file_h and rank_4

        a5 = file_a and rank_5
        b5 = file_b and rank_5
        c5 = file_c and rank_5
        d5 = file_d and rank_5
        e5 = file_e and rank_5
        f5 = file_f and rank_5
        g5 = file_g and rank_5
        h5 = file_h and rank_5

        a6 = file_a and rank_6
        b6 = file_b and rank_6
        c6 = file_c and rank_6
        d6 = file_d and rank_6
        e6 = file_e and rank_6
        f6 = file_f and rank_6
        g6 = file_g and rank_6
        h6 = file_h and rank_6

        a7 = file_a and rank_7
        b7 = file_b and rank_7
        c7 = file_c and rank_7
        d7 = file_d and rank_7
        e7 = file_e and rank_7
        f7 = file_f and rank_7
        g7 = file_g and rank_7
        h7 = file_h and rank_7

        a8 = file_a and rank_8
        b8 = file_b and rank_8
        c8 = file_c and rank_8
        d8 = file_d and rank_8
        e8 = file_e and rank_8
        f8 = file_f and rank_8
        g8 = file_g and rank_8
        h8 = file_h and rank_8

        file = 0
        rank = 0

        if a1:
            file = 0
            rank = 0
        elif b1:
            file = 1
            rank = 0
        elif c1:
            file = 2
            rank = 0
        elif d1:
            file = 3
            rank = 0
        elif e1:
            file = 4
            rank = 0
        elif f1:
            file = 5
            rank = 0
        elif g1:
            file = 6
            rank = 0
        elif h1:
            file = 7
            rank = 0
        elif a2:
            file = 0
            rank = 1
        elif b2:
            file = 1
            rank = 1
        elif c2:
            file = 2
            rank = 1
        elif d2:
            file = 3
            rank = 1
        elif e2:
            file = 4
            rank = 1
        elif f2:
            file = 5
            rank = 1
        elif g2:
            file = 6
            rank = 1
        elif h2:
            file = 7
            rank = 1
        elif a3:
            file = 0
            rank = 2
        elif b3:
            file = 1
            rank = 2
        elif c3:
            file = 2
            rank = 2
        elif d3:
            file = 3
            rank = 2
        elif e3:
            file = 4
            rank = 2
        elif f3:
            file = 5
            rank = 2
        elif g3:
            file = 6
            rank = 2
        elif h3:
            file = 7
            rank = 2
        elif a4:
            file = 0
            rank = 3
        elif b4:
            file = 1
            rank = 3
        elif c4:
            file = 2
            rank = 3
        elif d4:
            file = 3
            rank = 3
        elif e4:
            file = 4
            rank = 3
        elif f4:
            file = 5
            rank = 3
        elif g4:
            file = 6
            rank = 3
        elif h4:
            file = 7
            rank = 3
        elif a5:
            file = 0
            rank = 4
        elif b5:
            file = 1
            rank = 4
        elif c5:
            file = 2
            rank = 4
        elif d5:
            file = 3
            rank = 4
        elif e5:
            file = 4
            rank = 4
        elif f5:
            file = 5
            rank = 4
        elif g5:
            file = 6
            rank = 4
        elif h5:
            file = 7
            rank = 4
        elif a6:
            file = 0
            rank = 5
        elif b6:
            file = 1
            rank = 5
        elif c6:
            file = 2
            rank = 5
        elif d6:
            file = 3
            rank = 5
        elif e6:
            file = 4
            rank = 5
        elif f6:
            file = 5
            rank = 5
        elif g6:
            file = 6
            rank = 5
        elif h6:
            file = 7
            rank = 5
        elif a7:
            file = 0
            rank = 6
        elif b7:
            file = 1
            rank = 6
        elif c7:
            file = 2
            rank = 6
        elif d7:
            file = 3
            rank = 6
        elif e7:
            file = 4
            rank = 6
        elif f7:
            file = 5
            rank = 6
        elif g7:
            file = 6
            rank = 6
        elif h7:
            file = 7
            rank = 6
        elif a8:
            file = 0
            rank = 7
        elif b8:
            file = 1
            rank = 7
        elif c8:
            file = 2
            rank = 7
        elif d8:
            file = 3
            rank = 7
        elif e8:
            file = 4
            rank = 7
        elif f8:
            file = 5
            rank = 7
        elif g8:
            file = 6
            rank = 7
        elif h8:
            file = 7
            rank = 7

        self.clicked_square = chess.square(file,
                                           rank)
        piece = self.chessboard.piece_at(self.clicked_square)

        file_character = chr(file + 97)
        rank_number = str(rank + 1)
        ply = f"{file_character}{rank_number}"

        if self.piece_to_move[0]:
            move = chess.Move.from_uci(f"{self.piece_to_move[1]}{ply}")
            if move in self.chessboard.legal_moves:
                self.chessboard.push(move)

                self.move_from_square = move.from_square
                self.move_to_square = move.to_square

                piece = None
                ply = None

        self.piece_to_move = [piece, ply]
        self.draw_chessboard()

    def draw_chessboard(self):
        """
        Docstring.
        """
        is_it_check = self.chessboard.king(self.chessboard.turn) \
                      if self.chessboard.is_check() \
                      else None
        self.svg_chessboard = chess.svg.board(board=self.chessboard,
                                              lastmove=chess.Move(from_square=self.move_from_square,
                                                                  to_square=self.move_to_square),
                                              arrows=[(self.clicked_square, self.clicked_square),
                                                      (self.move_from_square, self.move_to_square)],
                                              check=is_it_check,
                                              flipped=FLIPPED,
                                              coordinates=COORDINATES,
                                              size=800)
        self.svg_chessboard_encoded = self.svg_chessboard.encode("utf-8")
        self.load(self.svg_chessboard_encoded)
Boštjan Mejak
  • 827
  • 9
  • 23