做棋牌产品的人常碰到一个尴尬事:同样叫“麻将”,跨过一条江,代码就得重写。

九江市区和周边几个县市,再加上隔江的湖北黄梅、安徽安庆,规则像方言一样存在过渡带——有些细节连本地牌友都说不清,只能靠牌桌上临时约定。

这篇不谈情怀,只从算法实现的角度,把九江玩法与周边规则的差异拆开看看。

牌张构成:108 张和 136 张,是两个世界

九江城区一带的主流打法多用 108 张,只保留万、条、筒三门,节奏偏快,胡牌门槛不高。部分局会加入红中充当赖子,但红中本身不进顺子、不做将的限制各地不一。

往南走到南昌,136 张是常态,风牌、箭牌齐全,还带一整套“精牌”体系。再往东到景德镇、上饶方向,牌张数和对字牌的处理又有自己的偏好。

这个差异对算法的第一层影响是数据结构。108 张可以用紧凑的计数数组,136 张要考虑字牌编码。如果同一套服务要同时支持两种牌张,最好把牌墙做成配置项,而不是在判定函数里写死长度。

赖子与精牌:都是“万能牌”,实现成本差很多

表面看,九江的红中赖子和南昌的精牌是一回事——都能替代任意牌。真写起来不是。

  • 九江部分玩法里,赖子只能补顺子或刻子,不能单独做将,胡牌判定时只需在枚举组合时替换有限位置。
  • 南昌精牌逻辑更绕:翻精决定精牌身份,精牌能做将但算分不同,还牵出冲关、霸王精等一串衍生规则,判定胡牌之后还要再跑一遍算分分支。
  • 有些周边乡镇的局干脆规定“赖子不能点炮”,这条如果不加进听牌提示,玩家会觉得系统在骗他。

所以做通用算法时,赖子不能只做成一个布尔开关,至少拆成“可替代范围”“是否可做将”“是否参与点炮”三个参数,否则后期改一处崩一片。

胡牌判定:平胡之外的那些岔路

九江主流是 4 副牌加 1 将的标准结构,七对、清一色、碰碰胡作为加成牌型,判定分支不算多。

周边规则就热闹了:江西不少地方认“十三烂”,即十三张互不搭靠的牌,检测逻辑和标准胡牌完全是两套代码;还有些局允许“杠上开花”直接翻倍,甚至把“海底捞月”单列番种。

这里有个容易被忽略的点——十三烂在九江市区接受度并不统一。有的牌桌认,有的牌桌直接说“我们这不打这个”。

做产品时把它做成房间可选项,比强行统一更省事。

番型与结算:分差往往出在这一步

胡牌算法算的是“能不能胡”,结算算法算的是“该给多少”,后者才是争议高发区。九江一带计分相对扁平,封顶值不高。

南昌方向因为精牌和冲关机制,单局分值波动大,必须设封顶。再比如一炮多响,九江多数局只认一炮,周边有些地方允许一炮多响,还有“包三家”的约定——点炮者承担全部或大部分分数。

杠分也是同理。明杠、暗杠、补杠的即时结算与终局结算,各地习惯不同,写进算法表时要标明结算时机,否则对账时永远扯不清。

把规则做成一张可配置的算法表

如果只服务九江本地,硬编码也许够用。一旦要覆盖周边,比较现实的做法是抽出一份九江麻将算法列表式的参数表,按维度组织:牌张集合、赖子规则组、牌型开关、番值映射、结算模式、封顶值。每开一个新地区,填表而不是改代码。

当然,这套思路也有例外。麻将规则在县域内靠口口相传,同一款玩法隔条街就可能变样,任何一份规则文档都只能算“参考版本”。产品上留一个房间自定义入口,让牌友自己勾选,往往比追求绝对正确更实用。