I'm making Minesweeper with tkinter. I want to have it so that when a button with 0 mines surrounding it is clicked, all the buttons around that one are automatically clicked. However, when I run this and click on a button with 0, the program crashes. (originally it gave me the error of "maximum recursion depth exceeded"). How do I fix this? Here is the full code:
import tkinter as tk
import sys
import random
from tkinter import messagebox
from PIL import Image, ImageTk
from types import FunctionType
from copy import copy
app = tk.Tk()
app.geometry("432x468")
app.title("Minesweeper")
sys.setrecursionlimit(999999999)
colors = ['#FFFFFF', '#0000FF', '#008200', '#FF0000', '#000084', '#840000', '#008284', '#840084', '#000000']
# create lists
def createlists():
global buttonlist
global mylist
global numberlist
global panelist
global rightlist
global flaglist
global rowlist
global columnlist
global abomb
global adic
global secondlist
secondlist = []
abomb = []
adic = {}
buttonlist = []
mylist = [0]
numberlist = []
panelist = []
rightlist = []
flaglist = []
rowlist = []
columnlist = []
for a in range(1,18):
mylist.append(18*a)
for i in range(1,325):
button = "b" + str(i)
flag = 'flag' + str(i)
row = 'row' + str(i)
column = 'column' + str(i)
buttonlist.append(button)
numberlist.append(i)
secondlist.append(i)
flaglist.append(flag)
rowlist.append(row)
columnlist.append(column)
# randomly select bombs
def selectbombs():
for i in range(0,50):
x = "panel" + str(bomblist[i])
panelist.append(x)
for i in bomblist:
n = "a" + str(i)
abomb.append(n)
secondlist.remove(i)
# create function for when a bomb is clicked
def mine():
global bomblist
for i in range(0,50):
panelist[i] = tk.Label(app, image = bomb)
for x in mylist:
for i in range(x,x+18):
if i+1 in bomblist:
thing = bomblist.index(i+1)
panelist[thing].grid(row=mylist.index(x)+1, column=i-x+1, columnspan=1)
MsgBox = tk.messagebox.askquestion ('Game Over', 'You clicked on a bomb! Game Over. Would you like to play again?')
if MsgBox == 'no':
app.destroy()
else:
createlists()
bomblist = random.sample(numberlist, 50)
selectbombs()
buttons()
numbers()
flags()
# create grid of buttons
def buttons():
for i in range(0,324):
if i+1 in bomblist:
buttonlist[i] = tk.Button(app, text="", width=2, height=1, command=mine)
else:
buttonlist[i] = tk.Button(app, text="", width=2, height=1)
for x in mylist:
for i in range(x,x+18):
buttonlist[i].grid(row=mylist.index(x)+1, column=i-x+1, columnspan=1)
rowlist[i] = mylist.index(x)+1
columnlist[i] = i-x+1
# determine the number of bombs adjacent to each button
def numbers():
for i in range(1,325):
adic.update({"a"+str(i) : 0})
alist = list(adic)
for i in bomblist:
for x in numberlist:
if rowlist[x-1] in range(rowlist[numberlist.index(i)]-1, rowlist[numberlist.index(i)]+2) and columnlist[x-1] in range(columnlist[numberlist.index(i)]-1, columnlist[numberlist.index(i)]+2):
adic[alist[x-1]] = adic[alist[x-1]] + 1
for i in bomblist:
del adic[alist[numberlist.index(i)]]
alist = list(adic)
for i in adic:
buttonlist[secondlist[alist.index(i)]-1].bind("<Button-1>", lambda event, x=secondlist[alist.index(i)]-1, y=adic[i] : num(x, y))
# number functions
def num(x, y):
a = rowlist[x]
b = columnlist[x]
if y==0:
buttonlist[x].config(bg = '#FFFFFF')
buttonlist[x]["state"] = "disabled"
if a != 1 and b != 1:
num(x-19, adic["a"+str(x-18)])
if a != 1:
num(x-18, adic["a"+str(x-17)])
if a != 1 and b != 18:
num(x-17, adic["a"+str(x-16)])
if b != 1:
num(x-1, adic["a"+str(x)])
if b != 18:
num(x+1, adic["a"+str(x+2)])
if a != 18 and b != 1:
num(x+17, adic["a"+str(x+18)])
if a != 18:
num(x+18, adic["a"+str(x+19)])
if a != 18 and b != 18:
num(x+19, adic["a"+str(x+20)])
else:
buttonlist[x].config(text = y, disabledforeground = colors[y], bg = '#FFFFFF')
buttonlist[x]["state"] = "disabled"
# create function to place a flag
im = Image.open("flag.png")
im = im.resize((20,20), Image.ANTIALIAS)
flag = ImageTk.PhotoImage(im)
def flags():
for i in range(0,324):
buttonlist[i].bind("<Button-3>", lambda event, x=i : right(event, x))
def right(event, x):
if buttonlist[x]["state"] == "normal":
flaglist[x] = tk.Button(app, text = "", width=18, height=19, image = flag)
flaglist[x].grid(row=rowlist[x], column=columnlist[x], columnspan=1)
flaglist[x].bind("<Button-1>", lambda event: flaglist[x].destroy())
# check if the game has been won
def checkwin():
disnum = 0
for i in secondlist:
if buttonlist[i-1]["state"] == "disabled":
disnum = disnum + 1
if disnum == 274:
MsgBox = tk.messagebox.askquestion ('Game Won', 'You have won the game! Would you like to play again?')
if MsgBox == 'no':
app.destroy()
else:
createlists()
bomblist = random.sample(numberlist, 50)
selectbombs()
buttons()
numbers()
flags()
# open images
img = Image.open("bomb.png")
img = img.resize((20,20), Image.ANTIALIAS)
bomb = ImageTk.PhotoImage(img)
createlists()
bomblist = random.sample(numberlist, 50)
selectbombs()
buttons()
numbers()
flags()
app.mainloop()
the specific part which is causing the program to crash:
def num(x, y):
a = rowlist[x]
b = columnlist[x]
if y==0:
buttonlist[x].config(bg = '#FFFFFF')
buttonlist[x]["state"] = "disabled"
if a != 1 and b != 1:
num(x-19, adic["a"+str(x-18)])
if a != 1:
num(x-18, adic["a"+str(x-17)])
if a != 1 and b != 18:
num(x-17, adic["a"+str(x-16)])
if b != 1:
num(x-1, adic["a"+str(x)])
if b != 18:
num(x+1, adic["a"+str(x+2)])
if a != 18 and b != 1:
num(x+17, adic["a"+str(x+18)])
if a != 18:
num(x+18, adic["a"+str(x+19)])
if a != 18 and b != 18:
num(x+19, adic["a"+str(x+20)])
else:
buttonlist[x].config(text = y, disabledforeground = colors[y], bg = '#FFFFFF')
buttonlist[x]["state"] = "disabled"