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()
问题分析
- 参数传递错误:
submit函数将counter作为参数传入,属于值传递,函数内修改的是局部变量,不会影响全局的counter。每次点击按钮都会传入全局初始值8,导致计数器始终停在7。 - 不必要的while循环:Tkinter是事件驱动模型,每次点击按钮触发一次
submit执行,while循环会打乱逻辑,仅需单次判断即可。 - 全局变量声明逻辑错误:要在函数内修改全局变量,需在函数内部声明
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
相关产品推荐
相关产品推荐

