Reputation: 1662
I am trying to take a text based game and make a GUI application with it. It is a number guessing game, where the computer chooses a number between 1 and 100. The user is expected to guess the correct number in the least amount of tries as possible.
My problem is that I am getting into an infinite loop when and I am not sure why or how to correct it.
The application is below:
# Guess My Number
#
# The computer picks a random number between 1 and 100
# The player tries to guess it and the computer lets the player know
# if the guess is too high, too low or right on the money
from tkinter import *
from random import randint
class Application(Frame):
""" A GUI Application for a number guessing game """
def __init__(self, master):
super(Application, self).__init__(master)
self.grid()
self.the_number = randint(1, 100)
self.guess_ent = Entry(self)
self.results = None
self.tries = 1
self.create_widgets()
def create_widgets(self):
Label(self,
text="Welcome to 'Guess My Number'"
).grid(row=0, column=0, columnspan=2, sticky=W+E+N+S)
Label(self,
text="I'm thinking of a number between 1 and 100"
).grid(row=1, column=0, columnspan=2, sticky=W+E+N+S)
Label(self,
text="Try to guess it in as few attempts as possible"
).grid(row=2, column=0, columnspan=2, sticky=W+E+N+S)
Label(self,
text="What is your guess: "
).grid(row=4, column=0, sticky=W)
self.guess_ent.grid(row=4, column=1, sticky=W)
Button(self,
text="Submit Guess",
command=self.guessing
).grid(row=5, column=0, sticky=W)
root.bind("<Return>", self.guessing_a)
self.results = Label(self, text="")
self.results.grid(row=6, column=0, sticky=W+E+N+S)
def guessing(self):
guess = int(self.guess_ent.get())
while guess != self.the_number:
if guess > self.the_number:
self.results.config(text="Lower")
self.guess_ent.delete(0, END)
else:
self.results.config(text="Higher")
self.guess_ent.delete(0, END)
self.tries += 1
if self.tries >= 10:
self.results.config(text="I'm sorry you couldn't guess the "
"number in the appropriate amount "
"of tries. The number I was "
"thinking of was: {}"
.format(self.the_number))
self.results.config(text="You guessed it!. "
"The number I was thinking of was: {}, "
"and it only took you {}, tries"
.format(self.the_number, self.tries))
def guessing_a(self):
self.guessing()
# main
root = Tk()
root.title("Guess My Number")
app = Application(root)
root.mainloop()
Upvotes: 1
Views: 73
Reputation: 22804
The last line of your code root.mainloop()
means you already have a while
loop in your program. So running a while
loop inside an other one the way you did will lead to problems.
So the idea is to take an advantage of the main implicit while loop of your program and use it to increment the number of tries self.tries
by one. This is in reality what is naturally when you used the command
option of your button and the bind()
method for Enter. I think you will understand the solution below easily.
Thus in the below program I modified only guessing()
method and ... one last thing: do not forget to inject an event as a parameter to def guessing_a()
method otherwise pressing on Enter will raise a TypeError
exception.
Here is the full program that works correctly both with pressing the button widget or the Enter keyboard button:
# Guess My Number
#
# The computer picks a random number between 1 and 100
# The player tries to guess it and the computer lets the player know
# if the guess is too high, too low or right on the money
from tkinter import *
from random import randint
class Application(Frame):
""" A GUI Application for a number guessing game """
def __init__(self, master):
super(Application, self).__init__(master)
self.grid()
self.the_number = randint(1, 100)
self.guess_ent = Entry(self)
self.results = None
self.tries = 1
self.create_widgets()
def create_widgets(self):
Label(self,
text="Welcome to 'Guess My Number'"
).grid(row=0, column=0, columnspan=2, sticky=W+E+N+S)
Label(self,
text="I'm thinking of a number between 1 and 100"
).grid(row=1, column=0, columnspan=2, sticky=W+E+N+S)
Label(self,
text="Try to guess it in as few attempts as possible"
).grid(row=2, column=0, columnspan=2, sticky=W+E+N+S)
Label(self,
text="What is your guess: "
).grid(row=4, column=0, sticky=W)
self.guess_ent.grid(row=4, column=1, sticky=W)
Button(self,
text="Submit Guess",
command=self.guessing
).grid(row=5, column=0, sticky=W)
root.bind("<Return>", self.guessing_a)
self.results = Label(self, text="")
self.results.grid(row=6, column=0, sticky=W+E+N+S)
def guessing(self):
if self.guess_ent.get() !='': # if there is a number in the entry widget. You can also improve this by checking if the entered text is a valid number
guess = int(self.guess_ent.get())
if guess > self.the_number:
self.results.config(text="Lower")
self.guess_ent.delete(0, END)
elif guess < self.the_number:
self.results.config(text="Higher")
self.guess_ent.delete(0, END)
else:
self.results.config(text="You guessed it!. "
"The number I was thinking of was: {}, "
"and it only took you {}, tries"
.format(self.the_number, self.tries))
self.tries += 1
if self.tries >= 10:
self.results.config(text="I'm sorry you couldn't guess the "
"number in the appropriate amount "
"of tries. The number I was "
"thinking of was: {}"
.format(self.the_number))
def guessing_a(self, event):
self.guessing()
# main
root = Tk()
root.title("Guess My Number")
app = Application(root)
root.mainloop()
Upvotes: 2
Reputation: 11645
You have a while loop that check while guess != self.number
. But, where do you change guess
? This condition will always be true -> infinite loop.
You want guess inside the while loop.
Also, in Tk you shouldn't use a while loop, unless you're using threads. This is going to block the GUI. Use the after
method instead.
Upvotes: 1