Files
huajishe-tts/docs/heart/00-research.md
e2hang a4fd9ea8fa feat(pig): 拱猪完整实现(3/4 人)+ 修复联机手牌渲染
- engine: Pig 游戏(发牌/跟牌/赢墩/结算:猪羊变压器全红大满贯),每人均分独立 13 张手牌
- engine: playerView 为每个请求者注入各自 myHand,他家手牌剥除
- web: PigBoard UI(椭圆桌+环形座位+计分板),修复 realG 提取——myHand 在 board 回调顶层而非 .G 内,此前只房主看到牌
- web/test: 15 个单测;Playwright 4 人验证每人 13 张、共 52 张、互不重叠
- app/lobby/server: 拱猪进房间列表、座位选择 [3,4]、engineName GongZhu
2026-08-25 16:57:52 +08:00

13 KiB
Raw Permalink Blame History

拱猪Gong Zhu / Pig游戏调研报告

本文档为「在 tts-like 模拟器中实现拱猪」前的规则调研。 拱猪是中国流行的扑克游戏,由国外 "Black Lady / 黑桃皇后"(即 Windows 自带「红心大战」Hearts 的玩法)传入后本土化发展而来。 用户要求:可 3 人玩,也可 4 人玩,规则与红心大战很像。 以下内容综合百度百科、各游戏平台规则页、玩家社区资料整理,并标注了 3 人局的可行变体方案。


一、游戏定位与关系

  • 拱猪 ≈ 红心大战Hearts的中国变体。共同内核:
    • 4 人、一副 52 张(无大小王)、每人 13 张。
    • 目标都是躲分(红心为负分), tricks 中吃到的分牌累计。
    • 跟牌必须跟同花色(无该花色可垫任意牌)。
  • 与红心大战的关键差异
    维度 红心大战 (Hearts) 拱猪 (Gong Zhu)
    换牌pass 3 每局开局互相传 3 张 无换牌,改为**亮牌(卖牌)**环节
    负分牌 仅 13 张红心 红心 + 黑桃 Q-100
    正分牌 方块 J+100
    特殊牌 梅花 10变压器加倍
    亮牌加倍 有(见下)
    首出限制 不能吃第一墩红心(除非手中只有红心) 多数变体无首出花色限制,领出可任意花色
    全收红心 全红 = 所有红心变正分(倒扣) 全红 = +200亮牌则 +400

二、标准规则4 人,一副牌)

2.1 牌组与发牌

  • 用去掉大小王后的 52 张牌4 人平分,每人 13 张
  • 点数大小递减A > K > Q > J > 10 > 9 > 8 > 7 > 6 > 5 > 4 > 3 > 2。
  • 首局庄家随机;之后一般由上一局吃到黑桃 Q的玩家坐庄。

2.2 分牌与分值(亮牌前的基础分)

16 张特殊牌15 张计分页 + 1 张功能牌(变压器)。

别称 基础分
♥A -50
♥K -40
♥Q -30
♥J -20
♥10 / ♥9 / ♥8 / ♥7 / ♥6 / ♥5 -10
♥4 / ♥3 / ♥2 0(不计入负分,但属于"红心",影响全红判定)
♠Q -100(游戏名"拱猪"的由来)
♦J +100
♣10 变压器 / 导板(double) 见 2.4

红心合计基础分 = -(50+40+30+20+6×10) = -200 分。 变体:部分规则把 ♥4 也记 -10、♥3/♥2 记 -3/-2使所有红心相加恰好 -200也有把 ♥2/3/4 都记 0 的简化版(如上表,推荐采用此简化版以贴合主流线上平台)。

2.3 亮牌(卖牌)机制

开局由庄家开始,每人可自愿亮出手中持有的以下牌之一或多张:

  • ♥A 亮出:所有红心牌分值 ×2(亮牌后红心合计 -400
  • ♠Q 亮出(卖猪):猪变为 -200
  • ♦J 亮出(卖羊):羊变为 +200
  • ♣10 亮出:变压器由"×2"变为"×4"(见 2.4)。

亮牌限制(主流规则):亮过的牌,在该花色第一次被领出时不能出,除非手中该花色只剩这一张。

首抓加倍(天亮/地亮):若发牌时抓到的第一张即可亮且当场亮出,效果再 ×2即 ♣10 亮牌=×4再首抓=×8其余亮牌×2 再首抓=×4。这是高阶变体初版实现可先不做。

2.4 变压器♣10的特殊作用

  • 若玩家吃到 ♣10、没吃到任何其他分牌 → 变压器单独计 +50 分
  • 若同时吃到其他分牌 → 变压器发生加倍作用:该玩家本副牌所有分(含正负、含亮牌翻倍后的结果)整体 ×2
  • 配合亮牌♣10 亮出后加倍倍数从 ×2 提升到 ×4(若再首抓则 ×8

2.5 出牌流程

  1. 亮牌阶段:庄家起,每人决定是否亮牌(可亮多张)。
  2. 首出:由特定牌的持有者首出(见 2.6)。之后每轮由上一轮赢得 tricks 最大牌者领出。
  3. 跟牌:轮到出牌时,若手中有领出花色的牌,必须跟该花色;若无,可垫任意其他花色(垫牌不赢墩)。
  4. 赢墩:一轮中打出领出花色里点数最大者,赢得该轮所有分牌。
  5. 直到 52 张全部出完,该局结束,进入结算。

2.6 首出牌规则(变体较多)

  • 主流线上平台:庄家首出,可出任意花色任意牌(无"红心未破不能领红心"限制)。
  • 常见指定首牌:持有 ♣2 者首出 ♣2JJ 比赛变体:由分数最低者首出且不必 ♣2。也有用 ♠2 / ♠3 作首牌的变体。
  • 亮牌约束:亮过的牌在对应花色第一次被领出时不可出(除非该花色仅此一张)。

2.7 结算(单副牌得分)

计算顺序(重要,避免歧义):

  1. 先按各分牌基础分累加得 S(亮牌已使相应牌的基础分翻倍)。
  2. 若吃到 ♣10 且还有其他分牌 → S = S × 2(亮 ♣10 则 ×4 / 首抓 ×8
  3. 吃到 ♣10 → 该玩家得 +50

全红(收齐全部 13 张红心):所有红心由同一家吃齐 → 红心全部变正分,合计 +200(亮 ♥A 则 +400。注意全红只翻转红心不影响猪/羊/变压器本来的正负。

大满贯(猪羊满圈):一家吃齐全部 16 张分牌(所有红心 + 猪 + 羊 + 变压器)→ 猪也变正分,总分 = (200 红心正分 + 100 羊 + 100 变压器翻倍基数) ×2 = +800;若所有可亮牌均被亮过则 ×4 = +3200

2.8 多局累计与胜负

  • 各局得分累加为累计分。拱猪是负分越少越好(红心大战同)。
  • 常见结束条件:某人累计达到 +1000 或 -1000 判胜负;或约定固定局数后比低分。
  • 奖励/惩罚(娱乐向,非规则必需):用鼻子拱出黑桃 Q、贴纸条、刮鼻子等。

三、3 人变体方案(用户明确要求支持)

标准 52 张牌 / 4 人 / 13 张是铁律;3 人时如何分配牌没有统一标准规则,需自行约定。调研到的可行方案如下,供实现时选定(建议初版采用方案 A

方案 A去牌法推荐最贴近 4 人逻辑)

  • 去掉 1 张非分牌(通常为 ♦2 或任意一张低价值非分牌),剩 51 张3 人每人 17 张
  • 所有分牌(猪/羊/变压器/红心)原样保留,分值不变。
  • 首出规则同 4 人(庄家或指定牌首出)。
  • 优点:规则 100% 复用 4 人逻辑,仅发牌数变化;分牌体系不变,玩家认知成本低。
  • 缺点:每人 17 张略多于 13但 tricks 数自然为 17 墩,无影响。

方案 B完整 52 张 / 轮空(发牌留底)

  • 仍用 52 张,每家 17 张 + 留 1 张底牌(或不发,每轮某人轮空)。
  • 复杂度高,不推荐

方案 C去多张法某些民间 3 人玩法)

  • 去掉 ♠2、♣2 等若干低牌,使 52 - k 能被 3 整除(如去 4 张 → 48 张 / 16 每人为常见)。
  • 需确保关键分牌♠Q/♦J/♣10/♥A不被误删

3 人局的额外设计决策(需与用户确认或默认)

  1. 首出指定牌3 人时仍可用 ♣2 持有者首出;若 ♣2 被去掉(方案 C改由庄家首出上局猪主首出
  2. 全红判定:红心共 13 张3 人时仍可能由一人吃齐,规则同 4 人(+200 / 亮 +400
  3. 大满贯判定16 张分牌由一人吃齐,规则同 4 人。

结论3 人支持的最佳实现路径是参数化发牌张数 + 可选去牌列表,分牌分值表与亮牌/变压器/全红/满贯逻辑完全共用 4 人代码。


四、与本项目已有 Holdem 实现的对照(架构提示)

  • Holdem 用 boardgame.io 的 Game({ setup, moves, phases, playerView }),拱猪可同样建模:
    • setup: 洗牌发牌(按人数 3/4 决定去牌与每人张数)。
    • 阶段expose(亮牌)→ play(出牌 13/17 墩)→ score(结算)。
    • moves: expose(card)(亮牌)、playCard(card)(跟/领牌,带跟牌校验)、pass(无合法牌时无需,拱猪无 pass
    • 状态: G.hands[pid]G.currentTrickG.leadSuitG.taken[pid](各家吃到的牌,用于结算)、G.exposed(已亮牌集合)、G.scores[pid](累计)。
    • 结算: 一局结束 onEndplay 末墩后计算单局分写入 G.scores,并提供"下一局"。
  • 与 Holdem 不同:拱猪是合作躲分 + 个人计分,无公共筹码池、无下注阶段;playerView 仍可隐藏他家手牌,但 tricks 公开可见符合真实玩法。

五、已确认的设计决策用户拍板2026-08-25

  1. 3 人去牌方案(已澄清)3 人局去掉 ♣21 张非分牌),保留 ♣3,剩 51 张3 人每人 17 张51 ÷ 3 = 17整除无矛盾
    • 即 4 人 = 52 张 / 13 每人3 人 = 51 张 / 17 每人(去 ♣2
  2. 首出牌规则(已澄清)
    • 第一局4 人局 = 持有 ♣2 者首出 ♣23 人局 = 持有 ♣3 者首出 ♣3(因 ♣2 已去掉,改用保留的 ♣3 作首牌)。
    • 第二局起:按出牌顺序(逆时针),由上一局首出者的下一位玩家首出,且不再强制特定牌(可出任意牌)。首出权随局轮转。
  3. 亮牌功能不做。所有分牌按基础分计算,无翻倍/卖牌机制。变压器 ♣10 仅保留"单独 +50 / 同吃其他分牌则 ×2"的基础规则(不含亮牌加成)。
  4. 红心 2/3/4 分值:确认均为 0 分(主流简化版),全红仍须集齐全部 13 张红心。
  5. 结束条件无结束条件。对局连续进行,每局结束自动进入下一局,累计分持续累加,玩家自行决定是否继续。
  6. 单房间人数:创建房间时由房主选择 3 人或 4 人(类似 Holdem 的 numPlayers 选项)。

新增需求 — 计分板(榜)

  • 需要一个计分板 UI类似排行榜Leaderboard
  • 4 人局:对家为队友(南-北一组、东-西一组),计分板需体现组队关系——既显示每人单局分/总分,也显示两队总分(两组各自成员分数相加)。
  • 3 人局:各自为战,计分板显示每人单局分 + 累计总分,无组队。
  • 计分板内容:
    • 每位玩家:本局得分累计总分4 人时)所属队伍
    • 每局结束后刷新本局分;总分跨局累加。
    • 视觉上做成"榜"——按总分排序(低分在前,因拱猪分越低越好),高亮当前玩家。

六、实现规划提示(供 EnterPlanMode 参考)

6.1 引擎 packages/engine/src/games/pig.ts

  • setup({ numPlayers }):洗 52 张牌4 人每人 13 张;3 人去掉 ♣2 后 51 张,每人 17 张
  • 阶段:lead(首出权决定)→ play出牌N 墩)→ score(结算单局)。
  • movesplayCard(card)(校验跟牌/领出)、nextRound()(进入下一局,重洗重发)。
  • 状态:G.hands[pid]G.currentTrickG.leadSuitG.leadPlayerG.taken[pid]: Card[]G.scores[pid](累计)、G.lastRoundScores[pid](本局)、G.round(局数)、G.teams4 人时固定对家分组)。
  • 结算函数 scoreRound(G):按第五节分值表算每家单局分 → 写入 lastRoundScores 并累加 scores
  • 首出权:G.firstLeader 首局 = ♣2 持有者4 人)/ 庄家3 人);之后 = 上局首出者下家。
  • playerView隐藏他家手牌tricks 公开。

6.2 UI apps/web/src/PigBoard.tsx + 计分板

  • 椭圆桌 + N 座位环形分布(复用 HoldemBoard 的 seatPos 思路)。
  • 中央显示当前 trick 与领出花色;手牌区可点击出牌。
  • <Scoreboard> 组件表格式榜4 人显示队伍列 + 每人行按总分升序3 人仅个人列。每局结束弹出/常驻展示本局分与总分。

6.3 接入

  • App.tsxGAMES 增加 pig(名"拱猪"),加入 GAME_ORDER(位置待定,建议放在 mill 之后)。
  • 创建房间时 numPlayers 仅允许 3 或 4maxSeats=4setupOptions 提供人数选择,或复用 Holdem 的座位选择 UI 改为 3/4

七、资料来源

  • 百度百科「拱猪」词条
  • 维基百科wikidpedia「拱猪」条目含完整分值、亮牌、全红、大满贯、规则差异
  • 腾讯游戏 / QQ 游戏 拱猪规则帮助页
  • 远航游戏中心、边锋、联众等平台拱猪规则说明
  • 萌娘百科「红心大战(拱猪变体)」条目
  • 百度贴吧 / 百度文库 玩家经验贴

注:拱猪民间变体极多,本报告以"主流线上平台 + 维基百科标准规则"为准3 人局采用上文方案 A 作为推荐默认。