当前位置: 首页 > news >正文

卡牌抽取游戏

我来为您创建一个使用Python Tkinter的卡牌抽取游戏UI。这个程序会实现您描述的所有功能。

这个程序提供了以下功能:

  1. 牌堆管理

    • 10种不同的牌,每种4张,总共40张牌

    • 实时显示牌堆中每种牌的剩余数量

    • 用进度条形式直观显示每种牌的数量

  2. 抽取功能

    • 每次显示3张随机抽取的牌

    • 可以单独抽取任意一张牌

    • 可以一次性抽取全部3张牌

    • 抽取后牌堆相应减少

  3. 刷新功能

    • 点击"刷新"按钮将当前未抽取的牌放回牌堆

    • 重新洗牌并抽取3张新牌

    • 已抽取的牌不会放回牌堆

  4. 显示区域

    • 当前抽取的3张牌(带抽取按钮)

    • 用户已抽取的牌(按类型统计)

    • 当前牌堆状态

    • 游戏统计信息

  5. 游戏控制

    • 重置游戏按钮,可重新开始游戏

    • 自动检测游戏结束条件(牌堆不足3张)

    • 彩色显示不同类型的牌

运行这个程序后,您会看到一个完整的GUI界面,可以按照您的描述进行卡牌抽取游戏。

import tkinter as tk from tkinter import ttk, messagebox import random from collections import Counter class CardGame: def __init__(self, master, N=10): self.master = master self.N = N self.master.title("卡牌抽取游戏") self.master.geometry("1000x700") # 初始化牌堆,每种牌4张 self.card_types = list(range(1, N + 1)) self.initial_counts = {card_type: 4 for card_type in self.card_types} self.deck = [] self.reset_deck() # 当前显示的3张牌 self.current_cards = [] # 用户已抽取的牌 self.user_drawn_cards = [] # 游戏状态 self.game_active = True # 设置样式 self.setup_styles() # 创建UI self.create_widgets() # 初始抽取3张牌 self.draw_initial_cards() def setup_styles(self): """设置样式""" style = ttk.Style() style.theme_use('clam') def reset_deck(self): """重置牌堆到初始状态""" self.deck = [] for card_type, count in self.initial_counts.items(): self.deck.extend([card_type] * count) def shuffle_deck(self): """洗牌""" random.shuffle(self.deck) def draw_three_cards(self): """从牌堆中抽取3张牌(不放回)""" if len(self.deck) < 3: messagebox.showwarning("牌堆不足", "牌堆中剩余牌数不足3张,无法继续游戏!") self.game_active = False return [] drawn_cards = [] for _ in range(3): if self.deck: card = self.deck.pop(0) drawn_cards.append(card) return drawn_cards def create_widgets(self): """创建所有UI组件""" # 主框架 main_frame = ttk.Frame(self.master, padding="20") main_frame.grid(row=0, column=0, sticky=(tk.W, tk.E, tk.N, tk.S)) # 标题 title_label = ttk.Label(main_frame, text="卡牌抽取游戏", font=("Arial", 20, "bold")) title_label.grid(row=0, column=0, columnspan=3, pady=(0, 20)) # 牌堆状态区域 deck_frame = ttk.LabelFrame(main_frame, text="当前牌堆状态", padding="10") deck_frame.grid(row=1, column=0, sticky=(tk.W, tk.E, tk.N, tk.S), padx=(0, 20)) self.deck_status_label = ttk.Label( deck_frame, text=self.get_deck_status_text(), font=("Consolas", 10), wraplength=200 ) self.deck_status_label.pack() # 抽取的牌显示区域 current_cards_frame = ttk.LabelFrame(main_frame, text="当前抽取的3张牌", padding="20") current_cards_frame.grid(row=1, column=1, sticky=(tk.W, tk.E, tk.N, tk.S), padx=20) # 当前3张牌的框架 self.card_frames = [] self.card_labels = [] self.draw_buttons = [] for i in range(3): card_frame = ttk.Frame(current_cards_frame) card_frame.grid(row=0, column=i, padx=10) # 牌显示 card_label = ttk.Label( card_frame, text="", font=("Arial", 24, "bold"), width=6, anchor="center", relief="solid", padding=10 ) card_label.pack(pady=(0, 10)) self.card_labels.append(card_label) # 抽取按钮 draw_button = ttk.Button( card_frame, text=f"抽取牌{i+1}", command=lambda idx=i: self.draw_single_card(idx) ) draw_button.pack() self.draw_buttons.append(draw_button) self.card_frames.append(card_frame) # 用户抽取的牌区域 user_cards_frame = ttk.LabelFrame(main_frame, text="您已抽取的牌", padding="10") user_cards_frame.grid(row=1, column=2, sticky=(tk.W, tk.E, tk.N, tk.S), padx=(20, 0)) self.user_cards_text = tk.Text( user_cards_frame, height=15, width=20, font=("Consolas", 10) ) self.user_cards_text.pack() self.user_cards_text.config(state=tk.DISABLED) # 控制按钮区域 control_frame = ttk.Frame(main_frame) control_frame.grid(row=2, column=0, columnspan=3, pady=20) # 刷新按钮 self.refresh_button = ttk.Button( control_frame, text="刷新牌堆并重新抽取", command=self.refresh_and_redraw, width=30 ) self.refresh_button.pack(side=tk.LEFT, padx=5) # 抽取全部按钮 self.draw_all_button = ttk.Button( control_frame, text="抽取全部3张牌", command=self.draw_all_cards, width=20 ) self.draw_all_button.pack(side=tk.LEFT, padx=5) # 重置游戏按钮 self.reset_button = ttk.Button( control_frame, text="重置游戏", command=self.reset_game, width=15 ) self.reset_button.pack(side=tk.LEFT, padx=5) # 统计信息 stats_frame = ttk.LabelFrame(main_frame, text="游戏统计", padding="10") stats_frame.grid(row=3, column=0, columnspan=3, sticky=(tk.W, tk.E), pady=(10, 0)) self.stats_label = ttk.Label( stats_frame, text=self.get_stats_text(), font=("Consolas", 10) ) self.stats_label.pack() # 配置网格权重 self.master.columnconfigure(0, weight=1) self.master.rowconfigure(0, weight=1) main_frame.columnconfigure(1, weight=1) def get_deck_status_text(self): """获取牌堆状态文本""" if not self.deck: return "牌堆已空!" card_counter = Counter(self.deck) status_lines = [] for card_type in sorted(card_counter.keys()): count = card_counter[card_type] bar = "■" * count status_lines.append(f"牌{card_type}: {count}张 {bar}") status_text = f"牌堆总牌数: {len(self.deck)}\n" status_text += "\n".join(status_lines) return status_text def get_stats_text(self): """获取统计信息文本""" card_counter = Counter(self.user_drawn_cards) stats_lines = [] for card_type in sorted(card_counter.keys()): count = card_counter[card_type] stats_lines.append(f"牌{card_type}: 抽取了{count}次") stats_text = f"您总共抽取了 {len(self.user_drawn_cards)} 张牌\n" if stats_lines: stats_text += "\n".join(stats_lines) return stats_text def draw_initial_cards(self): """初始抽取3张牌""" self.current_cards = self.draw_three_cards() self.update_card_display() self.update_buttons_state() def update_card_display(self): """更新卡牌显示""" for i, label in enumerate(self.card_labels): if i < len(self.current_cards): label.config(text=f"牌{self.current_cards[i]}") # 为不同牌设置不同颜色 colors = ["lightblue", "lightgreen", "lightcoral", "lightyellow", "lightpink", "lightcyan", "lightgray", "lightgoldenrodyellow", "lightsalmon", "lightseagreen"] color_idx = (self.current_cards[i] - 1) % len(colors) label.config(background=colors[color_idx]) else: label.config(text="", background="SystemButtonFace") def update_buttons_state(self): """更新按钮状态""" for i, button in enumerate(self.draw_buttons): if i < len(self.current_cards) and self.game_active: button.config(state=tk.NORMAL) else: button.config(state=tk.DISABLED) def draw_single_card(self, card_index): """抽取单张牌""" if not self.game_active or card_index >= len(self.current_cards): return # 抽取选中的牌 drawn_card = self.current_cards.pop(card_index) self.user_drawn_cards.append(drawn_card) # 更新显示 self.update_card_display() self.update_buttons_state() self.update_deck_status() self.update_user_cards_display() self.update_stats() # 检查是否还有牌可抽 if not self.current_cards: self.check_game_status() def draw_all_cards(self): """抽取全部3张牌""" if not self.game_active or not self.current_cards: return # 抽取所有剩余牌 while self.current_cards: drawn_card = self.current_cards.pop(0) self.user_drawn_cards.append(drawn_card) # 更新显示 self.update_card_display() self.update_buttons_state() self.update_deck_status() self.update_user_cards_display() self.update_stats() # 检查游戏状态 self.check_game_status() def refresh_and_redraw(self): """刷新牌堆并重新抽取""" if not self.game_active: messagebox.showinfo("游戏结束", "游戏已结束,请点击重置游戏重新开始!") return # 将当前剩余的牌放回牌堆 for card in self.current_cards: self.deck.append(card) # 洗牌 self.shuffle_deck() # 重新抽取3张牌 self.current_cards = self.draw_three_cards() # 更新显示 self.update_card_display() self.update_buttons_state() self.update_deck_status() self.update_stats() # 检查游戏状态 self.check_game_status() def reset_game(self): """重置游戏""" # 重置所有状态 self.reset_deck() self.shuffle_deck() self.current_cards = [] self.user_drawn_cards = [] self.game_active = True # 初始抽取 self.draw_initial_cards() # 更新显示 self.update_deck_status() self.update_user_cards_display() self.update_stats() def update_deck_status(self): """更新牌堆状态显示""" self.deck_status_label.config(text=self.get_deck_status_text()) def update_user_cards_display(self): """更新用户抽取的牌显示""" self.user_cards_text.config(state=tk.NORMAL) self.user_cards_text.delete(1.0, tk.END) if not self.user_drawn_cards: self.user_cards_text.insert(tk.END, "尚未抽取任何牌") else: card_counter = Counter(self.user_drawn_cards) for card_type in sorted(card_counter.keys()): count = card_counter[card_type] self.user_cards_text.insert(tk.END, f"牌{card_type}: {count}张\n") self.user_cards_text.config(state=tk.DISABLED) def update_stats(self): """更新统计信息""" self.stats_label.config(text=self.get_stats_text()) def check_game_status(self): """检查游戏状态""" if len(self.deck) < 3 and not self.current_cards: messagebox.showinfo("游戏结束", "牌堆中牌数不足3张,游戏结束!") self.game_active = False self.update_buttons_state() def main(): root = tk.Tk() app = CardGame(root, N=10) root.mainloop() if __name__ == "__main__": main()
http://www.zskr.cn/news/1418100.html

相关文章:

  • 别再死记硬背了!用‘找书’和‘找章节’的比喻,5分钟搞懂Linux内存管理中的一级/二级页表
  • 个人认为目前为止java后端面试最有效且快捷的方法
  • 实测在蜂窝网络下使用Taotoken调用大模型API的成功率与体验
  • 背包问题 01背包/完全背包/多重背包/分组背包/单调队列优多重背包/二维费用背包
  • 番茄小说下载器终极指南:如何轻松下载并离线阅读番茄小说
  • Nexknit Gateway v0.2.0:全新采集器与告警系统上线
  • AI营销新纪元:多智能体协作破局
  • 回民街的坑很多,但洒金桥那条巷子藏着真正的老味道
  • 2026年5月口碑好的武汉地下管线漏水检测公司排行榜厂家推荐榜,家庭/厂房/市政管道漏水检测厂家选择指南 - 海棠依旧大
  • Windows系统的用户管理操作
  • 北京研华医疗工控机
  • 2026年当下,温州别墅门窗选购指南与实力生产商深度解析 - 2026年企业资讯
  • 强强联合!比昂芯携手麒麟软件,打造新一代全栈国产化电路仿真解决方案
  • Magisk系统级修改框架:Android权限管理与系统定制终极指南
  • 别再问红外图像为啥模糊了!一文讲透它与可见光融合的实战价值(附Python代码示例)
  • 基于Arduino的轻量级外骨骼手臂:从力反馈原理到DIY实践
  • DeepSeek + 腾讯云函数SCF实现毫秒级弹性扩缩容:单实例QPS突破128,成本直降63%(含压测数据对比表)
  • 保姆级教程:手把手教你下载并处理ImageNet1K验证集(附Python脚本)
  • 异构PIM架构热管理挑战与THERMOS解决方案
  • 矩阵控制屏障函数(MCBF)在机器人安全控制中的应用
  • Instagram如何批量私信?外贸人必学的INS协议群发教程
  • 保姆级教程:用U盘启动盘修复Win10的No Bootable Device和蓝屏重启
  • 保姆级教程:用OpenCV的SGBM算法搞定双目立体匹配(附Python代码避坑指南)
  • 串的块链存储表示及其插入、删除操作
  • 订单越多,利润越少?本地生活行业告别“租流量”,用 LikeShop 搭建自己的用户体系
  • 提升JAVA从业者工作效率的Claude Code使用技巧
  • RAG 文档切片实战:国标知识库篇(一)——基础切片
  • 从零到一:如何用chanvis搭建你的专属缠论量化分析系统
  • 读懂JBoltAI智能问数升级:企业AI用数,瓶颈不是模型
  • 跨境直播拍卖高并发场景下的网络稳定性技术实践