You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Tkinter数字猜谜游戏:错误猜测时计数器无法持续递减求助

数字猜谜游戏计数器不递减问题解决

问题描述

开发基于CustomTkinter的数字猜谜游戏时,期望每次猜错数字时计数器递减,但目前仅首次猜错时计数器减1,后续不再变化。原代码如下:

import random
import customtkinter as ctk
import tkinter


root = ctk.CTk()
ctk.set_appearance_mode('dark')
ctk.set_default_color_theme("dark-blue")
root.geometry('800x800')
root.title('Name Guessing Game')

random_number = random.randint(1, 100)
global counter
counter = 8
n_var = tkinter.StringVar(root, value='hint')


def low():
    print('Higher')


def high():
    print('Lower')

def won():
    print('You Guessed Correctly!!!!')


def submit(counter, chances_counter):
    
    global number
    number = 0

    while number != random_number and counter != 0:
        number = int(number_guess.get())
        if number < random_number:
            n_var.set(value='Too low go higher')
            counter -= 1
            chances_counter.configure(text=counter)
            return low()

        elif number > random_number:
            n_var.set(value='Too high go lower')
            counter -= 1
            chances_counter.configure(text=counter)
            return high()

        else:
            n_var.set(value='')
            return won()
            break

#GUI


frame_title = ctk.CTkFrame(master=root, corner_radius=20)
frame_title.pack(pady=(20, 20), padx=20, fill='x')

frame_guess = ctk.CTkFrame(master=root, corner_radius=20)
frame_guess.pack(side='top', ipady=80, fill='x', padx=20)

frame_hint = ctk.CTkFrame(master=root, corner_radius=20)
frame_hint.pack(side='top', ipady=80, fill='x', padx=20, pady=(20, 10))

frame_answer = ctk.CTkFrame(master=root, corner_radius=20)
frame_answer.pack(side='top', ipady=80, fill='x', padx=20, pady=(10, 10))

title_block = ctk.CTkLabel(master=frame_title, text='Number Guessing Game!', font=ctk.CTkFont(size=30))
title_block.pack(pady=80)

# guess input
number_guess = ctk.CTkEntry(master=frame_guess, placeholder_text='number to guess')
number_guess.pack(side='left', padx=20)

# guess submit
button = ctk.CTkButton(master=frame_guess, text='submit', command=lambda:[submit(counter, chances_counter), answer_a()])
button.pack(side='left')

#chances left


chances_counter = ctk.CTkLabel(master=frame_guess, text=counter, font=ctk.CTkFont(size=18))
chances_counter.pack(side='right', padx=20)

chances_counter1 = ctk.CTkLabel(master=frame_guess, text='How many chances left:', font=ctk.CTkFont(size=16))
chances_counter1.pack(side='right')

#hint


hint_lower = ctk.CTkLabel(master=frame_hint, textvariable=n_var, font=ctk.CTkFont(size=16))
hint_lower.pack(side='left',fill='both', expand=True, padx=20)


#answer
a_var = tkinter.StringVar(root, value='')
def answer_a():
    if number == random_number:
        a_var.set(value='Congratultions you guessed right!!!')
    


hint_answer = ctk.CTkLabel(master=frame_answer, textvariable=a_var, font=ctk.CTkFont(size=16))
hint_answer.pack(side='left',fill='both', expand=True, padx=20)


root.mainloop()

问题分析

  1. 参数传递错误:submit函数将counter作为参数传入,属于值传递,函数内修改的是局部变量,不会影响全局的counter。每次点击按钮都会传入全局初始值8,导致计数器始终停在7。
  2. 不必要的while循环:Tkinter是事件驱动模型,每次点击按钮触发一次submit执行,while循环会打乱逻辑,仅需单次判断即可。
  3. 全局变量声明逻辑错误:要在函数内修改全局变量,需在函数内部声明global counter,而非全局作用域开头。

修复后的代码

import random
import customtkinter as ctk
import tkinter


root = ctk.CTk()
ctk.set_appearance_mode('dark')
ctk.set_default_color_theme("dark-blue")
root.geometry('800x800')
root.title('Number Guessing Game')

random_number = random.randint(1, 100)
counter = 8
n_var = tkinter.StringVar(root, value='hint')
number = 0  # 全局变量统一声明


def low():
    print('Higher')


def high():
    print('Lower')

def won():
    print('You Guessed Correctly!!!!')


def submit(chances_counter):
    global counter, number
    
    # 判断剩余机会
    if counter <= 0:
        n_var.set(value='No chances left!')
        return
    
    # 处理非数字输入
    try:
        number = int(number_guess.get())
    except ValueError:
        n_var.set(value='Please enter a valid number!')
        return
    
    if number < random_number:
        n_var.set(value='Too low go higher')
        counter -= 1
        chances_counter.configure(text=counter)
        low()
    elif number > random_number:
        n_var.set(value='Too high go lower')
        counter -= 1
        chances_counter.configure(text=counter)
        high()
    else:
        n_var.set(value='')
        won()
        a_var.set(value='Congratulations you guessed right!!!')


# GUI部分
frame_title = ctk.CTkFrame(master=root, corner_radius=20)
frame_title.pack(pady=(20, 20), padx=20, fill='x')

frame_guess = ctk.CTkFrame(master=root, corner_radius=20)
frame_guess.pack(side='top', ipady=80, fill='x', padx=20)

frame_hint = ctk.CTkFrame(master=root, corner_radius=20)
frame_hint.pack(side='top', ipady=80, fill='x', padx=20, pady=(20, 10))

frame_answer = ctk.CTkFrame(master=root, corner_radius=20)
frame_answer.pack(side='top', ipady=80, fill='x', padx=20, pady=(10, 10))

title_block = ctk.CTkLabel(master=frame_title, text='Number Guessing Game!', font=ctk.CTkFont(size=30))
title_block.pack(pady=80)

# 猜数字输入框
number_guess = ctk.CTkEntry(master=frame_guess, placeholder_text='number to guess')
number_guess.pack(side='left', padx=20)

# 提交按钮,移除counter参数
button = ctk.CTkButton(master=frame_guess, text='submit', command=lambda: submit(chances_counter))
button.pack(side='left')

# 剩余机会显示
chances_counter = ctk.CTkLabel(master=frame_guess, text=counter, font=ctk.CTkFont(size=18))
chances_counter.pack(side='right', padx=20)

chances_counter1 = ctk.CTkLabel(master=frame_guess, text='How many chances left:', font=ctk.CTkFont(size=16))
chances_counter1.pack(side='right')

# 提示信息
hint_lower = ctk.CTkLabel(master=frame_hint, textvariable=n_var, font=ctk.CTkFont(size=16))
hint_lower.pack(side='left',fill='both', expand=True, padx=20)

# 结果信息
a_var = tkinter.StringVar(root, value='')
hint_answer = ctk.CTkLabel(master=frame_answer, textvariable=a_var, font=ctk.CTkFont(size=16))
hint_answer.pack(side='left',fill='both', expand=True, padx=20)


root.mainloop()

关键修改点

  • 移除submit函数的counter参数,在函数内部通过global counter声明使用全局变量,确保修改的是全局计数器。
  • 删除不必要的while循环,改为单次判断,符合Tkinter事件驱动逻辑。
  • 将answer_a函数的逻辑合并到submit的正确分支中,简化调用流程。
  • 添加输入合法性判断,避免非数字输入导致报错。
  • 增加剩余机会耗尽的提示逻辑。

内容的提问来源于stack exchange,提问作者JustTrying

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.06 20:54:52