1

I've been set some fun work from my CS teach for A-Level preparation as we don't have any 'official' work to do as I've finished year 11, the task is a 'Mastermind' type game

The player guesses colours in an order and how many are right

This is my first time using Tkinter, I've found the destory() function, but i can't then restart the program without manually pressing "run" again.

Is there a way of removing all of the widgets and then re-displaying them. Like a reset button.

here is my code:

#the main window
win = Tk()
#the main frame
MainFrame = Frame(win)
#the frame which contains the buttons
ButtonFrame = Frame(win)
#will contain the game
MainCanvas = Canvas(MainFrame, height=550)
#the bottom most frame, contains the new game button
BottomFrame = Frame(win)


def closeWin():
    win.destroy()

def updateCoordinates(coodinates,NumberOfPresses):
    for i in range (4):
        print(i)
        if coodinates[i] == coodinates[0]:
                print(coodinates)
                coodinates[i] = coodinates[i] + 60
                print(coodinates)
        elif coodinates[i] == coodinates[1] and NumberOfPresses >= 5:
                coodinates[i] = coodinates[i] - 60
                print(coodinates)
        elif coodinates[i] == coodinates[2]:
                coodinates[i] = coodinates[i] + 60
                print(coodinates)
        elif coodinates[i] == coodinates[3] and NumberOfPresses >= 5:
                coodinates[i] = coodinates[i] - 60
                print(coodinates)
    return coodinates

#this is run is the red button is pressed
def redGuess(coodinates,NumberOfPresses):
    redGuess = MainCanvas.create_oval(coodinates, fill="red")
    NumberOfPresses = NumberOfPresses + 1
    updateCoordinates(coodinates,NumberOfPresses)
    return NumberOfPresses, coodinates

def blueGuess(coodinates,NumberOfPresses):
    blueGuess = MainCanvas.create_oval(coodinates, fill="blue")
    NumberOfPresses = NumberOfPresses + 1
    updateCoordinates(coodinates,NumberOfPresses)
    return NumberOfPresses, coodinates

def MakeAnswer():
    #the list of the colours
    colours = list("rbygwo")
    #randomizes them
    random.shuffle(colours)
    #creates a new list of the randomised letters
    order = ''.join(colours)
    result = ''
    for i in (order):
        #loops through each letter and adds a space bettween them
        result = result + i + ' '
    #calls the new list answer AND puts each letter into a sepearte index in a list
    answer = result.split()
    #removes one colour from the answer
    answer.pop(5)
    return answer


#runs the main program
def NewGame():
    NumberOfPresses = 0
    coodinates = [15,500,65,550]
    answer = MakeAnswer()
    redButton = Button(ButtonFrame,height=3, width=7 ,bg= "red", command =lambda: redGuess(coodinates,NumberOfPresses))
    blueButton = Button(ButtonFrame,height=3, width=7 ,bg= "blue", command =lambda: blueGuess(coodinates, NumberOfPresses))
    yellowButton = Button(ButtonFrame,height=3, width=7 ,bg= "yellow")
    greenButton = Button(ButtonFrame,height=3, width=7 ,bg= "green")
    whiteButton = Button(ButtonFrame,height=3, width=7 ,bg= "white")
    orangeButton = Button(ButtonFrame,height=3, width=7 ,bg= "orange")
    #displays all the widgets in the window
    MainFrame.pack()
    ButtonFrame.pack()
    MainCanvas.pack()
    BottomFrame.pack(side=BOTTOM)
    redButton.pack(side=LEFT, fill=X)
    blueButton.pack(side=LEFT, fill=X)
    yellowButton.pack(side=LEFT, fill=X)
    greenButton.pack(side=LEFT, fill=X)
    whiteButton.pack(side=LEFT, fill=X)
    orangeButton.pack(side=LEFT, fill=X)
    reset_button = Button(BottomFrame, text="Start A New Game", command = closeWin)
    reset_button.pack(side=BOTTOM, fill=X)
    #displayes the correct sequence
    print(answer)
    return

#starting coodinates of the first guess
#format= [x1, y1, x2, y2]


#Start of the game
NewGame()

#creates the buttons to select the different colours

#runs the game continuously
win.mainloop()

also just so you know the button pressing counter doesn't work properly, but I can't fix it until I can reset the window.

t0mas
  • 127
  • 14

2 Answers2

2

You can use the .withdraw() function.

.destroy() literally destroys the widget, and you can't get it back once you destroy it. If you refer to it after destroying it, you will get an error.

So, you would need to use .withdraw() to make it temporarily dissapear, and to bring it back, you would use .deiconify().

Here is an example:

from tkinter import *
window = Tk()
window2 = Toplevel()
def go_away():
    window.withdraw()
def come_back():
    window.deiconify()
b = Button(window, text = "go away", command = go_away).pack()
b2 = Button(window2, text = "come back", command = come_back).pack()
window.mainloop()

Hopefully this answer helps!

10 Rep
  • 2,217
  • 7
  • 19
  • 33
0

No,there is no function called reset to do what you want.You need to create it manually. In your code,reset means:

  1. generate a new variable answer
  2. delete all the object on the canvas.
  3. initialize the variable you have set.

So all the code could be:

from tkinter import *
import random
win = Tk()
#the main frame
MainFrame = Frame(win)
#the frame which contains the buttons
ButtonFrame = Frame(win)
#will contain the game
MainCanvas = Canvas(MainFrame, height=550)
#the bottom most frame, contains the new game button
BottomFrame = Frame(win)

def updateCoordinates(coodinates,NumberOfPresses):
    for i in range (4):
        print(i)
        if coodinates[i] == coodinates[0]:
                print(coodinates)
                coodinates[i] = coodinates[i] + 60
                print(coodinates)
        elif coodinates[i] == coodinates[1] and NumberOfPresses >= 5:
                coodinates[i] = coodinates[i] - 60
                print(coodinates)
        elif coodinates[i] == coodinates[2]:
                coodinates[i] = coodinates[i] + 60
                print(coodinates)
        elif coodinates[i] == coodinates[3] and NumberOfPresses >= 5:
                coodinates[i] = coodinates[i] - 60
                print(coodinates)
    return coodinates

#this is run is the red button is pressed
def redGuess(coodinates,NumberOfPresses):
    redGuess = MainCanvas.create_oval(coodinates, fill="red")
    NumberOfPresses = NumberOfPresses + 1
    updateCoordinates(coodinates,NumberOfPresses)
    return NumberOfPresses, coodinates

def blueGuess(coodinates,NumberOfPresses):
    blueGuess = MainCanvas.create_oval(coodinates, fill="blue")
    NumberOfPresses = NumberOfPresses + 1
    updateCoordinates(coodinates,NumberOfPresses)
    return NumberOfPresses, coodinates

def MakeAnswer():
    #the list of the colours
    colours = list("rbygwo")
    #randomizes them
    random.shuffle(colours)
    #creates a new list of the randomised letters
    order = ''.join(colours)
    result = ''
    for i in (order):
        #loops through each letter and adds a space bettween them
        result = result + i + ' '
    #calls the new list answer AND puts each letter into a sepearte index in a list
    answer = result.split()
    #removes one colour from the answer
    answer.pop(5)
    return answer


#runs the main program
def NewGame():
    def closeWin():
        MainCanvas.delete("all")
        nonlocal NumberOfPresses,answer,coodinates
        NumberOfPresses = 0
        coodinates = [15, 500, 65, 550]
        answer = MakeAnswer()
        print(answer)

    NumberOfPresses = 0
    coodinates = [15,500,65,550]
    answer = MakeAnswer()
    redButton = Button(ButtonFrame,height=3, width=7 ,bg= "red", command =lambda: redGuess(coodinates,NumberOfPresses))
    blueButton = Button(ButtonFrame,height=3, width=7 ,bg= "blue", command =lambda: blueGuess(coodinates, NumberOfPresses))
    yellowButton = Button(ButtonFrame,height=3, width=7 ,bg= "yellow")
    greenButton = Button(ButtonFrame,height=3, width=7 ,bg= "green")
    whiteButton = Button(ButtonFrame,height=3, width=7 ,bg= "white")
    orangeButton = Button(ButtonFrame,height=3, width=7 ,bg= "orange")
    #displays all the widgets in the window
    MainFrame.pack()
    ButtonFrame.pack()
    MainCanvas.pack()
    BottomFrame.pack(side=BOTTOM)
    redButton.pack(side=LEFT, fill=X)
    blueButton.pack(side=LEFT, fill=X)
    yellowButton.pack(side=LEFT, fill=X)
    greenButton.pack(side=LEFT, fill=X)
    whiteButton.pack(side=LEFT, fill=X)
    orangeButton.pack(side=LEFT, fill=X)
    reset_button = Button(BottomFrame, text="Start A New Game", command = closeWin)
    reset_button.pack(side=BOTTOM, fill=X)
    #displayes the correct sequence
    print(answer)
    return

#starting coodinates of the first guess
#format= [x1, y1, x2, y2]


#Start of the game
NewGame()

#creates the buttons to select the different colours

#runs the game continuously
win.mainloop()
jizhihaoSAMA
  • 12,336
  • 9
  • 27
  • 49
  • i copied the code from the NewGame() function and it is giving me a syntax error of:```SyntaxError: no binding for nonlocal 'NumberOfPresses' found``` but when i copy the whole program it works, why is that? – t0mas May 09 '20 at 13:50
  • 1
    @t0mas You maybe have revised my code.(Read [python-nonlocal-statement](https://stackoverflow.com/questions/1261875/python-nonlocal-statement)) – jizhihaoSAMA May 09 '20 at 13:56