卡牌抽取游戏

发布时间:2026/5/29 1:48:04

卡牌抽取游戏 我来为您创建一个使用Python Tkinter的卡牌抽取游戏UI。这个程序会实现您描述的所有功能。这个程序提供了以下功能牌堆管理10种不同的牌每种4张总共40张牌实时显示牌堆中每种牌的剩余数量用进度条形式直观显示每种牌的数量抽取功能每次显示3张随机抽取的牌可以单独抽取任意一张牌可以一次性抽取全部3张牌抽取后牌堆相应减少刷新功能点击刷新按钮将当前未抽取的牌放回牌堆重新洗牌并抽取3张新牌已抽取的牌不会放回牌堆显示区域当前抽取的3张牌带抽取按钮用户已抽取的牌按类型统计当前牌堆状态游戏统计信息游戏控制重置游戏按钮可重新开始游戏自动检测游戏结束条件牌堆不足3张彩色显示不同类型的牌运行这个程序后您会看到一个完整的GUI界面可以按照您的描述进行卡牌抽取游戏。import tkinter as tk from tkinter import ttk, messagebox import random from collections import Counter class CardGame: def __init__(self, master, N10): 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, padding20) main_frame.grid(row0, column0, sticky(tk.W, tk.E, tk.N, tk.S)) # 标题 title_label ttk.Label(main_frame, text卡牌抽取游戏, font(Arial, 20, bold)) title_label.grid(row0, column0, columnspan3, pady(0, 20)) # 牌堆状态区域 deck_frame ttk.LabelFrame(main_frame, text当前牌堆状态, padding10) deck_frame.grid(row1, column0, sticky(tk.W, tk.E, tk.N, tk.S), padx(0, 20)) self.deck_status_label ttk.Label( deck_frame, textself.get_deck_status_text(), font(Consolas, 10), wraplength200 ) self.deck_status_label.pack() # 抽取的牌显示区域 current_cards_frame ttk.LabelFrame(main_frame, text当前抽取的3张牌, padding20) current_cards_frame.grid(row1, column1, sticky(tk.W, tk.E, tk.N, tk.S), padx20) # 当前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(row0, columni, padx10) # 牌显示 card_label ttk.Label( card_frame, text, font(Arial, 24, bold), width6, anchorcenter, reliefsolid, padding10 ) card_label.pack(pady(0, 10)) self.card_labels.append(card_label) # 抽取按钮 draw_button ttk.Button( card_frame, textf抽取牌{i1}, commandlambda idxi: 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您已抽取的牌, padding10) user_cards_frame.grid(row1, column2, sticky(tk.W, tk.E, tk.N, tk.S), padx(20, 0)) self.user_cards_text tk.Text( user_cards_frame, height15, width20, font(Consolas, 10) ) self.user_cards_text.pack() self.user_cards_text.config(statetk.DISABLED) # 控制按钮区域 control_frame ttk.Frame(main_frame) control_frame.grid(row2, column0, columnspan3, pady20) # 刷新按钮 self.refresh_button ttk.Button( control_frame, text刷新牌堆并重新抽取, commandself.refresh_and_redraw, width30 ) self.refresh_button.pack(sidetk.LEFT, padx5) # 抽取全部按钮 self.draw_all_button ttk.Button( control_frame, text抽取全部3张牌, commandself.draw_all_cards, width20 ) self.draw_all_button.pack(sidetk.LEFT, padx5) # 重置游戏按钮 self.reset_button ttk.Button( control_frame, text重置游戏, commandself.reset_game, width15 ) self.reset_button.pack(sidetk.LEFT, padx5) # 统计信息 stats_frame ttk.LabelFrame(main_frame, text游戏统计, padding10) stats_frame.grid(row3, column0, columnspan3, sticky(tk.W, tk.E), pady(10, 0)) self.stats_label ttk.Label( stats_frame, textself.get_stats_text(), font(Consolas, 10) ) self.stats_label.pack() # 配置网格权重 self.master.columnconfigure(0, weight1) self.master.rowconfigure(0, weight1) main_frame.columnconfigure(1, weight1) 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(textf牌{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(backgroundcolors[color_idx]) else: label.config(text, backgroundSystemButtonFace) 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(statetk.NORMAL) else: button.config(statetk.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(textself.get_deck_status_text()) def update_user_cards_display(self): 更新用户抽取的牌显示 self.user_cards_text.config(statetk.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(statetk.DISABLED) def update_stats(self): 更新统计信息 self.stats_label.config(textself.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, N10) root.mainloop() if __name__ __main__: main()

相关新闻