大家好,我是你们的老朋友,一个专注于用代码讲生活、玩转小游戏的自媒体作者,今天不聊流量、不谈变现,咱们来点硬核的——手把手教你用 Python 写一个完整的“麻将胡了”游戏!别怕,哪怕你是编程小白,只要跟着我一步步走,也能在 2 小时内做出一个能玩、能赢、还能自己加规则的小程序!
为什么选“麻将胡了”?因为它是中文语境里最接地气的游戏之一,几乎每个家庭过年过节都会搓几圈,它不仅考验运气,更讲究策略和记忆,而把它变成代码,就是把“人脑计算”变成了“机器模拟”,简直太酷了!
🎯 我的目标是:
- 实现一副标准麻将牌(万、条、筒各 9 张 ×4 = 36 张 + 字牌 ×4 = 4 张,共 136 张);
- 洗牌、发牌(每人13张,庄家14张);
- 玩家可以打牌、碰、杠、胡;
- 判断是否胡牌(符合基本胡牌规则:4组顺子/刻子 + 1对将牌);
- 可扩展:加入AI玩家、计分系统、界面化(比如用 Pygame 或 Tkinter)。
📌 第一步:定义牌类结构
我们先创建一个 Tile 类,表示一张牌:
class Tile:
def __init__(self, suit, value):
self.suit = suit # '万', '条', '筒', '东'等
self.value = value
def __str__(self):
return f"{self.suit}{self.value}"
然后生成整副牌:
def create_tiles():
tiles = []
for suit in ['万', '条', '筒']:
for value in range(1, 10):
tiles.extend([Tile(suit, value)] * 4)
for suit in ['东', '南', '西', '北', '中', '发', '白']:
tiles.extend([Tile(suit, None)] * 4)
return tiles
📌 第二步:洗牌与发牌
用 random.shuffle() 随机打乱顺序,再分给玩家(这里简化为两个玩家+庄家):
import random
def deal_tiles(tiles, num_players=2):
random.shuffle(tiles)
hands = [[] for _ in range(num_players)]
for i in range(13):
for j in range(num_players):
hands[j].append(tiles.pop())
# 庄家多一张
hands[0].append(tiles.pop())
return hands
📌 第三步:判断胡牌逻辑 —— 核心难点!
这是整个程序的灵魂,我们要检查玩家手里的牌能否组成 4 组(顺子或刻子)+ 1 对将牌。
核心思路是:
- 先统计每种牌的数量;
- 用递归回溯尝试所有组合方式;
- 如果找到一种合法组合,就返回 True。
这是一个简化的版本(实际可优化成 DP 或剪枝):
def is_valid_hu(hand):
from collections import Counter
count = Counter(tile.suit + str(tile.value) if tile.value else tile.suit for tile in hand)
def can_form_groups(count):
if not count:
return True
# 找到第一张非空的牌
tile_str = next(iter(count))
tile = tile_str[0] + tile_str[1:] if len(tile_str) > 1 else tile_str
val = int(tile_str[1:]) if len(tile_str) > 1 else None
# 尝试三种情况:刻子、顺子、对子
if count[tile_str] >= 3:
new_count = count.copy()
new_count[tile_str] -= 3
if not new_count[tile_str]:
del new_count[tile_str]
if can_form_groups(new_count):
return True
# 顺子:需要同花色连续三张
if tile in ['万', '条', '筒'] and val <= 7:
next1 = tile + str(val + 1)
next2 = tile + str(val + 2)
if count[next1] > 0 and count[next2] > 0:
new_count = count.copy()
new_count[tile_str] -= 1
new_count[next1] -= 1
new_count[next2] -= 1
if not new_count[tile_str]: del new_count[tile_str]
if not new_count[next1]: del new_count[next1]
if not new_count[next2]: del new_count[next2]
if can_form_groups(new_count):
return True
# 对子:单独配对
if count[tile_str] >= 2:
new_count = count.copy()
new_count[tile_str] -= 2
if not new_count[tile_str]: del new_count[tile_str]
if can_form_groups(new_count):
return True
return False
return can_form_groups(count)
📌 最后一步:运行游戏流程
你可以把这个函数嵌入到主循环中,让玩家输入打哪张牌、是否碰杠、是否胡,每次操作后调用 is_valid_hu() 判断是否胜利。
💡 小贴士:
- 加入日志打印当前手牌状态,方便调试;
- 用
input()接收用户指令,“打 万3”、“碰 东”; - 后续可升级为图形界面(Tkinter)或 Web 版(Flask + HTML);
- AI玩家可以用随机选择 + 胡牌概率预判(进阶玩法)!
🎯
今天我们从零搭建了一个“麻将胡了”的简易版游戏框架,虽然功能简单,但已经涵盖了核心逻辑:洗牌、发牌、出牌、胡牌判定,你完全可以基于这个基础继续拓展,比如加入番数计算、多人联机、AI对战等等!
如果你觉得有趣,欢迎留言告诉我你想加什么功能?下一期我可以教你如何用 Flask 做网页版麻将,或者用强化学习训练AI对手!关注我,一起用代码玩转生活中的乐趣 👨💻🀄️







