手把手教你用Python写一个“麻将胡了”判断程序
大家好,我是你们的自媒体作者小码哥,今天不聊八卦、不讲热点,来点硬核又有趣的——用Python写一个能自动判断“麻将是否胡了”的程序!你没听错,就是那种你在手机上玩麻将时,系统提示“恭喜你胡了!”的逻辑。
很多人以为打麻将全靠运气,但其实背后有一套严谨的数学规则和算法逻辑,标准的国标麻将中,“胡牌”必须满足以下条件:
我们今天的目标,就是把这个判断过程自动化!用代码模拟人类玩家的思考路径。
先说思路:
我们要写一个函数,输入是一组14张牌(用数字表示,1~9代表筒子,10~18是条子,19~27是万子,28~34是东南西北中发白),输出是True or False —— 表示是否胡牌。
步骤拆解如下:
第一步:预处理数据
把输入的牌整理成一个列表,[1, 1, 1, 2, 3, 4, 5, 6, 7, 8, 9, 9, 9, 10],然后统计每种牌的数量(可以用字典或Counter),这样就能快速判断是否有刻子、顺子。
第二步:枚举所有可能的“将牌”
因为胡牌必须有一对将牌,所以我们先尝试每一种可能出现的将牌(即两张相同的牌),如果牌中有三个1,那我们可以选两个作为将,剩下的一张可以参与顺子/刻子。
第三步:递归判断剩余12张牌能否分成4组合法组合
这是一个关键点,我们写一个递归函数,不断尝试从剩余牌中提取一组顺子或刻子,直到没有牌为止,如果某次成功分完,说明这局能胡!
具体怎么判断顺子?
比如牌是[1,2,3],我们就认为它是一个顺子(同花色连续数字),注意:顺子只能是连续三个不同数字,且在同一花色内(比如筒子1-2-3,不能跨花色)。
刻子则是三张相同数字,1,1,1]。
第四步:优化与剪枝
为了提高效率,我们可以在递归过程中加入一些剪枝策略,
下面是我写的简化版Python代码(适合初学者理解):
from collections import Counter
def is_valid_mahjong(hand):
def can_form_group(counts, group_type, target):
if group_type == 'triplet':
return counts[target] >= 3
elif group_type == 'sequence':
return (counts[target] > 0 and
counts[target+1] > 0 and
counts[target+2] > 0)
def try_split(counts, used_groups=0):
if used_groups == 4:
return True
for i in range(1, 10): # 筒子
if counts[i] >= 3:
counts[i] -= 3
if try_split(counts, used_groups + 1):
return True
counts[i] += 3
for i in range(1, 8): # 顺子,最多到7才能凑出1-2-3
if counts[i] > 0 and counts[i+1] > 0 and counts[i+2] > 0:
counts[i] -= 1
counts[i+1] -= 1
counts[i+2] -= 1
if try_split(counts, used_groups + 1):
return True
counts[i] += 1
counts[i+1] += 1
counts[i+2] += 1
return False
hand = sorted(hand)
counts = Counter(hand)
# 尝试每一对作为将牌
for card in set(hand):
if counts[card] >= 2:
counts[card] -= 2 # 去掉一对将牌
if try_split(counts.copy()):
return True
counts[card] += 2 # 回溯
return False
print(is_valid_mahjong([1,1,1,2,3,4,5,6,7,8,9,9,9,10])) # False
print(is_valid_mahjong([1,1,1,2,2,2,3,3,3,4,4,4,5,5])) # True(三组刻子 + 一对将)
这个程序虽然简略,但已经能准确识别大部分常见胡牌情况,你可以把它扩展为GUI界面,甚至接入微信小程序或抖音小游戏,让AI帮你判断胡牌状态!
写这个程序的过程,其实就是把“人类思维”变成“机器逻辑”,从数据结构、递归回溯到剪枝优化,全是编程基本功,更重要的是,它让我们明白:麻将不仅是娱乐,更是算法思维的绝佳训练场!
如果你也喜欢这种“生活+技术”的结合,请点赞关注我!下期我想讲《用Python写一个自动洗牌发牌的麻将游戏》,敬请期待!
