- 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 通过
3.6 KiB
3.6 KiB
立直麻将(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 会破坏其他客户端同步)。
四、实施顺序(每步附验证)
- P1 牌与宝牌:
mahjong-tiles.ts+ 测试(牌组张数、赤 5、宝牌指示循环、三麻去牌)。 - P2 和牌与役:
mahjong-yaku.ts+ 测试(和牌分解、全部役种表、双倍役满、宝牌加算)。 - P3 符与点数:符计算 + 点数表 + 测试(对拍 §9.3 表、满贯封顶、切上满贯不采用、亲/子/自摸/荣和、本场)。
- P4 听牌/振听/食替:听牌判定、舍张/同巡/立直后振听、现物+筋食替校验 + 测试。
- P5 Game 骨架:阶段机 + 配牌/摸打/立直/鸣牌/和了/流局 moves + playerView + 本局/终局结算 + 测试(用 boardgame.io 的
Client/Game.T驱动)。 - P6 UI:
apps/web/src/MahjongBoard.tsx(参照BridgeBoard.tsx重设计为立式麻将桌)。 - P7 接入:注册 server 两数组 +
App.tsx(GAMES/GAME_ORDER/GameKey/Local/Online View)。 - P8 验证:
pnpm -r ts && pnpm --filter @tts-like/engine test,必要时补 E2E。
五、风险与注意
- 役种与符计算是最大复杂度来源:先写穷尽单测对拍标准表,再写 Game 逻辑。
- 三麻自摸损、拔北、北客风等需在点数与役判定中分支处理。
- 鸣牌并发在 boardgame.io 下单线程,需用状态窗口 + 超时模拟;避免多客户端抢发同一 move。
- 隐藏信息严格走
playerView,UI 不得二次实现。