Search code examples
pythonpython-3.xpygameminesweeper

Trying to code a grid of squares that disappear when clicked, wrong squares disappear and I have no idea why


I am new to programming and I decided to code the game minesweeper as a way to exercise. To do this, I started by creating a code that makes a grid of 10 x 10 cells that disappear when clicked. However the squares when clicked sometimes make other squares disappear in an unpredictable way.

Here is a gif showing what happens :

square_disappearing

Clicking the same square could make multiple squares disappear or not and I have no idea what triggers it, which makes me think the problem might not come from my code ? By the way here it is :

import pygame
import sys
listeSuppr = []  # list of squares that shouldn't be drawn
pygame.init()
WIDTH = 800
HEIGHT = 800
GREY = (50, 50, 50)
BLACK = (0, 0, 0)


def add_to_list(a, liste_locale):            # looks at the position of the mouse and says what square it corresponds to
    a = pygame.mouse.get_pos()               # then adds it to the list of squares that shouldn't be drawn (listeSuppr)
    print(a)
    for x in range(HEIGHT // hauteur):
        if hauteur * x < int(list(a)[1]) < hauteur * (x + 1):
            break
    print(x)
    for y in range(WIDTH // longueur):
        if longueur*y < int(list(a)[0]) < longueur*(y+1):
            break
    print(y)
    if not [longueur*y, hauteur*x] in listeSuppr:
        liste_locale.append([longueur*y, hauteur*x])
    print(liste_locale)


longueur = WIDTH//10
hauteur = HEIGHT//10
screen = pygame.display.set_mode((WIDTH, HEIGHT))
game_over = False
while not game_over:
    for x in range(HEIGHT//hauteur):          # looks if the program should draw the squares or not
        for y in range(WIDTH//longueur):
            if not [longueur*y, hauteur*x] in listeSuppr:
                pygame.draw.rect(screen, GREY, (longueur*y, hauteur*x, int(longueur*0.90), int(hauteur*0.90)))
            else:
                pygame.draw.rect(screen, BLACK, (longueur * y, hauteur * x, int(longueur * 0.90), int(hauteur * 0.90)))
    for event in pygame.event.get():
        if event.type == pygame.QUIT:  # detects if the game has to close
            sys.exit()
        elif pygame.mouse.get_pressed() == (1, 0, 0):  # detects when right-click has been pressed to delete the square
            print(pygame.mouse.get_pos())
            add_to_list(0, listeSuppr)
            listeSuppr.sort()
            print(listeSuppr)
        elif pygame.mouse.get_pressed() == (0, 0, 1):  # detects when left-click has been pressed to reset the grid
            listeSuppr.clear()
    pygame.display.update()

Sorry if the code looks like garbage lol. Also sorry for the half french half english names for the vars and fuctions... If someone knows if there is something wrong with the code or the way I codded the grid, or if it isn't my fault but you know a way to fix the problem, please do tell me !


Solution

  • The issue always happens, when the first loop in add_to_list runs to the end and doesn't find a valid coordinate. This always happens when you click at a pixel, whose x coordinate is dividable by hauteur respectively y coordinate is divisible by longueur. In this case the condition hauteur * x < int(list(a)[1]) < hauteur * (x + 1) and/or longueur*y < int(list(a)[0]) < longueur*(y+1) is never fulfilled.
    You have to evaluate <= rather than < for either the 1st or 2nd condition, to cover the full range of pixels:

    if hauteur * x < int(list(a)[1]) < hauteur * (x + 1):

    if hauteur * x <= int(list(a)[1]) < hauteur * (x + 1):
    

    if longueur*y < int(list(a)[0]) < longueur*(y+1):

    if longueur*y <= int(list(a)[0]) < longueur*(y+1):
    

    Anyway, the code can be simplified by using the // (floor division) operator to compute the cell indices:

    def add_to_list(a, liste_locale):  
        a = pygame.mouse.get_pos()  
        print(a)
        x = a[1] // hauteur
        print(x)
        y = a[0] // longueur
        print(y)
        if not [longueur*y, hauteur*x] in listeSuppr:
            liste_locale.append([longueur*y, hauteur*x])
        print(liste_locale)