1

I want to develop a chess game in pygame.I have just created the chessboard using two classes: the Board class and the Square class.I am basically creating some square objects that have a bunch of attributes hoping that in the future they might come in handy.But now I am facing a problem: whenever I right click on some square I want it to turn red.However, even if I have for every square an attribute square.rect, I have stored all my rects in a list, and now I do not quite know how to deal with the condition: if mouse is in some rect_object then turn red.How can I check if mouse is entered the boundaries of a specific square given that I stored all this rectangles in a list.Basically the question is, how can i access each square and change the attribute self.color (I know how to use the collidepoint method but my issue is more of a design issue, probably ;).Thanks in advance.

this is my board.py file

"""
File that creates the board object
"""
import pygame
from typing import List, Tuple, Dict

class Board:
    """
    Class that creates a board object and draws it onto the screen:

    CLASS VARIABLES:
    1. ROWS ===> list containing all the numbers that label a row.
    2. COLUMNS ===> list containing all the letter that label a column

    ATTRIBUTES:
    1. squares: List[Square] ===> List of square objects
    2. surface_board: pygame.Surface ===> Gets the surface board
    2. top: int ===> distance from the top in the screen.
    3. left: int ===> distance from the left in the screen.

    METHODS:
    1. draw_board ===> by using all the squares in the self.squares list it draws them in the surface board
    2. get_all_squares ===> fills the list of squares populating it with square objects
    3. increment_top ===> increments the top of each square by the height of the square and makes the left go to 0.
    4. increment_left ===> increments the left of each square by the width of the square.
    """

    DIMENSIONS = (680, 680)
    ROWS = [1, 2, 3, 4, 5, 6, 7, 8]
    COLUMNS = ["a", "b", "c", "d", "e", "f", "g", "h"]

    def __init__(self, top, left):
        self.top = top
        self.left = left
        self.squares: List[Square] = []
        self.get_all_squares()

    def increment_top(self):
        self.top += Square.HEIGHT
        self.left -= Square.WIDTH * 7

    def increment_left(self):
        self.left += Square.WIDTH

    def draw_board(self, surface):
        for square in self.squares:
            pygame.draw.rect(surface, square.color, square.rect)

    def get_all_squares(self):
        pointer_col = 1
        pointer_row = 1
        for number in Board.ROWS:
            for letter in Board.COLUMNS:
                square = Square(self.left, self.top)
                square.position = (letter, number)
                square.create_id()
                square.pick_color(pointer_col, pointer_row)
                if pointer_col < 8:
                    self.increment_left()
                    pointer_col += 1
                else:
                    self.increment_top()
                    pointer_col = 1
                    pointer_row += 1
                self.squares.append(square)


class Square:
    """
    Class that creates a square object.

    CLASS VARIABLES:
    GREENISH = 128, 194, 175 ===> Green color for even squares.
    WHITE = 255, 255, 255 ===> White color for odd squares.
    WIDTH ===> width of each square.
    HEIGHT ===> height of each square.

    ATTRIBUTES:
    1. id: string ===> Every square is going to have an id like a1 or h3 based on its coordinates.
    2. position: tuple ===> Tuple that stores the row and the column.
    3. active: bool ===> It says if a square is active (has been clicked etc) or not.
    4. color: tuple ===> Tuple with one of the color contained in the class board.
    5. left: int ===> distance from the left.
    6. top: int ===> distance from the top.

    METHOD:
    1. create_id ===> creates the id out of the coordinates.
    2. get_square_surface ===> Return the surface with a square drawn on it.
    3. pick_color ===> depending on the number of the column it picks the appropriate color.
    4. get_square_rect ===> get the Rect of the square
    """
    WHITE = 255, 255, 255
    GREENISH = 128, 194, 175
    WIDTH = Board.DIMENSIONS[0] / 8
    HEIGHT = Board.DIMENSIONS[0] / 8

    def __init__(self, left, top):
        self.left = left
        self.top = top
        self.id = ""
        self.position = ()
        self.active = False
        self.color = None
        self.rect = pygame.Rect(self.left, self.top, Square.WIDTH, Square.HEIGHT)


    def pick_color(self, num_column, num_row):
        if abs(num_column - num_row) % 2 == 0:
            self.color = Square.GREENISH
            return
        self.color = Square.WHITE
        return

    def create_id(self):
        self.id = self.position[0] + str(self.position[1])

this is my main.py file:

mport pygame, sys
from board_and_graphics.board import Board
from game_logic.click_events import Checker

checker = Checker()
class Game:
    SIZE = 1000,1000
    SCREEN_COLOR = 255, 255, 255
    def __init__(self):
        pygame.init()
        self.screen = pygame.display.set_mode(Game.SIZE, pygame.RESIZABLE)
        self.running = True

    def start(self):
        board = Board(0, 0)
        board.draw_board(self.screen)
        while self.running:

            for event in pygame.event.get():
                if event.type == pygame.QUIT: self.running = False
                if event.type == pygame.MOUSEBUTTONDOWN:
                    if pygame.mouse.get_pressed()[2]:
                        checker.check_boundaries(board.squares)
            pygame.display.update()

if __name__ == '__main__':
    game = Game()
    game.start()


and this is the first file of my game_logic directory some methods are still not implemented but when I understand how to deal with this problem than it’s gonna be quite easy to code them.


"""
Script that adds some functionalities: whenever the user rigthclicks
on the squares the square becomes active and becomes red.
"""

from board_and_graphics.board import Square, Board
import pygame

class Checker:
    """
    Class tries to detect right clicks and left clicks on the board

    METHODS:
    1. check_boundaries ===> check if the mouse is inside the screen
    2. set_color_rect ===> change the actual color of the rectangle to red
    3. get_left_click ===> if a left click happens while some of the squares are red than
                            the color of all the rectangles is reset.

    """
    def __init__(self):
        self.active_square = False

    def check_boundaries(self, objects):
        mouse = pygame.mouse.get_pos()
        for object in objects:
            if object.rect.collidepoint(mouse):
                object.color = (0, 0, 0)


  • You get the row and column by dividing the mouse position `column = mosue[0] // Square.WIDTH` and `row = mouse[1] // Square.HEIGHT`. See [Python: How to make drawn elements snap to grid in pygame](https://stackoverflow.com/questions/63926261/python-how-to-make-drawn-elements-snap-to-grid-in-pygame/63926759#63926759). You may also find some help in the answer to [How to use a dictionary of images with sprite?](https://stackoverflow.com/questions/66467383/how-to-use-a-dictionary-of-images-with-sprite/66514748#66514748) – Rabbid76 Oct 26 '21 at 19:40

1 Answers1

0

You get the row and column by dividing the mouse coordinates by the size of a tile:

for event in pygame.event.get():
    # [...]
    
    if event.type == pygame.MOUSEBUTTONDOWN:
        if event.button == 3: # right button
            column = (event.pos[0] - board.left) // Square.WIDTH
            row = (event.pos[1] - board.top) // Square.HEIGHT
   
            # [...]
Rabbid76
  • 202,892
  • 27
  • 131
  • 174