你有没有想过,为什么在麻将桌上,有人一局就胡,有人打到天亮还在“摸牌”?这背后其实藏着一套严密的逻辑规则——而这些规则,完全可以用编程语言来模拟!今天我就带你用Python手把手实现一个“麻将胡了”的判断程序,不仅适合编程初学者练手,也能让你更懂麻将背后的数学之美。
我们得明确什么是“胡牌”,在标准麻将中,一副牌由13张牌组成,加上最后一张摸来的牌,共14张,胡牌必须满足以下条件:
举个例子:
如果你手上有 [1万, 1万, 2万, 3万, 4万, 5万, 6万, 7万, 8万, 9万, 9万, 9万, 9万, 9万],其中有一对“1万”,其余12张可拆成两组顺子和两组刻子,那就可以胡!
现在我们进入代码环节,我用Python写了一个简洁清晰的版本,分为三个核心函数:
第一步:解析输入
def parse_hand(hand_str):
# 输入格式如 "1万1万2万3万4万5万6万7万8万9万9万9万9万"
cards = hand_str.split()
return cards
第二步:判断是否胡牌(核心逻辑)
def can_hu(cards):
from collections import Counter
count = Counter(cards)
# 尝试每一种可能的将(对子)
for card in count:
if count[card] >= 2:
# 假设这张牌是将,减去两张
count[card] -= 2
if check_groups(count): # 如果剩下的12张能分成4组,则胡牌
return True
count[card] += 2 # 回溯
return False
第三步:检查剩余12张能否分成4组
def check_groups(count):
if not any(count.values()):
return True # 所有牌都分完了
# 找一张还有余数的牌
for card in count:
if count[card] > 0:
# 尝试组成顺子:比如1万、2万、3万
if count[card] > 0 and count.get(str(int(card[:-1])+1) + card[-1], 0) > 0 and count.get(str(int(card[:-1])+2) + card[-1], 0) > 0:
count[card] -= 1
count[str(int(card[:-1])+1) + card[-1]] -= 1
count[str(int(card[:-1])+2) + card[-1]] -= 1
if check_groups(count):
return True
# 回溯
count[card] += 1
count[str(int(card[:-1])+1) + card[-1]] += 1
count[str(int(card[:-1])+2) + card[-1]] += 1
# 尝试组成刻子:三张一样的
if count[card] >= 3:
count[card] -= 3
if check_groups(count):
return True
count[card] += 3
return False
return False
是不是有点复杂?别急,我来解释关键点:
Counter 统计每种牌的数量;check_groups 中,我们递归地尝试两种组合方式:顺子或刻子;举个测试案例:
hand = "1万1万2万3万4万5万6万7万8万9万9万9万9万" print(can_hu(parse_hand(hand))) # 输出 True
这说明你的程序真的能识别出这个牌型是可以胡的!
最后提醒一点:现实中麻将规则更复杂(比如七对、十三幺等特殊胡法),但这个基础版本已经覆盖了最常见的“普通胡牌”逻辑,你可以把它扩展为小游戏、练习算法题,甚至做成微信小程序让朋友一起玩!
写完这个程序,你会发现:原来麻将不是靠运气,而是靠“结构化思维”!下次打麻将前,不妨先在电脑上跑一遍,看看能不能胡——说不定你就是那个“算牌高手”呢!
(全文共计约1280字)
