Doing a minesweeper on python using tkinter. I'm trying to make a square white when you click on it but it only makes the first square white.
import random
import tkinter as tk
import time
def init_grille(m, n, n_mines): # Creates the grid with the mines and the numbers
grille = []
for i in range(m) :
ligne = []
for i in range(n) :
ligne.append(0)
grille.append(ligne)
for i in range(n_mines) :
rm = random.randint(0, m - 1)
rn = random.randint(0, n - 1)
while grille[rm][rn] == 'X' :
rm = random.randint(0, m - 1)
rn = random.randint(0, n - 1)
grille[rm][rn] = 'X'
for em in range(m) :
for en in range(n) :
if grille[em][en] == 0 :
m_proches = 0
if en > 0 and grille[em][en-1] == 'X' :
m_proches = 1
if en < n - 1 and grille[em][en 1] == 'X' :
m_proches = 1
if em < m - 1 and grille[em 1][en] == 'X' :
m_proches = 1
if em < m - 1 and en < n - 1 and grille[em 1][en 1] == 'X' :
m_proches = 1
if em < m - 1 and en > 0 and grille[em 1][en-1] == 'X' :
m_proches = 1
if em > 0 and grille[em-1][en] == 'X' :
m_proches = 1
if em > 0 and en < n - 1 and grille[em-1][en 1] == 'X' :
m_proches = 1
if em > 0 and en > 0 and grille[em-1][en-1] == 'X' :
m_proches = 1
grille[em][en] = m_proches
return grille
def init_grille_joueur(m, n): # Creates the grid the player interacts with (digging and flagging)
grille_j = []
for i in range(m) :
ligne = []
for i in range(n) :
ligne.append(0)
grille_j.append(ligne)
return grille_j
root = tk.Tk()
M = 10
N = 10
LARGEUR_CASE = 50
HAUTEUR_CASE = 50 # Just some values used for testing the program
def fenetre_principale(): # Configurates the window
label = tk.Label(root, text = "GO !", background = "white")
label.pack()
root.title("Démineur")
root.geometry(str(M * LARGEUR_CASE) 'x' str(N * HAUTEUR_CASE 90))
def init_canvas(m, n): # Creates the visual grid
rect_id = []
canvas = tk.Canvas(root, width = M * LARGEUR_CASE 25, height = N * HAUTEUR_CASE 25)
for i in range(m):
for j in range(n):
rect_id.append(canvas.create_rectangle(j * LARGEUR_CASE, i * HAUTEUR_CASE, (j 1) * LARGEUR_CASE, (i 1) * HAUTEUR_CASE, outline = "lightgray", fill = "gray", width = 2))
canvas.bind('<Button-1>', clic_gauche)
canvas.bind('<Button-3>', clic_droit)
canvas.pack()
return rect_id, canvas
def get_case(x, y): # Locates a square on the visual grid
case = canvas.find_overlapping(x, y, x, y)
if len(case) == 0 :
return -1, -1
else :
x = (case[0] - 1) // M
y = (case[0] - 1) % N
return x, y
def creuser(i, j): # The digging mechanic
if not grille[i][j] == -1 :
grille_j[i][j] = -1
C = (j * LARGEUR_CASE LARGEUR_CASE / 2, i * HAUTEUR_CASE HAUTEUR_CASE / 2)
case_id = canvas.find_overlapping(j, i, j, i)
case = case_id[0]
canvas.itemconfig(case, fill = "white")
if grille[i][j] == 'X' :
print("Perdu!")
canvas.create_text(C, font = "Wingdings 20 bold", text = chr(77), fill = "purple")
elif grille[i][j] == 1 :
canvas.create_text(C, font = "Arial 20 bold", text = str(grille[i][j]), fill = "blue")
elif grille[i][j] == 2 :
canvas.create_text(C, font = "Arial 20 bold", text = str(grille[i][j]), fill = "green")
elif grille[i][j] > 2 :
canvas.create_text(C, font = "Arial 20 bold", text = str(grille[i][j]), fill = "red")
canvas.pack()
def clic_gauche(event): # Left click
x, y = get_case(event.x, event.y)
creuser(x, y)
def drapeau(i, j): # The flag mechanic, unfinished
C = (j * LARGEUR_CASE LARGEUR_CASE / 2, i * HAUTEUR_CASE HAUTEUR_CASE / 2)
if grille_j[i][j] == 0 :
grille_j[i][j] = 1
canvas.create_text(C, font = "Wingdings 20 bold", text = chr(80), fill = "orange")
elif grille_j[i][j] == 1 :
grille_j[i][j] = 0
canvas.delete()
def clic_droit(event): # Right click
x, y = get_case(event.x, event.y)
drapeau(x, y)
'''def maj_labels():''' # Not finished yet
grille = init_grille(M, N, 5)
grille_j = init_grille_joueur(M, N)
fenetre_principale()
rect_id, canvas = init_canvas(M, N)
'''root.after(500, maj_labels)''' # It's supposed to update the timer which isn't implemented yet
root.mainloop()
I tried using find_overlapping to get the square's id when I click on it and then change its color with itemconfig, I tried to change the lines' order to see if they contradicted eachother but it's still the same problem
CodePudding user response:
You passed incorrect region (j, i, j, i)
to canvas.find_overlapping()
inside creuser()
, region (*C, *C)
should be used instead:
def creuser(i, j):
...
#case_id = canvas.find_overlapping(j, i, j, i) # incorrect region
case_id = canvas.find_overlapping(*C, *C) # correct region
...