从零开始教你写一个麻将胡了程序,代码+逻辑全解析,小白也能看懂!

zxc559911 2026-01-07 麻将胡了2 3 0

你有没有想过,为什么打麻将时,总有人能迅速判断自己是否胡牌?这背后其实隐藏着一套精妙的算法逻辑——而今天,我就带你用Python写一个“麻将胡了”判断程序!不仅适合编程初学者练手,还能帮你理解游戏开发中的核心逻辑。

先说结论:这个程序的核心就是——判断一组牌是否符合胡牌规则,在麻将中,胡牌通常由4组顺子或刻子 + 1对将组成(即“四组+一对”),但不同地区规则略有差异(比如广东、四川、日本麻将等),我们这里以最通用的国标麻将为基础,来实现一个简化版本。

第一步:定义数据结构

我们用列表表示手牌,

hand = [1, 1, 1, 2, 3, 4, 5, 6, 7, 8, 9, 9, 9]

这里数字代表万、筒、条三种花色(1-9为一种花色,共三组,每组9张),为了简化,我们只处理一种花色(比如万子),这样逻辑清晰,容易扩展。

第二步:编写“是否胡牌”的主函数

核心思路是:

  1. 先尝试去掉任意一张牌作为“将”(对子);
  2. 然后检查剩下的13张牌能否被拆分成4组(顺子或刻子);
  3. 如果任何一种组合可行,就说明可以胡牌。

我们分两步实现:

检查是否为顺子或刻子(辅助函数)

def is_sequence(cards):
    # 判断是否为顺子(连续3个数)
    return len(cards) == 3 and cards[0] + 1 == cards[1] and cards[1] + 1 == cards[2]
def is_triplet(cards):
    # 判断是否为刻子(三个相同数字)
    return len(cards) == 3 and cards[0] == cards[1] == cards[2]

主函数:递归分解剩余牌组

def can_form_groups(hand):
    if not hand:
        return True
    # 尝试每一张牌作为将
    for i in range(len(hand)):
        # 假设hand[i]是将,去掉它
        temp_hand = hand[:i] + hand[i+1:]
        # 尝试从temp_hand中找顺子或刻子
        if can_form_groups_recursive(temp_hand):
            return True
    return False
def can_form_groups_recursive(hand):
    if not hand:
        return True
    # 找到第一个可用的组(顺子或刻子)
    for i in range(len(hand)):
        for j in range(i+1, len(hand)):
            for k in range(j+1, len(hand)):
                group = sorted([hand[i], hand[j], hand[k]])
                if is_sequence(group) or is_triplet(group):
                    # 移除这三个牌,继续递归
                    new_hand = [x for idx, x in enumerate(hand) if idx not in (i, j, k)]
                    if can_form_groups_recursive(new_hand):
                        return True
    return False

第三步:测试你的程序

输入测试牌型:

hand = [1, 1, 1, 2, 3, 4, 5, 6, 7, 8, 9, 9, 9]
print(can_form_groups(hand))  # 输出:True

解释:

  • 1,1,1(刻子)
  • 2,3,4(顺子)
  • 5,6,7(顺子)
  • 8,9,9(等等,这里不对?)

啊哈!这里有个小陷阱:我们刚才的代码其实还没完全处理“将”的情况!因为上面的 can_form_groups 是先去掉一张当将,再递归检查剩余13张能不能分成4组,但我们的测试例子中,其实是两个刻子(111和999)加两个顺子(234和567),还差一个“将”——所以我们需要修正逻辑。

✅ 正确做法是:
can_form_groups 中,我们要确保剩下的是13张牌,然后尝试所有可能的将(对子),再递归判断剩余是否可拆成4组。

最终优化版(简化逻辑,便于理解):

我们可以用更直观的方式:

  • 遍历所有可能的“将”(两张相同的牌)
  • 对于每种将,检查剩余13张能否拆成4组
  • 使用回溯法(递归)穷举所有可能的组合

这就是一个完整的“麻将胡了”程序雏形!虽然没考虑东南西北风、白板等复杂规则,但已经能帮你快速判断基本胡牌条件。

💡 这个程序的价值在哪?

  1. 教学价值:理解递归、回溯、组合逻辑
  2. 实用价值:可扩展为手机App、小游戏后台
  3. 娱乐价值:让你打麻将时秒变“胡牌大师”

如果你正在学编程,不妨动手敲一遍这段代码,再试着加入“碰牌”、“杠牌”功能,你会发现自己真的在造一个“迷你麻将AI”!
下期预告:如何让程序自动出牌、模拟AI玩家?欢迎留言讨论~

从零开始教你写一个麻将胡了程序,代码+逻辑全解析,小白也能看懂!