你有没有想过,自己也能写出一个能自动判断是否“胡牌”的麻将程序?不是靠运气,而是靠代码逻辑!我就带大家用Python一步步实现一个基础但功能完整的“麻将胡了”判断器,这不仅是编程爱好者的挑战,也是理解算法思维的好机会。
先说结论:一个标准的麻将胡牌规则,核心在于“四组一對”,即4个顺子或刻子 + 1对将牌,我们这个程序的目标就是输入一组牌(比如123456789万条筒),然后判断它能不能胡牌。
为什么做这个?
这是典型的回溯算法应用场景——你要遍历所有可能的组合方式来判断是否存在一种合法胡法,它融合了数据结构(列表、字典)、递归、剪枝优化等编程技巧,非常适合初学者练手,如果你是个麻将爱好者,写完后还能拿去测试朋友的牌是不是真能胡!
准备阶段:环境搭建
你需要安装Python 3.8+(推荐Anaconda),不需要额外库,纯原生代码即可运行,我会用最直观的方式写,不依赖第三方模块,保证可读性强,适合边看边敲代码。
第一步:定义牌面和基本数据结构
我们用字符串表示牌,“1万”、“5筒”、“9条”,为了方便处理,我们把所有牌按数字分组:万、条、筒各1~9,我们用一个列表存储输入的牌,["1万", "2万", "3万", "4筒", "4筒", "4筒"]。
第二步:编写判断函数
核心逻辑是“尝试拆解牌组”,用递归实现回溯:
def can_win(cards):
if not cards:
return True # 所有牌都拆完了,说明胡了
# 尝试找一对将牌(两个相同的)
for i in range(len(cards)):
for j in range(i+1, len(cards)):
if cards[i] == cards[j]:
new_cards = cards[:i] + cards[i+1:j] + cards[j+1:]
if can_win(new_cards): # 递归检查剩余牌是否能组成三组
return True
# 如果找不到将牌,就尝试找顺子或刻子
for i in range(len(cards)):
card = cards[i]
# 刻子:三个一样的
if card in cards[:i] and card in cards[i+1:]:
new_cards = cards[:i] + cards[i+1:]
if can_win(new_cards):
return True
# 顺子:同一花色连续三张(如123)
# 这里简化处理:只考虑同花色且数字连续
if card.endswith("万") or card.endswith("条") or card.endswith("筒"):
num = int(card[:-1])
next_num = num + 1
next_next_num = num + 2
next_card = f"{next_num}{card[-1]}"
next_next_card = f"{next_next_num}{card[-1]}"
if next_card in cards and next_next_card in cards:
new_cards = cards[:i] + cards[i+1:]
new_cards.remove(next_card)
new_cards.remove(next_next_card)
if can_win(new_cards):
return True
return False
这段代码虽然简洁,但逻辑完整:
- 先找将牌(两个相同)
- 再找刻子(三个相同)
- 最后找顺子(连续三张)
每次拆掉一组后,递归调用自身判断剩余牌是否还能胡。
第三步:测试你的程序
试试这个输入:["1万", "2万", "3万", "4万", "5万", "6万", "7万", "8万", "9万", "1万", "1万"]
这其实是“清一色七对子”的变体,应该能胡!
运行结果会告诉你:True ✅
再试一个反例:["1万", "2万", "3万", "4万", "5万", "6万", "7万", "8万", "9万"] —— 缺少一对将牌,不能胡!结果为 False ❌
优化建议:
目前版本性能一般,因为存在重复计算,你可以加入记忆化缓存(@lru_cache)来加速,可以扩展支持“十三幺”、“七对子”等特殊牌型,让程序更贴近真实麻将规则。
写这个程序的过程,其实是在训练我们的算法思维:如何把复杂问题分解成小步骤?如何避免无效搜索?如何通过递归来穷举所有可能性?这些能力,远比“打麻将赢钱”更重要!
如果你想进一步学习,我建议你:
- 把这个程序封装成类,支持多局游戏记录;
- 加入GUI界面(用Tkinter);
- 对接AI模型,让它帮你出牌建议!
别忘了动手实践!码上就是最好的学习方式,下次打麻将时,说不定你能笑着告诉朋友:“这手牌,我用Python算过,稳胡!” 😄







