首页 > 解决方案 > 猜谜游戏 - Tkinter 模块

问题描述

我在 Python 中创建了一个代码来呈现一个 1 到 100 之间数字的猜谜游戏。我想使用 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!')

标签: pythontkinter

解决方案


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

  • 将动作监听器添加到您的执行按钮(谷歌动作监听器以了解更多信息)
  • 使用消息框显示输出而不是打印
  • 将“动作代码”(分析猜测等的代码)放入一个函数中,该函数在按下执行按钮时执行

我对代码所做的一般更改是使用 elif 语句并使用列表来存储消息,而不是if x == 3, then print("blablabla")使用 elif 语句,因为评估您知道会失败的条件是没有意义的(例如,如果x == 3执行,则没有需要检查是否x == 4会执行 - 我们知道它不会执行。)我鼓励您更深入地研究 if/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() 函数。执行函数是所有的动作代码,加上一些修改。为了得到猜到的数字,我调用form.get()来获取名为 form 的输入框的内容。我没有打印消息,而是使用 tkinter 消息框显示它们。再说一次,网上有很多关于消息框的资源,所以我不会过多解释。我不能保证这会完美运行,因为我不会说太多西班牙语(因此无法有效地测试它),但至少,这将提供您的两段代码之间的链接。您显然可以修改它,直到它适合您。

另一个不涉及消息框的解决方案是使用字符串变量更新标签。也可以随意谷歌。作为关于涉及线程的其他答案的注释,这当然是更好的做法(我自己使用它),但我不会担心这个项目。计算实际上是即时的,因此您的框架不应冻结。如果确实发生这种情况,那么您可以继续使用线程。另一个注意事项:如果您能提供帮助,我会尽量避免使用全局变量。大多数时候,创建函数和使用 return 语句要干净得多。


推荐阅读