2016-07-25 3 views
1

Я пытаюсь взять текстовую игру и сделать с ней графическое приложение. Это игра с угадыванием чисел, где компьютер выбирает число от 1 до 100. Предполагается, что пользователь будет угадывать правильное число в наименьшем количестве попыток.Бесконечная петля, не знаю, почему

Моя проблема в том, что я попадаю в бесконечный цикл, когда и не знаю, почему и как его исправить.

Приложение ниже:

# 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() 
+0

когда вы входите в то время цикла, вы никогда не обновлять 'guess' , 'guess' не волшебным образом обновляется по мере ввода пользователем. –

+0

Я добавил еще один 'self.guess = int (self.guess_ent.get())' внутри цикла while перед 'self.tries + = 1' и получить те же результаты. Теперь это точно так же, как и у меня для текстовой версии игры, которая работает. – DarthOpto

ответ

2

Последняя строка вашего кода root.mainloop() означает, что у вас уже есть цикл while в вашей программе. Таким образом, работа в цикле while внутри другого, как вы делали, приведет к проблемам.

Так идея заключается в том, чтобы принять преимущество главного неявной во время цикла вашей программы и использовать его, чтобы увеличить число попыток self.tries один. Это на самом деле то, что естественно, когда вы использовали command вариант вашей кнопки и метод bind() для . Введите. Я думаю, вы легко поймете решение ниже.

Таким образом, в следующей программе я изменил только guessing() метод и ... одна последней вещи: не забывайте вводить событие в качестве параметра DEF guessing_a() метода иначе, нажав на Enter поднимет TypeError исключения.

Программа

Вот полная программа, которая работает правильно и с нажатием кнопки виджета или Enter кнопки клавиатуры:

# 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() 
+1

Большое вам спасибо. – DarthOpto

+1

Вы можете определить 'угадывание' как' def guessing (self, event = None) ', а затем использовать его как для команды, так и для связывания, исключая необходимость в' guessing_a'. –

+0

Спасибо @BryanOakley – DarthOpto

1

У вас есть время цикла, что проверить while guess != self.number. Но, где вы меняете guess? Это условие всегда будет истинным -> бесконечный цикл.

Вы хотите угадать внутри цикла while.

Кроме того, в Tk не следует использовать цикл while, если вы не используете потоки. Это заблокирует GUI. Вместо этого используйте метод after.

+0

Догадка находится прямо над циклом while, откуда я получаю его из поля guess_ent. 'guess = int (self.guess_ent.get())' – DarthOpto

+0

Да, вот в чем проблема – Pythonista

+0

Да, не полезно, в чем проблема. Я получаю предположение от ввода пользователя. Затем сравните его в цикле while. Он работал в текстовой игре, на которой я основываюсь? – DarthOpto

Смежные вопросы