从零到一教你写一个麻将胡了程序,代码逻辑拆解与实战演示

你有没有想过,为什么每次打麻将,总有人“听牌三圈,胡了最后一张”?这背后不只是运气,还有算法在默默工作——比如我们今天要讲的“麻将胡了判断程序”,作为一个自媒体作者,我不仅会带你搞懂这个程序怎么写,还会用通俗易懂的方式拆解它的底层逻辑,让你真正理解“胡牌”是怎么被计算机识别出来的。

先说结论:一个完整的麻将胡了判断程序,核心在于三个步骤:

  1. 牌型合法性校验(是否符合基本规则)
  2. 胡牌组合判定(能否组成4组顺子/刻子 + 1对将)
  3. 特殊牌型识别(如七对、十三幺、混一色等)

下面,我就用 Python 来一步步实现它,全程不跳步,小白也能看懂!


第一步:数据结构设计

我们需要把麻将牌表示成计算机能处理的数据,通常用数字表示牌面,

  • 1~9:万、条、筒各一套(共三组)
  • 10~13:东、南、西、北(字牌)
  • 14~17:中、发、白(字牌)

为了方便,我们定义一个函数 is_valid_hand(hand) 来检查输入的手牌是否合法——即总数必须是13张(或14张用于判断是否可以胡),且每种牌不超过4张。

def is_valid_hand(hand):
    if len(hand) not in [13, 14]:
        return False
    count = {}
    for card in hand:
        count[card] = count.get(card, 0) + 1
        if count[card] > 4:
            return False
    return True

第二步:判断是否能胡牌(核心逻辑)

接下来是最关键的部分:如何判断这13张牌能不能组成胡牌?

麻将胡牌的基本条件是:

  • 4组面子(顺子或刻子) + 1对将牌(一对相同的牌)

我们可以用递归回溯法来穷举所有可能的组合方式:

def can_win(hand):
    if not is_valid_hand(hand):
        return False
    # 如果是14张,尝试去掉一张作为“摸到的那张”,看看剩下13张能不能胡
    if len(hand) == 14:
        for i in range(14):
            remaining = hand[:i] + hand[i+1:]
            if can_win(remaining):
                return True
        return False
    # 如果是13张,直接判断能否组成胡牌
    cards = sorted(hand)
    return backtrack(cards, [])
def backtrack(cards, groups):
    if not cards:
        return len(groups) == 4  # 必须刚好4组
    # 尝试当前牌组成顺子或刻子
    first = cards[0]
    rest = cards[1:]
    # 刻子:三张一样的
    if cards.count(first) >= 3:
        new_groups = groups + [[first]*3]
        new_cards = [c for c in cards if c != first]
        if backtrack(new_cards, new_groups):
            return True
    # 顺子:连续三张(只适用于1~9)
    if first <= 7 and (first+1 in cards) and (first+2 in cards):
        new_groups = groups + [[first, first+1, first+2]]
        new_cards = [c for c in cards if c not in [first, first+1, first+2]]
        if backtrack(new_cards, new_groups):
            return True
    return False

这段代码虽然简洁,但效率不高,不过对于教学和演示来说完全够用!实际项目中可以用剪枝优化或动态规划。

第三步:加入特殊牌型识别(进阶玩法)

如果你玩的是国标麻将,还得考虑七对、十三幺、混一色这些特殊牌型,七对”就是7对相同牌(共14张):

def is_seven_pairs(hand):
    if len(hand) != 14:
        return False
    count = {}
    for card in hand:
        count[card] = count.get(card, 0) + 1
    return all(v == 2 for v in count.values())

这样,你的程序就能识别出“别人明明没胡,却突然说‘我七对’”的情况啦!


不只是代码,更是思维方式

写这样一个“麻将胡了”程序,看似只是个小游戏,实则训练了我们三种能力:

  1. 问题拆解能力:把复杂问题分解为小步骤;
  2. 递归思维:穷举所有可能性,找到最优解;
  3. 边界意识:比如合法牌数、重复牌限制等细节。

下次你再看到朋友喊“胡了”,不妨问一句:“你是怎么判断的?”——说不定他连算法都没学过呢!

如果你想自己动手试试,建议从基础版开始,逐步加上七对、十三幺等功能,GitHub 上也有开源项目可以参考,mahjong-solver

编程不是炫技,而是解决问题的艺术,麻将胡了程序,就是一个绝佳的起点。

现在轮到你了:你打算怎么优化这个程序?评论区见!

从零到一教你写一个麻将胡了程序,代码逻辑拆解与实战演示

麻将胡了