如何在Tkinter中实现可更新的数组求和(Blackjack场景)
解决Tkinter Blackjack游戏实时更新分数总和的问题
核心问题分析
- 初始化时仅计算一次分数,后续抽卡未重新计算并更新标签
- 分数标签创建时直接调用
.pack(),未保存引用导致无法修改内容 - 全局变量使用不规范,函数内修改全局变量未声明
global
修改后的完整代码
from tkinter import * import random from tkinter import messagebox # 初始化全局变量 card_values = [2,3,4,5,6,7,8,9,10,10,10,10,11] *4 random.shuffle(card_values) player_cards_values = [] dealer_cards_values = [] player_display_cards = [] dealer_display_cards = [] # 扑克牌对应表,优化结构 card_symbols = { 2: ["🂢","🂲","🃒","🃂"], 3: ["🂣","🂳","🃓","🃃"], 4: ["🂤","🂴","🃔","🃄"], 5: ["🂥","🂵","🃕","🃅"], 6: ["🂦","🂶","🃖","🃆"], 7: ["🂧","🂷","🃗","🃇"], 8: ["🂨","🂸","🃘","🃈"], 9: ["🃉","🃙","🂺","🂪"], 10: ["🂪","🂫","🂭","🂮","🂺","🂻","🂽","🂾","🃚","🃛","🃝","🃞","🃊","🃋","🃍","🃎"], 11: ['🂡','🂱','🃑','🃁'] } # 初始化庄家牌局 def init_dealer(): global dealer_cards_values, dealer_display_cards dealer_score = 0 dealer_cards_values = [] dealer_display_cards = [] while True: card_val = card_values.pop() dealer_score += card_val dealer_cards_values.append(card_val) dealer_display_cards.append(random.choice(card_symbols[card_val])) if dealer_score < 17: continue elif 16 < dealer_score < 22: break else: dealer_score = ">21" break return dealer_score # 更新玩家分数标签 def update_player_score(label): total = sum(player_cards_values) if total > 21: label.config(text=f"Счет: >21") else: label.config(text=f"Счет: {total}") # 开始新游戏 def start_new_game(): global player_cards_values, player_display_cards # 重置玩家数据 player_cards_values = [] player_display_cards = [] dealer_score = init_dealer() # 创建游戏窗口 game_window = Toplevel(root) game_window.title('Игра') game_window.geometry("1880x1260+0+0") # 分数标签(保存引用用于后续更新) score_label = Label(game_window, text="Счет: 0", font="Times 55") score_label.pack() # 庄家牌显示 dealer_label = Label(game_window, text=dealer_display_cards, font="Times 80", width=100) dealer_label.pack() # 玩家牌显示 player_label = Label(game_window, text=player_display_cards, font="Times 80", width=50) player_label.pack() # 抽卡逻辑 def hit_card(): card_val = card_values.pop() player_cards_values.append(card_val) player_display_cards.append(random.choice(card_symbols[card_val])) # 更新牌面和分数 player_label.config(text=player_display_cards) update_player_score(score_label) # 检查爆牌 if sum(player_cards_values) > 21: messagebox.showinfo("Игра окончена", "Вы перебрали! Проигрыш.") game_window.destroy() # 停牌逻辑 def stand(): player_total = sum(player_cards_values) if dealer_score == ">21": result = "Вы победили! Дилер перебрал." elif player_total > 21: result = "Вы проиграли! Перебрали." elif player_total > dealer_score: result = "Вы победили!" elif player_total == dealer_score: result = "Ничья!" else: result = "Вы проиграли!" messagebox.showinfo("Результат", result) game_window.destroy() # 创建按钮 Button(game_window, command=hit_card, text="Взять карту").pack() Button(game_window, command=stand, text="Стоп").pack() # 发初始两张牌 for _ in range(2): hit_card() # 主窗口创建 root = Tk() root.title('Главное меню') root.geometry("600x300+150+150") Label(root, text="Игра БлэкДжэк").pack() Button(root, text='Начать игру', command=start_new_game).pack() root.mainloop()
关键修改点
- 用字典替代多个独立列表存储扑克牌符号,结构更简洁易维护
- 新增
update_player_score函数,每次抽卡后调用以更新分数标签 - 游戏窗口改为在
start_new_game内创建,避免提前初始化的逻辑错误 - 保存分数标签引用,确保后续可以修改文本内容
- 修复全局变量使用问题,明确声明需要修改的全局变量
- 添加停牌功能和完整的游戏结果判断逻辑
- 优化庄家牌局初始化逻辑,代码更简洁
内容的提问来源于stack exchange,提问作者BotKotik
相关产品推荐
相关产品推荐

