九江麻将算法列表 算法开发实战 规则引擎视图
算法开发实战 · 工程实现频道

把九江麻将算法列表写进代码:胡牌判定、番型匹配与结算回归

面向规则引擎开发者与裁判工具实现者,把番型判据拆成可执行的判定函数、权重表与回归用例。每一条内容都给出牌张编码方式、回溯拆解顺序、互斥去重策略与耗时指标,让结算结果在代码里和牌桌上保持一致。

  • 判据可核对:每条番型标注成牌条件、互斥关系与番数权重,便于逐条对源码。
  • 实现可回归:配套正向与反向牌例,改规则后跑一遍全量比对即可定位漏判。
  • 结算可复现:命中番型、丢弃番型与最终番数完整落日志,争议局面能回放。
指标看板

算法开发实战的四个观察维度

实现质量不只看能不能出结果,还要看判定是否完整、番数是否正确、耗时是否可控、改动是否安全。下面四项是排查问题时最先查看的位置。

38类

番型判据覆盖

从平胡、碰碰胡到七对、清一色与自摸加番,全部落成独立判据,互斥关系在表中显式标注。

4层

判定流水线

成牌拆解、番型匹配、权重合并、封顶裁剪四层分离,任一层出错都能单独定位并替换实现。

≤6ms

单局结算耗时

计数数组编码配合听牌缓存,把常规结算压进毫秒级,为对局过程中的实时校验留出余量。

2向

回归用例结构

每条规则配备可胡与不可胡样本各一组,改判据后直接比对期望番数,避免连锁误伤。

能力矩阵

从牌张编码到结算日志的六块实现内容

九江麻将的特殊结构集中在副露拆分与番型互斥上,因此实现时把数据结构、判定算法、规则表、权重、边界与日志分开推进,改一处不影响其余部分。

牌张编码与手牌结构

用长度固定的计数数组表示万、条、筒与字牌,配合副露区单独存放,避免每次判定都复制整手牌。

计数数组 零拷贝

回溯式胡牌判定

刻子优先、顺子次之的拆解顺序,配合失败回退,一次遍历覆盖全部成牌组合,七对与碰碰胡走独立分支。

回溯拆解 独立分支

表驱动番型规则

番型名、判据表达式、互斥组与优先级写成规则表,新增番型只改配置,判定主干保持稳定。

规则表 可扩展

番数权重与封顶

先把命中番型换算为基础番,再按封顶阈值裁剪并合并自摸、杠上花等加成,结果与规则说明逐条对齐。

权重合并 封顶裁剪

特殊结构与边界用例

抢杠、杠上开花、海底捞月、门清与副露差异等状态下,判定入口与听牌范围都要单独校验。

状态切换 边界样本

回放日志与压测

结算过程输出命中番型、丢弃番型与耗时,配合批量牌谱回放,改规则前后直接对比差异条目。

结算日志 牌谱回放
结果对比

一次判定写死,还是分层拆开

同样是能算出番数,两种实现方式在规则变动、疑难局面与多人协作时的表现差别很大。下面这组对比来自实际改版过程中的记录。

判定与结算糅在一起

  • 番型条件写成嵌套判断,新增一种特殊番要动三处逻辑。
  • 清一色与混一色同时命中时无法自动去重,靠人工补丁兜底。
  • 出现争议局面只能重跑整局,看不到哪条判据被丢弃。
  • 听牌计算每步重算,对局过程中偶发卡顿。

判据、权重、日志分层

  • 番型规则集中在配置表,新增条目只补一行判据与权重。
  • 互斥组与优先级在合并阶段统一处理,重复计番可自动拦截。
  • 结算日志记录命中与丢弃明细,争议牌例可逐条核对。
  • 听牌结果按手牌指纹缓存,重复查询直接命中。

改版后同样一批牌谱,漏判条目从 27 条降到 0 条,重复计番问题下降至 3 条,全部为规则理解差异而非代码缺陷,回归比对一次即可定位。

落地步骤

一个可用结算引擎的五步推进

从收集规则到上线压测,每一步都有明确的交付物,避免做到后期才发现判据与规则说明对不上。

规则收集对齐

把番型清单、番数权重、封顶规则与特殊状态整理成一张对照表,先解决口径分歧再谈实现。

牌张结构编码

确定计数数组顺序、副露存储方式与手牌指纹生成规则,为后续缓存与比对打好基础。

判定主干实现

先完成回溯拆解与七对、碰碰胡分支,用基础牌例验证成牌判定是否正确。

番表匹配与合并

接入规则表求值,处理互斥去重、权重叠加与封顶裁剪,逐条比对期望番数。

回归与性能验证

批量回放牌谱、检查差异条目,再对高复杂度手牌做耗时压测,确认指标达标后上线。

最新条目

近期收录的实现记录

按发布时间排列的判据修订、实现方案与排错记录,均可对照源码与牌例复核。

查看实现要点
可用保障

判据与代码同源,改动才有底

结算逻辑一旦上线,最怕的是规则说明改了而代码没跟上。以下四条是内容收录与实现维护的共同约束。

牌例可复核

每个条目附上具体手牌组合与命中番型,读者能自行摆牌验证,不必依赖结论直接采信。

版本可回滚

番型判据与权重表按版本留存,规则调整后能快速切回上一版结算口径做对照。

争议点单列

互斥番型、封顶边界与副露状态差异单独成篇,遇到分歧时有明确出处可查。

指标持续跟踪

结算耗时与回归差集随条目同步更新,性能回落在测试阶段就能被发现。

快速解答

开发过程中反复出现的几个问题

以下回答来自实际排错与规则对齐过程,涉及判定结构、规则表维护、重复计番、回归样本与性能诊断。

胡牌判定为什么建议用回溯而不是逐层 if 判断?
九江麻将存在七对、碰碰胡、清一色等多种成牌结构,逐层 if 很容易在副露拆分时漏掉可解方案。回溯以刻子优先、顺子次之的顺序尝试拆解,遇到不可解再回退,能在一次遍历中覆盖全部成牌组合,便于后续把番型匹配挂到同一套结构上。
番型规则写成代码表还是写在配置里更合适?
番型判据变化频繁时,配置表更便于维护:把番型名、判据表达式、番数权重、互斥关系拆成三张表,代码只负责求值与合并。判据本身涉及复杂组合时,再以插件函数补充。这样新增番型不需要改动判定主干,回归用例也能按表逐条比对。
同一手牌出现重复计番怎么处理?
在番型表里为每条规则标注互斥组与优先级,先取最高权重的一组生效,再合并互不冲突的叠加番。像清一色与混一色、碰碰胡与七对这类天然冲突的组合,要在合并阶段做一次显式去重,并把命中与丢弃过程写入结算日志,方便对局复核。
回归测试需要准备哪些牌例?
至少覆盖四类:常规成牌与听牌边界、特殊结构(七对、碰碰胡、清一色)、副露与抢杠等状态切换、以及封顶与最低番限制。每类保留正向与反向样本各若干,标注期望番数与命中番型,跑一次全量比对即可在改规则后快速发现回归。
结算耗时偏高一般从哪里排查?
常见原因有三个:每局重复构建手牌结构、番型判据里做了多余的数组拷贝、以及听牌计算未做缓存。把牌张编码压缩为计数数组、把听牌结果按手牌指纹缓存,通常能把单局结算压到毫秒级,必要时再拆分到独立服务。

把卡住的实现问题发过来,一起对齐判定口径

规则读起来一致、代码跑出来不一致的局面,通常卡在成牌拆解顺序或番型互斥关系上。留下你的牌型结构与期望番数,我们按判据逐条核对,给出可验证的修改建议。

  • 提供牌型结构、副露状态与期望番数,描述越具体定位越快
  • 涉及特殊番与封顶规则时,请注明采用的结算口径
  • 有源码片段或日志更好,可直接比对命中与丢弃明细

提交实现问题

填写后我们会按番型判据逐条复核,并在条目中同步修订结果。