如何避免在扫雷器的 tkinter 版本中先被击中地雷?

How to avoid a mine being hit first in a tkinter version of minesweeper?

好的,现在我已经在开发我的编程技能的同时编写了一段代码,所以请原谅我的粗制滥造,我的大部分代码都被包括在内,因为我不知道如何在它仍然有效的情况下减少它并且有道理。任何减少它的编辑将不胜感激。

问题是我的扫雷游戏有时允许它在第一轮击中地雷,我需要确保这不可能,每次我尝试我的解决方案时它都会崩溃。这个想法是,如果 self.Counter"start" 并且第一个点击的是地雷,它会重置网格,但它崩溃了。有什么想法吗?

from tkinter import *
import random
import time


#==================================================================================================
root=Tk()
#==================================================================================================

class GridGame(Toplevel):
    def __init__(self,master):
        self.fr=Toplevel(master)
        self.TotalFrame=Frame(self.fr,bg="black")
        self.ButtonColor="red"
        self.GameFrame=Frame(self.TotalFrame,bg="white")
        self.AllButtons=[]
        self.MineGrid=[]
        self.SizeGrid=17
        self.Mines=50
        self.MarkedMineColour="blue"
        self.Counter="Start"
        for x in range(self.SizeGrid):
            Column=[]
            MineColumn=[]
            for y in range(self.SizeGrid):
                item=Button(self.GameFrame,bg=self.ButtonColor,text="",height=2, width=6)
                item.bind("<Button-3>",self.ChoiceChange)
                Column.append(item)
                MineColumn.append("")
            self.AllButtons.append(Column)
            self.MineGrid.append(MineColumn)
        self.GameFrame.grid(row=0,column=0,pady=15,padx=20,columnspan=2)
        self.Quit=Button(self.TotalFrame, text="Destroy This Game", bg="orange",command=self.fr.destroy)
        self.Restart=Button(self.TotalFrame, text="Reset This Game", bg="light blue",command=self.Reset)
        self.Quit.grid(row=1,column=0,pady=5,padx=10)
        self.Restart.grid(row=1,column=1,pady=5,padx=10)
        self.TotalFrame.pack()


        for x in range(self.SizeGrid):
            for y in range(self.SizeGrid):
                    self.AllButtons[x][y].configure(command=lambda a=self.AllButtons[x][y],c=x,d=y:self.ColorFlip(a,c,d))
                    self.AllButtons[x][y].grid(row=x,column=y,padx=5,pady=5)
##        w = self.fr.winfo_screenwidth()
##        h = self.fr.winfo_screenheight()
        self.fr.geometry('%dx%d+%d+%d' % (1100, 950, 300, 10))
#==================================================================================================
    def MineGridMaker(self):
        for x in range(0,self.Mines):
                choice1,choice2=random.choice(range(0,len(self.AllButtons))),random.choice(range(0,len(self.AllButtons)))
                if self.MineGrid[choice1][choice2]=="":
                    self.MineGrid[choice1][choice2]="M"
        for x in range(0,len(self.AllButtons)):
            for y in range(0,len(self.AllButtons)):
                if self.MineGrid[x][y]=="M":
                    for xx in range(x-1,x+2):
                        for yy in range(y-1,y+2):
                            if xx in range(0,self.SizeGrid) and yy in range(0,self.SizeGrid):
                                if self.MineGrid[xx][yy]!="M" and self.MineGrid[xx][yy]=="":
                                    self.MineGrid[xx][yy]="1"
                                elif self.MineGrid[xx][yy]!="M" and int(self.MineGrid[xx][yy])>=1:
                                    self.MineGrid[xx][yy]=str(int(self.MineGrid[xx][yy])+1)
#==================================================================================================
    def ColorFlip(self,Object,x,y):
        if self.Counter==self.SizeGrid**2-self.Mines:
            MineGridMaker()
        if Object["bg"]==self.ButtonColor:
            if self.MineGrid[x][y]=="M":
                for Item in range(0,len(self.AllButtons)):
                    for item in range(0,len(self.AllButtons)):
                        self.AllButtons[Item][item].configure(bg="grey",text=self.MineGrid[Item][item])
                Object.configure(bg="red",text=self.MineGrid[x][y])
                for a in range(x-1,x+2):
                    for b in range(y-1,y+2):
                        if a in range(0,self.SizeGrid) and b in range(0,self.SizeGrid):
                            root.after(200,self.BlowUp,a,b)
            else:
                self.Counter-=1
                if self.MineGrid[x][y]=="":
                    for a in range(x-1,x+2):
                        for b in range(y-1,y+2):
                            if a in range(0,self.SizeGrid) and b in range(0,self.SizeGrid):
                                if self.AllButtons[a][b]["bg"]==self.ButtonColor:
                                    Object.configure(bg="white",text=self.MineGrid[x][y])
                                    self.ColorFlip(self.AllButtons[a][b],a,b)
                else:
                    Object.configure(bg="white",text=self.MineGrid[x][y])
        if self.Counter<=0:
            for a in range(0,(self.SizeGrid)):
                for b in range(0,(self.SizeGrid)):
                    if self.MineGrid[a][b]=="M":
                        self.AllButtons[a][b].configure(text=self.MineGrid[a][b],bg="orange")
                    else:
                        self.AllButtons[a][b].configure(bg="light green")
#==================================================================================================
    def BlowUp(self,x,y):
        for a in range(1,21):
            root.after((75*a)-25,self.Flash1,x,y)
            root.after(75*a,self.Flash2,x,y)
        root.after(1800,self.Fade,x,y)

    def Flash1(self,x,y):
        try:
            if self.AllButtons[x][y]["bg"]!=self.ButtonColor:
                self.AllButtons[x][y].configure(bg="orange")
        except:
            pass

    def Flash2(self,x,y):
        try:
            if self.AllButtons[x][y]["bg"]!=self.ButtonColor:
                self.AllButtons[x][y].configure(bg="yellow")
        except:
            pass

    def Fade(self,x,y):
        try:
            if self.AllButtons[x][y]["bg"]!=self.ButtonColor or self.AllButtons[x][y]["text"]!="":
                self.AllButtons[x][y].configure(bg="white")
        except:
            pass

    def Reset(self):
        for x in self.AllButtons:
            for y in x:
                y.configure(bg=self.ButtonColor,text="")
        self.Counter=(self.SizeGrid**2)-self.Mines

    def ChoiceChange(self,event):
        if event.widget["bg"]==self.ButtonColor:
            event.widget["bg"]=self.MarkedMineColour
        elif event.widget["bg"]==self.MarkedMineColour:
            event.widget["bg"]=self.ButtonColor

self.Counter 开始为 "Start"。 当 ColourFlip 被调用时,让它检查 self.Counter 是否开始,如果是,然后创建地雷网格,将 x 和 y 坐标作为参数引入,并保持点击的按钮不是地雷。那就继续吧,有地雷就让你死吧

有重置的问题,它与上一场比赛完全一样,所以是的。可能好,也可能不好。

from tkinter import *
import random
import time


#==================================================================================================
root=Tk()
#==================================================================================================

class GridGame(Toplevel):
    def __init__(self,master):
        self.fr=Toplevel(master)
        self.TotalFrame=Frame(self.fr,bg="black")
        self.ButtonColor="red"
        self.GameFrame=Frame(self.TotalFrame,bg="white")
        self.AllButtons=[]
        self.MineGrid=[]
        self.SizeGrid=17
        self.Mines=50
        self.MarkedMineColour="blue"
        self.Counter="Start"
        for x in range(self.SizeGrid):
            Column=[]
            MineColumn=[]
            for y in range(self.SizeGrid):
                item=Button(self.GameFrame,bg=self.ButtonColor,text="",height=2, width=6)
                item.bind("<Button-3>",self.ChoiceChange)
                Column.append(item)
                MineColumn.append("")
            self.AllButtons.append(Column)
            self.MineGrid.append(MineColumn)
        self.GameFrame.grid(row=0,column=0,pady=15,padx=20,columnspan=2)
        self.Quit=Button(self.TotalFrame, text="Destroy This Game", bg="orange",command=self.fr.destroy)
        self.Restart=Button(self.TotalFrame, text="Reset This Game", bg="light blue",command=self.Reset)
        self.Quit.grid(row=1,column=0,pady=5,padx=10)
        self.Restart.grid(row=1,column=1,pady=5,padx=10)
        self.TotalFrame.pack()


        for x in range(self.SizeGrid):
            for y in range(self.SizeGrid):
                    self.AllButtons[x][y].configure(command=lambda a=self.AllButtons[x][y],c=x,d=y:self.ColorFlip(a,c,d))
                    self.AllButtons[x][y].grid(row=x,column=y,padx=5,pady=5)
##        w = self.fr.winfo_screenwidth()
##        h = self.fr.winfo_screenheight()
        self.fr.geometry('%dx%d+%d+%d' % (1100, 950, 300, 10))
#==================================================================================================
    def MineGridMaker(self,a="a",b="a"):
        for x in range(0,self.Mines):
            CarryOn=False
            while CarryOn==False:
                choice1,choice2=random.choice(range(0,len(self.AllButtons))),random.choice(range(0,len(self.AllButtons)))
                if self.MineGrid[choice1][choice2]=="":
                    if a!=choice1 or b!=choice2:
                        self.MineGrid[choice1][choice2]="M"
                        CarryOn=True

        for x in range(0,len(self.AllButtons)):
            for y in range(0,len(self.AllButtons)):
                if self.MineGrid[x][y]=="M":
                    for xx in range(x-1,x+2):
                        for yy in range(y-1,y+2):
                            if xx in range(0,self.SizeGrid) and yy in range(0,self.SizeGrid):
                                if self.MineGrid[xx][yy]!="M" and self.MineGrid[xx][yy]=="":
                                    self.MineGrid[xx][yy]="1"
                                elif self.MineGrid[xx][yy]!="M" and int(self.MineGrid[xx][yy])>=1:
                                    self.MineGrid[xx][yy]=str(int(self.MineGrid[xx][yy])+1)
#==================================================================================================
    def ColorFlip(self,Object,x,y):
        if self.Counter=="Start":
            self.Counter=(self.SizeGrid**2)-self.Mines
            self.MineGridMaker(x,y)
        if Object["bg"]==self.ButtonColor:
            if self.MineGrid[x][y]=="M":
                for Item in range(0,len(self.AllButtons)):
                    for item in range(0,len(self.AllButtons)):
                        self.AllButtons[Item][item].configure(bg="grey",text=self.MineGrid[Item][item])
                Object.configure(bg="red",text=self.MineGrid[x][y])
                for a in range(x-1,x+2):
                    for b in range(y-1,y+2):
                        if a in range(0,self.SizeGrid) and b in range(0,self.SizeGrid):
                            root.after(200,self.BlowUp,a,b)
            else:
                self.Counter-=1
                if self.MineGrid[x][y]=="":
                    for a in range(x-1,x+2):
                        for b in range(y-1,y+2):
                            if a in range(0,self.SizeGrid) and b in range(0,self.SizeGrid):
                                if self.AllButtons[a][b]["bg"]==self.ButtonColor:
                                    Object.configure(bg="white",text=self.MineGrid[x][y])
                                    self.ColorFlip(self.AllButtons[a][b],a,b)
                else:
                    Object.configure(bg="white",text=self.MineGrid[x][y])
        if self.Counter<=0:
            for a in range(0,(self.SizeGrid)):
                for b in range(0,(self.SizeGrid)):
                    if self.MineGrid[a][b]=="M":
                        self.AllButtons[a][b].configure(text=self.MineGrid[a][b],bg="orange")
                    else:
                        self.AllButtons[a][b].configure(bg="light green")
#==================================================================================================
    def BlowUp(self,x,y):
        for a in range(1,21):
            root.after((75*a)-25,self.Flash1,x,y)
            root.after(75*a,self.Flash2,x,y)
        root.after(1800,self.Fade,x,y)

    def Flash1(self,x,y):
        try:
            if self.AllButtons[x][y]["bg"]!=self.ButtonColor:
                self.AllButtons[x][y].configure(bg="orange")
        except:
            pass

    def Flash2(self,x,y):
        try:
            if self.AllButtons[x][y]["bg"]!=self.ButtonColor:
                self.AllButtons[x][y].configure(bg="yellow")
        except:
            pass

    def Fade(self,x,y):
        try:
            if self.AllButtons[x][y]["bg"]!=self.ButtonColor or self.AllButtons[x][y]["text"]!="":
                self.AllButtons[x][y].configure(bg="white")
        except:
            pass

    def Reset(self):
        for x in self.AllButtons:
            for y in x:
                y.configure(bg=self.ButtonColor,text="")
        self.Counter=(self.SizeGrid**2)-self.Mines

    def ChoiceChange(self,event):
        if event.widget["bg"]==self.ButtonColor:
            event.widget["bg"]=self.MarkedMineColour
        elif event.widget["bg"]==self.MarkedMineColour:
            event.widget["bg"]=self.ButtonColor