Files
huajishe-tts/docs/mahjong/01-implementation-plan.md
e2hang 8d5fb3c511 feat(mahjong): 立直麻将(四麻/三麻,半庄战,雀魂规则)
- engine/tiles: 34 种牌、四麻 136/三麻 108(去 2m~8m)、赤 5(3/2 枚)、宝牌指示映射、排序与计数
- engine/yaku: 和牌分解(标准/七对/国士)+ 全役种(含双倍役满、累计役满)+ 符计算 + 番符→点数(满贯封顶、不采用切上满贯、三麻自摸损)+ 听牌/振听/食替
- engine/game: boardgame.io Game(阶段机 + 摸打/立直/鸣牌/和了/流局 moves + 鸣牌窗口“荣>碰/杠>吃/头跳” + playerView 隐藏 + 连庄/进庄/击飞/西入/半庄终局)
- ui: 新增 MahjongBoard(立式麻将桌:手牌/牌河/副露/宝牌/剩余张数/点数/鸣牌倒计时)
- 注册: server 两数组 + App.tsx GAMES/GAME_ORDER/GameKey/本地+联机 View(maxSeats=4, seatChoices=[3,4])
- docs: docs/mahjong/{00-rules,01-implementation-plan}.md + dev-log 15;CODEBUDDY.md 游戏清单更新
- 测试: mahjong-tiles/yaku/game 共 59 条;engine 全量 310 通过;web tsc+vite build、server tsc 通过
2026-10-03 12:43:51 +08:00

3.6 KiB
Raw Permalink Blame History

立直麻将(Mahjong)实现计划

规则依据:00-rules.md(雀魂标准,四麻 + 三麻,半庄战)。 目标文件与集成点见 00-rules §14。本文只描述工程拆分与实施顺序。


一、模块拆分(均放 packages/engine/src/games/)

文件 职责 是否纯函数
mahjong-tiles.ts 牌定义、牌组生成(四麻/三麻)、赤宝牌、排序、宝牌指示映射、索引/牌种互转 ✅
mahjong-yaku.ts 和牌型分解(标准型/七对/国士)、役种判定、番数、符计算、点数计算、振听/听牌判定辅助 ✅
mahjong.ts boardgame.io Game 定义:阶段机、moves、playerView、本局/终局结算、连庄/进庄 ❌(含状态机)

对应测试:mahjong-tiles.test.ts、mahjong-yaku.test.ts、mahjong.test.ts。

二、牌与状态数据模型

  • 牌种索引(34 种):0-8 = 1m..9m,9-17 = 1p..9p,18-26 = 1s..9s,27-33 = 東南西北白發中。
  • 物理牌:{ id: string; kind: string; red?: boolean },其中 kind 用 '1m'..'9m'/'1p'../'1s'../'1z'..'7z';赤 5 用 '0m'/'0p'/'0s' 表示,normalizeKind 归一到 '5m'/'5p'/'5s' 参与牌型判定。
  • G 关键字段:players/hands/deck/wall/deadWall、melds[pid]、discards[pid]、scores[pid]、riichi[pid]、doraIndicators、honba、kyoutaku(供托)、bakaze(场风)、dealer、round、phase 相关标记、pendingClaims(鸣牌/荣和响应)、turn、lastDiscard、furiten 标记等。

三、阶段机与主循环

waiting ──startGame──▶ playing ──(和了/流局)──▶ roundEnd ──nextRound──▶ playing ...
                                        └──(半庄终局)──▶ gameEnd
  • playing 内部用 turnStep 区分:draw(摸牌)→ discard(打牌)→ claim(鸣牌响应窗口)。
  • 鸣牌响应:逆时针依次询问有资格者(吃/碰/杠/荣/拔北),pass 或超时继续;优先级 荣和 > 碰/杠 > 吃。
  • 发牌必须一次性原子完成(踩坑记忆:单客户端 flood move 会破坏其他客户端同步)。

四、实施顺序(每步附验证)

  1. P1 牌与宝牌:mahjong-tiles.ts + 测试(牌组张数、赤 5、宝牌指示循环、三麻去牌)。
  2. P2 和牌与役:mahjong-yaku.ts + 测试(和牌分解、全部役种表、双倍役满、宝牌加算)。
  3. P3 符与点数:符计算 + 点数表 + 测试(对拍 §9.3 表、满贯封顶、切上满贯不采用、亲/子/自摸/荣和、本场)。
  4. P4 听牌/振听/食替:听牌判定、舍张/同巡/立直后振听、现物+筋食替校验 + 测试。
  5. P5 Game 骨架:阶段机 + 配牌/摸打/立直/鸣牌/和了/流局 moves + playerView + 本局/终局结算 + 测试(用 boardgame.io 的 Client/Game.T 驱动)。
  6. P6 UI:apps/web/src/MahjongBoard.tsx(参照 BridgeBoard.tsx 重设计为立式麻将桌)。
  7. P7 接入:注册 server 两数组 + App.tsx(GAMES/GAME_ORDER/GameKey/Local/Online View)。
  8. P8 验证:pnpm -r ts && pnpm --filter @tts-like/engine test,必要时补 E2E。

五、风险与注意

  • 役种与符计算是最大复杂度来源:先写穷尽单测对拍标准表,再写 Game 逻辑。
  • 三麻自摸损、拔北、北客风等需在点数与役判定中分支处理。
  • 鸣牌并发在 boardgame.io 下单线程,需用状态窗口 + 超时模拟;避免多客户端抢发同一 move。
  • 隐藏信息严格走 playerView,UI 不得二次实现。