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

52 lines
3.6 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 立直麻将(Mahjong)实现计划
> 规则依据:[`00-rules.md`](./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 不得二次实现。