4
\$\begingroup\$

I have just finished my minesweeper game using tkinter and would like to know how I could improve my program.

from tkinter import *
from tkinter import messagebox
from random import randint
class setupwindow():
 def __init__(window): #window is the master object of the setup window
 window.root = Tk()
 window.root.title("Setup")
 window.root.grid()
 window.finish = "N"
 labels = ["Height:", "Width:", "Mines:"]
 window.label = ["","",""]
 window.entry = ["","",""]
 for i in range(3):
 window.label[i] = Label(text = labels[i])
 window.label[i].grid(row = i, column = 1)
 window.entry[i] = Entry()
 window.entry[i].grid(row = i, column = 2)
 window.startbutton = Button(text = "Start", command = lambda: setupwindow.onclick(window))
 window.startbutton.grid(column = 2)
 window.root.mainloop()
 def onclick(window):
 setupwindow.verification(window)
 if window.verf == "Y":
 window.finish = "Y"
 window.root.destroy()
 return window
 def verification(window):
 height = window.entry[0].get()
 width = window.entry[1].get()
 mines = window.entry[2].get()
 window.verf = "N"
 if height.isdigit() and width.isdigit() and mines.isdigit():
 height = int(height)
 width = int(width)
 mines = int(mines)
 if height > 0 and height <= 24:
 totalsquares = height * width
 if width > 0 and width <= 48:
 if mines > 0:
 if mines < totalsquares:
 window.verf = "Y"
 window.height = height
 window.width = width
 window.mines = mines
 else:
 messagebox.showerror("Invalid", "You cannot have more mines than squares!")
 else:
 messagebox.showerror("Invalid", "You can't play minesweeper without mines!")
 else:
 messagebox.showerror("Invalid", "Width must be between 1 and 48 inclusive")
 else:
 messagebox.showerror("Invalid", "Height must be between 1 and 24 inclusive")
 else:
 messagebox.showerror("Invalid", "All values must be integers")
class gamewindow():
 def __init__(s, setup): #s is the master object of the main game
 s.height = setup.height
 s.width = setup.width
 s.mines = setup.mines
 s.root = Tk()
 s.root.title("Minesweeper")
 s.root.grid()
 s.finish = "N"
 s.maingrid = list()
 for i in range(s.height):
 s.maingrid.append([])
 for x in range(s.width):
 s.maingrid[i].append(" ")
 s.maingrid[i][x] = Button(height = 0, width = 3, font = "Calibri 15 bold", text = "", bg = "gray90", command = lambda i=i, x=x: gamewindow.onclick(s, i, x))
 s.maingrid[i][x].bind("<Button-3>", lambda event="<Button-3>", i=i, x=x: gamewindow.rightclick(event, s, i, x))
 s.maingrid[i][x].grid(row = i, column = x)
 s.maingrid[i][x].mine = "False"
 totalsquares = s.height * s.width
 s.scoreneeded = totalsquares - s.mines
 s.score = 0
 indexlist = list()
 for i in range(totalsquares):
 indexlist.append(i)
 spaceschosen = list() #where the mines are going to be
 for i in range(s.mines):
 chosenspace = randint(0, len(indexlist) - 1)
 spaceschosen.append(indexlist[chosenspace])
 del indexlist[chosenspace]
 for i in range(len(spaceschosen)):
 xvalue = int(spaceschosen[i] % s.width)
 ivalue = int(spaceschosen[i] / s.width)
 s.maingrid[ivalue][xvalue].mine = "True"
 s.root.mainloop()
 def onclick(s, i, x):
 colourlist = ["PlaceHolder", "Blue", "Green", "Red", "Purple", "Black", "Maroon", "Gray", "Turquoise"]
 if s.maingrid[i][x]["text"] != "F" and s.maingrid[i][x]["relief"] != "sunken":
 if s.maingrid[i][x].mine == "False":
 s.score += 1
 combinationsi = [1, -1, 0, 0, 1, 1, -1, -1]
 combinationsx = [0, 0, 1, -1, 1, -1, 1, -1] #All the surrounding spaces
 minecount = 0
 for combinations in range(len(combinationsi)):
 tempi = i + combinationsi[combinations]
 tempx = x + combinationsx[combinations]
 if tempi < s.height and tempx < s.width and tempi >= 0 and tempx >= 0:
 if s.maingrid[tempi][tempx].mine == "True":
 minecount = minecount + 1
 if minecount == 0:
 minecount = ""
 s.maingrid[i][x].configure(text = minecount, relief = "sunken", bg = "gray85")
 if str(minecount).isdigit():
 s.maingrid[i][x].configure(fg = colourlist[minecount])
 if minecount == "":
 for z in range(len(combinationsi)):
 if s.finish == "N":
 ivalue = i + int(combinationsi[z])
 xvalue = x + int(combinationsx[z])
 if ivalue >= 0 and ivalue < s.height and xvalue >=0 and xvalue < s.width:
 if s.maingrid[ivalue][xvalue]["relief"] != "sunken":
 gamewindow.onclick(s, ivalue, xvalue)
 if s.score == s.scoreneeded and s.finish == "N":
 messagebox.showinfo("Congratulations", "A winner is you!")
 s.finish = "Y"
 s.root.destroy()
 else:
 s.maingrid[i][x].configure(bg = "Red", text = "*")
 for a in range(len(s.maingrid)):
 for b in range(len(s.maingrid[a])):
 if s.maingrid[a][b].mine == "True":
 if s.maingrid[a][b]["text"] == "F":
 s.maingrid[a][b].configure(bg = "Green")
 elif s.maingrid[a][b]["bg"] != "Red":
 s.maingrid[a][b].configure(bg = "Pink", text = "*")
 elif s.maingrid[a][b]["text"] == "F":
 s.maingrid[a][b].configure(bg = "Yellow")
 messagebox.showinfo("GAME OVER", "You have lost")
 s.root.destroy()
 def rightclick(event, s, i, x):
 if s.maingrid[i][x]["relief"] != "sunken":
 if s.maingrid[i][x]["text"] == "":
 s.maingrid[i][x].config(text = "F")
 elif s.maingrid[i][x]["text"] == "F":
 s.maingrid[i][x].config(text = "?")
 else:
 s.maingrid[i][x].config(text = "")
if __name__ == "__main__":
 setup = setupwindow()
 if setup.finish == "Y":
 game = gamewindow(setup)
 quit()
200_success
146k22 gold badges190 silver badges479 bronze badges
asked Feb 17, 2019 at 12:59
\$\endgroup\$

1 Answer 1

3
\$\begingroup\$
  1. PEP-8
  • Class names should normally use the CapWords convention. #class-names

  • Don't use spaces around the = sign when used to indicate a keyword argument, or when used to indicate a default value for an unannotated function parameter. #whitespaces

  • Always use self for the first argument to instance methods. #function-and-method-arguments

  • There are other PEP-8 violations. Read complete document

  1. Guard clause

What are guard clauses and how to use them?

  1. Do not use for i in range(len(list)) unless you really need index. Even if you do need it, use enumerate instead.
  1. Convert range to list
 indexlist = list()
 for i in range(totalsquares):
 indexlist.append(i)

is equivalent to indexlist = list(range(totalsquares))

answered Feb 17, 2019 at 14:14
\$\endgroup\$
2
  • \$\begingroup\$ Thanks for the feedback however I'm unsure which part of the program you are referring to when you mentioned white spaces. \$\endgroup\$ Commented Feb 18, 2019 at 21:56
  • \$\begingroup\$ It's about functions/constructor calls like .grid(row=i, column=x), .config(text="F") and Button(height=0, width=3, ...) \$\endgroup\$ Commented Feb 19, 2019 at 21:41

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.