从零开始写一个麻将胡了游戏代码,用Python实现经典牌类玩法的完整逻辑!

大家好,我是你们的老朋友,一个专注于用代码讲生活、玩转小游戏的自媒体作者,今天不聊流量、不谈变现,咱们来点硬核的——手把手教你用 Python 写一个完整的“麻将胡了”游戏!别怕,哪怕你是编程小白,只要跟着我一步步走,也能在 2 小时内做出一个能玩、能赢、还能自己加规则的小程序!

为什么选“麻将胡了”?因为它是中文语境里最接地气的游戏之一,几乎每个家庭过年过节都会搓几圈,它不仅考验运气,更讲究策略和记忆,而把它变成代码,就是把“人脑计算”变成了“机器模拟”,简直太酷了!

🎯 我的目标是:

  1. 实现一副标准麻将牌(万、条、筒各 9 张 ×4 = 36 张 + 字牌 ×4 = 4 张,共 136 张);
  2. 洗牌、发牌(每人13张,庄家14张);
  3. 玩家可以打牌、碰、杠、胡;
  4. 判断是否胡牌(符合基本胡牌规则:4组顺子/刻子 + 1对将牌);
  5. 可扩展:加入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对手!关注我,一起用代码玩转生活中的乐趣 👨‍💻🀄️

从零开始写一个麻将胡了游戏代码,用Python实现经典牌类玩法的完整逻辑!