三国杀online张昌蒲严教算数辅助器(带GUI界面)

博主是一名三国杀玩家,玩张昌蒲时发现算数这个技能可以通过编程解决。于是基于python和tk界面做了个算数器,经过博主实测,效果还行。

界面布局如下:

使用方法大家应该一看就能看懂:例如本次严教算数共有6张牌:9 Q Q 4 8 3 4 ,那么

则需要依次点击数字按钮即可完成选牌,选好牌后按计算就能得出结果,并且很人性化的是博主同时把计算结果复制到了你的剪切板中(至于这样要干嘛你玩多了就知道)。

下一次严教时则需要清空上次的选择和结果,就可以重新选牌。

下面讲讲算法的逻辑大致是数量优先,就是尽可能地分出来更多的牌,就是让未使用的牌最少(最好为零)。因为张昌蒲这个技能也是要求你尽量把牌都分完,如果未使用的牌数量超过1,那张昌蒲这轮的手牌上限就减一。一些资深的三国杀玩家可能会偏向于拿关键的牌而忽略牌数,这样也有道理,本算数辅助器其实只是辅助你计算得出牌数最优的结果,在此基础上你可以稍加调整,以上面的第一组Q Q,第二组 9 4 8 3 为例,假设你觉得4是一张桃比较关键你想分到第一组,你就把Q和4+8替换就行了,变成第一组 Q 4 8 ,第二组Q 9 3 。意思就是在得出结果的基础上做调整,拿到你最想要的牌(要是你有这个时间和精力的话,并且我认为资深一点的三国杀玩家对这个调整会更加熟练)。

经过测试,牌数在18以下基本上计算都是秒出结果,这样其实已经能满足几乎所有牌局的需求,因为目前我还很少遇见张昌蒲一次严教能出这么多牌的。

而且我这个算法得出的结果逻辑也是根据牌的顺序来给出的,这样就方便了你分牌时的操作,如图,你可以看到第一组8 4 9 10 K Q Q 3基本上顺序都是跟选牌时的顺序顺延下来的,包括第二组也是一样的,所以你分牌的时候找牌会非常方便。并且我还将该程序固定在了屏幕最顶层,就是只能通过按最小化按钮或关闭按钮才能在屏幕消失,这样就是为了让你分牌找牌的时候可以一边点游戏,一边看辅助器。

以下是部分源码,若想获得完整源码请私聊我或联系作者

import tkinter as tk
from tkinter import ttk, messagebox

class CardButton:
    def __init__(self, text, row, col, command):
        self.text = text
        self.row = row
        self.col = col
        self.command = command
        self.button = None
        
    def create(self, parent):
        self.button = ttk.Button(parent, text=self.text, command=self.command)
        self.button.grid(row=self.row, column=self.col, padx=5, pady=5)

class App:
    def __init__(self, root):
        self.root = root
        self.root.title("张昌蒲算数技能助手")
        
        # 设置窗口大小和位置
        window_width = 600
        window_height = 500
        screen_width = root.winfo_screenwidth()
        screen_height = root.winfo_screenheight()
        x = (screen_width - window_width) // 2
        y = (screen_height - window_height) // 2
        root.geometry(f"{window_width}x{window_height}+{x}+{y}")
        
        # 设置窗口置顶
        root.attributes('-topmost', True)
        
        # 创建菜单栏
        menubar = tk.Menu(root)
        root.config(menu=menubar)
        
        # 添加"与作者交流"菜单项
        def show_contact():
            contact_dialog = ContactDialog(self.root)
            contact_dialog.show()
        
        menubar.add_command(label="与作者交流", command=show_contact)
        
        # 设置样式
        style = ttk.Style()
        style.configure('Card.TButton', padding=6, width=6, font=('Arial', 12))
        style.configure('Action.TButton', padding=6, width=12, font=('Arial', 11))
        style.configure('Calculate.TButton', padding=8, width=15, font=('Arial', 12, 'bold'))
        
        # 当前选择的牌
        self.cards = []
        
        self.create_widgets()
        
    def create_widgets(self):
        # 创建主框架
        main_frame = ttk.Frame(self.root, padding="10")
        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", 16, "bold"))
        title_label.grid(row=0, column=0, columnspan=7, pady=10)
        
        # 创建卡牌区域框架
        cards_frame = ttk.Frame(main_frame)
        cards_frame.grid(row=1, column=0, columnspan=7, pady=5)
        
        # 创建数字牌按钮(A-10)
        card_values = ["A"] + [str(i) for i in range(2, 11)]
        for i in range(10):
            button = ttk.Button(
                cards_frame,
                text=card_values[i],
                style='Card.TButton',
                command=lambda x=i+1: self.add_card(x)
            )
            button.grid(row=i // 5, column=i % 5, padx=4, pady=4)
        
        # 创建字母牌按钮(J、Q、K)
        letter_cards = [("J", 11), ("Q", 12), ("K", 13)]
        for i, (letter, value) in enumerate(letter_cards):
            button = ttk.Button(
                cards_frame,
                text=letter,
                style='Card.TButton',
                command=lambda x=value: self.add_card(x)
            )
            button.grid(row=2, column=i, padx=4, pady=4)
        
        # 创建当前选择的牌的显示区域
        self.cards_label = ttk.Label(main_frame, text="已选择的牌:", font=("Arial", 12))
        self.cards_label.grid(row=2, column=0, columnspan=7, pady=10)
        
        # 创建操作按钮框架
        action_frame = ttk.Frame(main_frame)
        action_frame.grid(row=3, column=0, columnspan=7, pady=5)
        
        # 创建操作按钮
        ttk.Button(
            action_frame,
            text="清空",
            style='Action.TButton',
            command=self.clear_cards
        ).grid(row=0, column=0, padx=8)
        
        ttk.Button(
            action_frame,
            text="删除最后一张",
            style='Action.TButton',
            command=self.remove_last_card
        ).grid(row=0, column=1, padx=8)
        
        ttk.Button(
            action_frame,
            text="计算",
            style='Calculate.TButton',
            command=self.calculate
        ).grid(row=0, column=2, padx=8)
        
        # 创建结果显示区域
        self.result_text = tk.Text(main_frame, height=7, width=50, font=("Arial", 11))
        self.result_text.grid(row=4, column=0, columnspan=7, pady=10)
        self.result_text.config(state=tk.DISABLED)
    
    def add_card(self, value):
        self.cards.append(value)
        self.update_cards_display()
    
    def clear_cards(self):
        self.cards = []
        self.update_cards_display()
        self.clear_result()
    
    def remove_last_card(self):
        if self.cards:
            self.cards.pop()
            self.update_cards_display()
            self.clear_result()
    
    def update_cards_display(self):
        # 将数字转换为显示文本
        display_cards = []
        for card in self.cards:
            if card == 1:
                display_cards.append("A")
            elif card == 11:
                display_cards.append("J")
            elif card == 12:
                display_cards.append("Q")
            elif card == 13:
                display_cards.append("K")
            else:
                display_cards.append(str(card))
        
        self.cards_label.config(text="已选择的牌:" + " ".join(display_cards))
    
    def clear_result(self):
        self.result_text.config(state=tk.NORMAL)
        self.result_text.delete(1.0, tk.END)
        self.result_text.config(state=tk.DISABLED)
    
    def number_to_card(self, number):
        if number == 1:
            return "A"
        elif number == 11:
            return "J"
        elif number == 12:
            return "Q"
        elif number == 13:
            return "K"
        return str(number)

    def format_group(self, group):
        return [self.number_to_card(num) for num in group]

    def calculate(self):
        if len(self.cards) < 4:
            messagebox.showerror("错误", "至少需要4张牌!")
            return
        
        result, num_used, unused = find_equal_sum_groups(self.cards)
        
        self.result_text.config(state=tk.NORMAL)
        self.result_text.delete(1.0, tk.END)
        
        if result:
            group1, group2 = result
            self.result_text.insert(tk.END, "找到解决方案!\n")
            self.result_text.insert(tk.END, f"使用了 {num_used} 张牌\n")
            formatted_group1 = self.format_group(group1)
            formatted_group2 = self.format_group(group2)
            self.result_text.insert(tk.END, f"第一组: {formatted_group1} (和为 {sum(group1)})\n")
            self.result_text.insert(tk.END, f"第二组: {formatted_group2} (和为 {sum(group2)})\n")
            if unused:
                formatted_unused = self.format_group(unused)
                self.result_text.insert(tk.END, f"未使用的牌: {formatted_unused}\n")
            
            # 自动复制结果到剪贴板
            simplified_result = f"第一组:{' '.join(formatted_group1)};第二组:{' '.join(formatted_group2)}"
            self.root.clipboard_clear()
            self.root.clipboard_append(simplified_result)
            self.result_text.insert(tk.END, "\n结果已复制到粘贴板中")
        else:
            self.result_text.insert(tk.END, "没有找到可行的分组方案。\n")
        
        self.result_text.config(state=tk.DISABLED)

最后祝大家使用顺利,牌技日益涨进,有疑问可留言或私聊我

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值