猜游戏-Tkinter模块

时间:2018-08-08 02:22:13

标签: python tkinter

我用Python创建了一个代码来展示1到100之间的数字的Guess游戏。我想使用Tkinter模块在图形界面中实现此游戏。我有一个主意,我使用tkinter创建了一个代码,但是之后我崩溃了。我的问题是,如何将创建的两个代码“合并”成一个图形界面?

Tkinter部分。

from tkinter import *
import random

i = Tk()

i.title('Guess Game')
i.geometry("400x200")

texto = Label(i, text = "Welcome to the Guess Game")
texto.pack()

texto = Label(i, text = "You have 10 chances to hit the number I'm thinking")
texto.pack()
texto = Label(i, text = "This is a value between 1 and 100. So, come on!")
texto.pack()

form = Entry(i, width=3)
form.pack()

b = Button(i, text ="Execute", fg= "green")
b.pack()

i.mainloop()

第二部分

import random

n = random.randrange(1, 101)
nrepete = []
estado1 = 7  # início
estado2 = 7


def SetStatus(tentativa):

    global estado2

    if abs(n - palpite) == 1:
        estado2 = 6  # Very Fucking Hot
    if abs(n - palpite) == 2 or abs(n - palpite) == 3:
        estado2 = 5  # Very Hot
    if abs(n - palpite) >= 4 and abs(n - palpite) <= 6:
        estado2 = 4  # Hot
    if abs(n - palpite) >= 7 and abs(n - palpite) <= 9:
        estado2 = 3  # Warm
    if abs(n - palpite) >= 10 and abs(n - palpite) <= 15:
        estado2 = 2  # Cold
    if abs(n - palpite) >= 16 and abs(n - palpite) <= 25:
        estado2 = 1  # Very Cold
    if abs(n - palpite) >= 26:
        estado2 = 0  #  Freezing


def FornecerPista():
    if estado1 == 7:
        if estado2 == 0:
            print('Freezing!')
        if estado2 == 1:
            print('Very cold!')
        if estado2 == 2:
            print('Cold!')
        if estado2 == 3:
            print('Warm!')
        if estado2 == 4:
            print('Hot!')
        if estado2 == 5:
            print('Very hot!')
        if estado2 == 6:
            print('Very fucking hot!')
    if estado1 - estado2 == 0:
        if estado2 == 0:
            print('Seu palpite continua congelando!')
        if estado2 == 1:
            print('Seu palpite continua muito frio!')
        if estado2 == 2:
            print('Seu palpite continua frio!')
        if estado2 == 3:
            print('Seu palpite continua morno!')
        if estado2 == 4:
            print('Seu palpite continua quente!')
        if estado2 == 5:
            print('Seu palpite continua muito quente!')
        if estado2 == 6:
            print('Seu palpite continua fervendo!')
    if estado1 - estado2 > 0:
        if estado2 == 0:
            print('Ops, seu palpite deu uma esfriada e agora está congelando!')
        if estado2 == 1:
            print('Ops, seu palpite deu uma esfriada e agora está muito frio!')
        if estado2 == 2:
            print('Ops, seu palpite deu uma esfriada e agora está frio!')
        if estado2 == 3:
            print('Ops, seu palpite deu uma esfriada e agora está morno!')
        if estado2 == 4:
            print('Ops, seu palpite deu uma esfriada e agora está quente!')
        if estado2 == 5:
            print('Ops, seu palpite deu uma esfriada e agora está muito quente!')
    if estado1 - estado2 < 0:
        if estado2 == 1:
            print('Ops, seu palpite deu uma esquentada e agora está muito frio!')
        if estado2 == 2:
            print('Ops, seu palpite deu uma esquentada e agora está frio!')
        if estado2 == 3:
            print('Ops, seu palpite deu uma esquentada e agora está morno!')
        if estado2 == 4:
            print('Ops, seu palpite deu uma esquentada e agora está quente!')
        if estado2 == 5:
            print('Ops, seu palpite deu uma esquentada e agora está muito quente!')
        if estado2 == 6:
            print('Ops, seu palpite deu uma esquentada e agora está fervendo!')


for tentativa in range(1, 11):
    while True:
        try:
            palpite = input('Tentativa' + str(tentativa) + ':')
            palpite = int(palpite)
            nrepete.append(palpite)
            if (palpite < 1) or (palpite > 100):
                raise ValueError
            if nrepete.count(palpite) >= 2:
                raise NameError
            else:
                break
        except NameError:
            print('Esse valor já foi testado! Tente de novo.')
        except ValueError:
            print('Invalid value! Try again.')

    if palpite == n:
        print('\nCongratulations !')
        print('\nYou hit the number', n, 'after', tentativa, 'tentativa(s)!')
        break
    if tentativa == 1:
        SetStatus(tentativa)
    if tentativa > 1:
        estado1 = estado2
        SetStatus(tentativa)
    FornecerPista()

    if tentativa == 10 and palpite != n:
        print('\nLamento, mas após', tentativa, 'tentativas')
        print('Você não conseguiu acertar o número', n, 'que eu estava pensando!')

2 个答案:

答案 0 :(得分:0)

仅“合并”您提到的两个部分并不简单。您需要更改许多变量,以便Tkinter可以访问它们,然后在GUI上显示。

但是对于初学者来说,您可以将以下代码移至GUI:

n = random.randrange(1, 101)
nrepete = []
estado1 = 7  # início
estado2 = 7


def SetStatus(tentativa):
    ...
def FornecerPista():
    ...

,然后在另一个函数中包装您的for循环:

def startgame():
    for tentativa in range(1, 11):
        .....

另外,为了避免在循环过程中冻结GUI,我建议您使用线程处理:

import threading
...
t = threading.Thread(target=startgame)
...

b = Button(i, text ="Execute", fg= "green", command=t.start)
b.pack()

i.mainloop()

仍然有很多工作要做,但是您可以开始并逐一进行。希望对您有帮助!

答案 1 :(得分:0)

我整理了一些可以满足您需求的代码。我还对代码进行了其他一些更改,这些更改对于使我的解决方案正常工作不是必需的,但是您应该强烈考虑实现它们,因为它们是更好的做法。我合并代码的方式是执行以下操作:

  • 将动作监听器添加到您的执行按钮(通过Google动作监听器了解更多信息)
  • 使用消息框显示输出而不是打印
  • 将“动作代码”(用于分析猜测等的代码)放置在每次按下执行按钮时都会执行的函数中

我对代码所做的一般更改是使用elif语句并使用列表存储消息,而不是使用if x == 3, then print("blablabla")使用elif语句,因为在评估您知道会失败的条件时没​​有意义(例如,如果x == 3执行,则无需检查x == 4是否将执行-我们知道不会执行。)我鼓励您更深入地研究是否/ elif / else条件,以便评论更有意义。

对于初学者来说,这是解决方案:在计算机上运行它,看看是否喜欢它。

from tkinter import *
import random
from tkinter import messagebox

n = random.randrange(1, 101)
nrepete = []
estado1 = 7  # início
estado2 = 7

tentativa = 0


def execute():
    global tentativa, estado2, estado1
    if tentativa < 10:  # only play if you still have turns
        palpite = form.get()
        try:
            palpite = int(palpite)
            nrepete.append(palpite)
            if (palpite < 1) or (palpite > 100):
                raise ValueError
            if nrepete.count(palpite) >= 2:
                raise NameError

            tentativa += 1
            if palpite == n:
                message = "Congratulations!  You hit the number {} after {} tentativa(s)!".format(n, tentativa)
                messagebox.showinfo("You win!", message)

            else:
                SetStatus(tentativa, palpite)
                if tentativa > 1:
                    estado1 = estado2

                message = FornecerPista()
                messagebox.showinfo("Status", message)

                if tentativa == 10 and palpite != n:
                    message = "Lamento, mas após {} tentativas. Você não conseguiu acertar o número {} que eu estava pensando!".format(
                        tentativa, n)
                    messagebox.showinfo("Game over", message)

        except NameError:
            messagebox.showerror("Error", 'Esse valor já foi testado! Tente de novo.')
        except ValueError:
            messagebox.showerror("Error", 'Invalid value! Try again.')


    else:
        messagebox.showinfo("Game over", "You've already lost.  The answer was {}".format(n))


def SetStatus(tentativa, palpite):
    global estado2
    x = abs(n - palpite)

    if x == 1:
        estado2 = 6  # Very Fucking Hot
    elif x == 2 or x == 3:
        estado2 = 5  # Very Hot
    elif 4 <= x <= 6:
        estado2 = 4  # Hot
    elif 7 <= x <= 9:
        estado2 = 3  # Warm
    elif 10 <= x <= 15:
        estado2 = 2  # Cold
    elif 16 <= x <= 25:
        estado2 = 1  # Very Cold
    elif x >= 26:
        estado2 = 0  # Freezing


def FornecerPista():
    message = ""
    if estado1 == 7:
        messages = ["Freezing!", "Very cold!", "Cold!", "Warm!", "Hot!", "Very hot!", "Very fucking hot!"]
        message = messages[estado2] + "\n"
    elif estado1 == estado2:
        messages = ['congelando', 'muito frio', "frio", "morno", "quente", "muito quente", "fervendo"]
        message += "Seu palpite continua {}!".format(messages[estado2])

    elif estado1 > estado2:
        messages = ['congelando', 'muito frio', "frio", "morno", "quente", "muito quente"]
        message += "Ops, seu palpite deu uma esfriada e agora está {}!".format(messages[estado2])
    else:
        messages = ['muito frio', "frio", "morno", "quente", "muito quente", "fervendo"]
        message += "Ops, seu palpite deu uma esquentada e agora está".format(messages[estado2 - 1])

    return message


i = Tk()

i.title('Guess Game')
i.geometry("400x200")

texto = Label(i, text="Welcome to the Guess Game")
texto.pack()

texto = Label(i, text="You have 10 chances to hit the number I'm thinking")
texto.pack()
texto = Label(i, text="This is a value between 1 and 100. So, come on!")
texto.pack()

form = Entry(i, width=3)
form.pack()

b = Button(i, text="Execute", fg="green", command=execute)
b.pack()

i.mainloop()

它如何工作:

通过将command = execute行添加到执行按钮结构中,每当按下按钮时都会调用execute()函数。 execute函数是所有动作代码,加上一些修改。要获取猜中的数字,我调用form.get()以获取名为form的输入框的内容。我不打印消息,而是使用tkinter消息框显示它们。再次,关于消息框的在线资源很多,因此我将不做过多解释。我不能保证它会完美地工作,因为我不会说太多西班牙语(因此无法有效地测试它),但是至少,这将在您的两个代码段之间提供一个链接。您显然可以对其进行修改,直到它适合您为止。

另一种不涉及消息框的解决方案将使用字符串变量更新标签。也可以免费使用Google。关于其他涉及线程的答案,请注意,这当然是更好的做法(我自己使用它),但是对于该项目,我不必担心。计算实际上是即时的,因此您的帧不应冻结。如果确实发生这种情况,则可以继续使用线程。另一个注意事项:如果可以,我会尽量避免使用全局变量。在大多数情况下,创建函数和使用return语句更为简洁。