墨局 · 麻将
墨局 · 麻将:一人对三家电脑的国潮水墨麻将,杭州 / 成都 / 血战到底三种打法,牌面是 AI 贴图再由代码合成。

玩法
一桌四人:你坐庄或闲,另外三家是电脑。三种打法在开场屏直接选:
| | 杭州麻将 | 成都麻将 | 血战到底 | |---|---|---|---| | 牌数 | 136(含东南西北中发白) | 108(仅万条筒) | 108 | | 财神 | 白板为财神,可当任意牌 | 无 | 无 | | 定缺 | 不需要 | 必须定缺 | 必须定缺 | | 胡牌限制 | 无番不可胡 | 有番型即可 | 有番型即可 | | 胡牌之后 | 本局结束 | 本局结束 | 不下桌,可继续连胡 | | 结束条件 | 一人胡牌即结束 | 一人胡牌即结束 | 牌墙摸尽 | | 一炮多响 | 否 | 否 | 是 |
分数按 底分 × 2^(番数−1),番数封顶 10 番。自摸由其他在桌的人各付,点炮由放炮者付。跨局连续胡牌有连番(每连一次 +1,上限 +3),庄家胡牌连庄同样加番。
不吃牌是刻意的:杭州、成都、血战三种玩法的通行规则都不允许吃,与其做一个玩家用不上的按钮,不如把操作列留给胡 / 槓 / 碰 / 过。
怎么打
点牌选中(那一张会浮起来),再点一次打出。摸到的牌单独摆在手牌最右侧一个独立槽位里,所以理好的那一摞不会因为摸牌而整体左右跳;那一格摆的一定是本巡摸进来的那张——打别的牌它就收进整排重新理齐,打它自己则整排一张不动。
胡 / 槓 / 碰 / 过贴在屏幕右缘,窄竖屏自动换成手牌下方的横排,任何形态都不压自己的牌、也不挡右侧对手的牌。顶栏「番数」打开的浮层按当前玩法列出全部番型,每一条都带可读的牌型图示(单吊用虚线空牌表示)。
手柄 / 键盘:左右方向键或左摇杆在手牌与右侧按钮之间走一格(光标那一张会浮起并描一圈冷白细框,与「可以碰的牌」的描金框是两件事),A / Enter 确认——第一次选中、再按一次打出,X / Backspace 取消选中,Start 暂停。开始屏、结算屏、排行榜、番数表、暂停面板由站点共用壳子接管,手柄可以直接逛。
榜单口径是单局净胜分:一局结算后,在结算屏打开排行榜、填昵称、点「提交成绩」才会上榜,同一局只记一次;开下一局会自动清掉上一局的快照。指标带胡牌次数、玩法、本局最高番。
实现
- 逻辑与表现彻底分开:
src/core/(牌定义、胡牌判定含癞子、番型计算、可序列化的对局状态机、AI)不引用任何 DOM 或 PixiJS,能在 Node 里原样跑;src/ui/只认「同形对象」,换成联机快照渲染不用改场景代码。 - 牌面不是字体画的,是 AI 生成的写实贴图:原图压到工作尺寸后以 data URI 嵌进
src/ui/art.gen.js,运行时按牌宽二分求解版式再 multiply 合成,小于 40px 自动换 small 档(图案放大一档 + 垫柔暗边)。所以条 / 筒 / 万的点数与花色由代码决定,素材只负责材质。 - 字体自托管:
fonts/下 8 个字面是从上游完整 TTF 裁出的子集(460 个字符,合计 719 KB),带 sha256 清单。改了文案必须回开发机重出子集,否则npm run check:fonts会红——线上新增文案缺字变成豆腐块,是肉眼最难发现的回归。 - 三种玩法共用一套番型表与结算流程,血战的「胡牌不下桌」靠状态机里的
continueAfterWin开关,而不是另写一局。
