很多做棋牌工具、算番器和规则资料的开发者,提到九江麻将时容易默认只有一套算法。
实际翻阅本地规则、比对不同牌桌的口口相传之后会发现:玩法分支不少,算法侧重点差别也大。有人关心胡牌判定,有人盯着番型查表,还有一类只用来做胜率估算。把这几种需求混成一套表,后续维护会很痛苦。
玩法分支决定了算法骨架
九江本地常见的几种玩法,在牌数与胡牌结构上并不会全盘一致。有些桌保留传统起手张数,有些为了节奏加快会调整;
杠牌是否计分、是否允许抢杠胡、有没有“漂”或“宝”这类特殊牌,都会直接影响胡牌判定函数的分支数量。
换个说法,算法骨架不是由“九江麻将”四个字决定的,而是由具体牌桌约定决定的。同样是清一色,有的规则只按基础番型给分,有的会叠加门清、自摸等条件。写代码时如果先假设一套统一规则,后面补丁会越打越多。
胡牌判定算法:递归回溯与状态压缩的取舍
最直观的做法是递归拆解手牌:先找将牌,再尝试刻子、顺子组合,能拆完即胡。九江玩法里如果存在特殊牌型,递归出口要额外判断,代码可读性好,但性能一般。
另一种思路是状态压缩,把每种牌的数量编码进数组,按花色分段处理。它适合高频调用的场景,比如实时提示听牌。
不过一旦玩法允许“赖子”或万能牌,状态空间会迅速膨胀,压缩带来的收益不一定盖过实现复杂度。这里没有绝对优劣,看你的调用量和规则稳定程度。
番型计算:查表思路与规则引擎的对比
番型部分常见的两种思路:查表和规则引擎。
- 查表法:把已知番型与对应分值整理成静态映射,胡牌后按牌型特征取键。优点是快、易核对,适合规则固定的休闲玩法。缺点是遇到组合叠加、地区差异时要不断扩表。
- 规则引擎:将每个番型写成独立判定条件,按优先级或权重累加。灵活,能处理“满足多条时取最高”或“可叠加”的差异,但调试成本高,容易漏掉互斥关系。
实际项目里常见折中方案:基础番型查表,特殊叠加走小型规则判断。这样既保留了查表的可读性,也不至于被少数复杂牌型拖垮。
查表设计的几个实操细节
键的设计很关键。用字符串拼牌型容易碰撞,用枚举加参数更稳。分值不要只存一个数字,最好区分“底番”和“加成”,方便不同玩法切换。表结构建议按玩法维度分开存放,而不是在一张表里塞条件分支。
还有一点容易被忽略:查表的顺序。多数规则是“取最高番”,但有些九江本地牌桌允许特定组合累加。是先匹配再比较,还是边匹配边累计,结果可能不同。这点最好在表旁边写清注释,否则过几个月自己都看不懂。
别把“标准答案”想得太死
九江麻将的玩法差异,本质上是牌桌约定差异,很难说哪套算法才是正解。
做工具时更务实的做法是:算法层保持可配置,规则数据外置,查表结构预留扩展位。至于具体某张桌子怎么算,多问一句、多留一个开关,比硬编码靠谱。