# 双升(两副牌升级 / 拖拉机 / 80分)玩法规则汇总 > 本文是给 CodeBuddy(及后续实现双升游戏 `packages/engine/src/games/double-up.ts`)的玩法依据。 > 来源:QQ游戏"升级"规则说明、百度百科"升级/拖拉机"词条、知乎升级(拖拉机)规则说明。 > 所有 **【已拍板】** 标记的规则为用户在 2026-08-27 确认的选型,实现时以此为准。 --- ## 0. 一句话定义 四人两两结对,用**两副含大小王的扑克牌(108张)**,通过"亮主定花色(无人亮则翻牌兜底)→ 庄家扣底 → 轮流出牌捡分(5/10/K)→ 抠底翻番"的流程,按闲家得分决定庄家队伍是否升级,先打到 A 的一方获胜。 --- ## 1. 牌具与发牌 - 牌数:**108 张**(两副 × 54 张,含大小王)。【已拍板 V1:含大小王】 - 人数:4 人,**固定 4 人**(双升不支持其他人数),对家为一队(南北 vs 东西)。 - 分牌分值:**5 = 5 分**,**10 = 10 分**,**K = 10 分**。两副牌总分 = 200 分。 ### 1.1 发牌流程(逐张发 + 实时排序 + 可亮主) 发牌是一个**独立阶段(deal)**,与出牌严格分离。流程: 1. 洗牌后,**一张一张**发给 4 家(按座位顺序轮转)。每发出一张,收到牌的玩家手牌**立即按「花色分组(主牌在前、副牌按 ♠>♥>♦>♣)、同花色点数从大到小」重排**(由 `sortHand` 保证,玩家无需手动整理)。 2. 发到 **100 张**时停止(每人 25 张),**剩余 8 张作为底牌,不再发给任何人**。 3. 发牌过程中(deal 阶段内任意时刻)任何玩家可**亮主**(见 §3)。亮出的牌**从手牌移到该玩家座位前的「亮主公开区」**(桌上所有人可见),被更高优先级反主时**自动归还其手牌**。 4. 发牌结束(满 100 张、剩 8 张底牌)**自动定主**:按亮主公开区里「当前最大优先级」的亮主记录定主花色+庄家(无人亮则**翻底牌第一张兜底**,见 §3 V3),亮主区牌归还各自主人,庄家收底,直接进入 **bottom 阶段**。**不再有独立的「确认主花色」按钮/阶段**(Request B)。 5. 主花色确认后进入 **bottom 阶段**:**庄家把 8 张底牌全部收入自己手牌**(临时 33 张),按主花色在前、副花色在后重新排序,再**挑 8 张扣出作为新底牌**。这 8 张扣底牌**只有庄家可见,其他人不可见**(结算抠底时才公开)。 6. 扣底完成后进入 play 阶段开始出牌。 > 工程实现注(v2026-08-27 重构):发牌改为**真正的一张一张发**——房主端 UI 通过 `dealOne` move 以 ~150ms 间隔自动驱动(`DoubleUpBoard` 内 `useEffect` 监听 `phase==='deal' && me==='0'`),发满 100 张(`dealIndex>=100`)自动调用 `resolveTrump` 定主并转 `bottom`。亮主为**公开亮主区**(`revealed[pid]`):`declareTrump` 把牌从手牌移入该区(所有人可见),更高优先级反主时先把被反者亮主区的牌**归还其手牌**再落新亮主;`resolveTrump`(发满 100 张自动触发,或旧 `confirmTrump` move 兜底)把所有亮主区牌归还各自主人、确定主花色/庄家、庄家收底。`playerView` 对所有人隐藏 `deck`(未发的整副牌)与 `bottom`(非庄家),但 `revealed` 公开。 > 阶段机:`waiting`(进房)→ `deal`(一张一张发+可亮主,发满自动定主)→ `bottom`(庄家收底+扣 8 张隐藏)→ `play`(出牌)→ `score`(结算)。`trump` 阶段已合并进 `deal` 末尾自动处理。 --- ## 2. 级牌 / 主牌 / 副牌 - **级数**:双方从 **2 级**起步;庄家队伍的当前级别 = 本局级牌点数。序列:2,3,4,5,6,7,8,9,10,J,Q,K,A。打到 A 且获胜即整场获胜。 - **级牌**:点数等于当前级数的一切牌(四种花色都有),无论是否主花色皆为主牌。 - **主牌**:大小王(无花色,恒为主)+ 级牌(四花色皆主)+ **主花色**所有牌(亮主决定)。 - **副牌**:除主牌之外其余三花色的牌。 - **2 是否常主**:【已拍板 V2:2 为常主】所有花色的 2 均为主牌,分"主2"(主花色里的2)与"副2"(其他花色的2)。 主牌大小顺序(2为常主,从大→小): ``` 大王 > 小王 > 主级牌 > 副级牌 > 主2 > 副2 > A > K > Q > J > 9 > 8 > 7 > 6 > 5 > 4 > 3 ``` 副牌大小顺序(从大→小,花色间无大小): ``` A > K > Q > J > 9 > 8 > 7 > 6 > 5 > 4 > 3 > 2 ``` > 同级牌"先出者大"(出牌时同点同花色以先落者为大)。 --- ## 3. 亮主 / 反主(确定主花色) **时机**:在 **deal 阶段(发牌过程中)** 即可亮主;亮出的牌从手牌移到该玩家座位前的「亮主公开区」(桌面可见,所有人都能看到),被反主时立即归还其手牌——不在手中、也不在暗处。发牌满 100 张时**自动定主**(亮主区最大优先级胜出,否则翻底牌第一张兜底),无需手动确认。 **抢亮优先级由低到高(V5 四级抢亮,"2 张反 1 张")**: | 等级 | 亮出的牌 | 效果 | | --- | --- | --- | | 1 | 单张级牌 | 定该花色为主 | | 2 | 一对级牌 | 反主(覆盖单张) | | 3 | 一对小王 | 反主(覆盖级牌对,等同"反无主"方向) | | 4 | 一对大王 | 反主(最高,打无主) | - 后亮者用**更高优先级**的牌可**反主**改花色;同优先级不能再反(以先出现者为准)。 - "自保":直接亮对级牌同花色,除反无主外不能被反;"自反":本队再次用更高牌反。 - 一对小王/大王亮出 = **打无主**(无主花色,仅大小王+级牌+2 为主)。 - **庄家认定**:本局庄家 = 最后成功亮主(优先级最高)的玩家。第一局若无人亮主,庄家按轮庄默认值(初始 P0);之后每局按轮庄顺序(§8)依次更替。 - **【已拍板 V3:翻第四张兜底】** 仅当全程**无人亮主**时,发牌满 100 张后从底牌翻一张牌兜底定主: - 翻到普通花色牌 → 该花色为主花色。 - 翻到大小王 → 打无主。 - 翻到级牌 → 该级牌的花色为主花色。 - 有人亮过主(含无主)则**不**翻牌,直接采用已亮主结果。 - 定主由 `resolveTrump` 在发满 100 张时自动完成(旧 `confirmTrump` move 作为手动兜底保留但未在 UI 暴露)。定案后庄家收底牌(§4)。 --- ## 4. 扣底(庄家收底 + 扣 8 张隐藏) - 主花色确认后,进入 bottom 阶段:**庄家先将 8 张底牌全部收入自己手牌**(手牌临时变为 25+8 = **33 张**),按主花色在前、副花色在后重新排序。 - 庄家从这 33 张中**挑 8 张扣出**,作为新底牌(`unshownBottom`)。这 8 张**只有庄家可见**,其他人不可见(不放在明面),直到结算抠底(§6)才公开。 - 庄家扣底后手牌回到 25 张,进入 play 阶段。 - 扣底策略:藏分牌或藏大牌防被抠。 - 底牌分数归属在 §6 抠底时结算。 > 工程实现注:底牌 8 张在 playerView 中对非庄家返回空数组,确保 secrecy;仅庄家 `myHand` 含其完整 33→25 牌。 --- ## 5. 出牌规则 - **首家(首引)**:每局第一轮由**庄家**先出;之后每轮由上一轮赢家先出。 - 首家可出任意牌型:单张、对子、拖拉机(连对)、或"甩牌"。 - **跟牌义务**: - 首家出**单张**:有该花色必须跟单张(无该花色可毙/垫)。 - 首家出**对子**:有对子必须出对子(含拖拉机中的对)。 - 首家出**拖拉机**:有拖拉机必须出拖拉机;无拖拉机则必须出对子;无对子才能出别的。 - 首家出**副牌花色**而某家**无此门花色**:可出**主牌毙**(牌型须匹配:对子用主对、拖拉机用主拖拉机),或出**别的副牌垫**(垫牌永远最小)。 - ⚠️ 若手上有首出花色牌,**不能**直接用主牌毙,必须先跟该花色。 - **毙牌(主牌压副牌)**: - 仅当无首出花色时可出主牌;主牌天然大于副牌。 - 毙牌牌型须 ≥ 首出牌型(拖拉机数、对子数都不能少于首家),否则算垫牌。 - 多家毙牌时比毙牌中拖拉机/对子大小,大者"盖毙"。 - **甩牌规则**: - 甩出的所有牌必须**全大**(同花色无人能压)。 - 甩牌失败(他人有更大的)→ 强制出被压制牌型中的**最小牌**。 - **【已拍板 V4:甩牌失败罚分】** 额外按被压制的牌型张数罚分: - 单张被压:**罚 10 分**。 - 对子被压:**罚 20 分**。 - 拖拉机被压(长度 n):**罚 20 × n 分**。 - 结算方向:**庄家甩牌失败 → 闲家得分**(罚分加给闲家);**闲家甩牌失败 → 闲家扣分**(从闲家总分中扣除)。 - 甩牌失败的具体最小牌型仍须按规则打出(软惩罚 + 罚分并存)。 - 一轮 4 家出齐(或对应牌型张数),最大者赢墩并收走本圈所有分牌。 > **UI 出牌交互(v2026-08-27)**:本人手牌可**自由多选**;`DoubleUpBoard` 实时调用 `parsePlay` + `validateFollow` 解析当前选择并提示牌型(单张/对子/拖拉机/甩牌)与合法性(如"必须跟领出花色")。「出牌」按钮**仅当选择合法时**才点亮。首出可任意牌型;跟牌若持有领出花色/对子/拖拉机则必须匹配,断门才可毙/垫。这样**对子、拖拉机、甩牌均可在 UI 正常打出**(之前缺实时提示导致只能出单张)。 --- ## 6. 拖拉机(连对)定义 - **定义**:同花色、点数**连续**、每点两张(对子)的联牌。必须全主或全副,主副不可混。 - 副牌例:`KKQQ`、`JJ99`、`554433`。 - 主牌例:`一对小王+一对主级牌`、`主级牌对+副级牌对`、`主级牌对+主A对`。 - **级牌相邻可连**:主花色级牌 7 可与红桃 66、红桃 88 连成拖拉机;副级牌 7 与副花色 7 可连(同为主)。 - **王的特殊**:大王+小王 可成对/连(在主牌序相邻)。 - **不算拖拉机**:`554`、`544`、`5533`、`JJQ`、`两对副10`(不相邻)、`JJ1010`、`AA22`(常主时 AA 与 22 间隔 KQJ9…8,不相邻)。 > 连续长度 n:两连对 n=2,三连对 n=3,以此类推。 --- ## 7. 抠底(底牌翻番) - 最后一圈若**闲家方**赢,触发抠底:底牌中的分牌按倍数计入闲家得分。 - **倍数 = 2 的(最后一圈最大牌型张数)次方**。【已拍板 V6:封顶 64 倍】(即 6 张 / 三连对封顶)。 - 单张抠底:2¹ = 2 倍。 - 对子抠底(如 44):2² = 4 倍。 - 两连对(如 4455):2⁴ = 16 倍。 - 三连对(如 444555):2⁶ = 64 倍(封顶)。 - 甩牌抠底:只按甩牌中的**最大牌型**算倍数(如甩 AKQJ109877,按对子 77 算 4 倍;甩 AKQJ 按单张算 2 倍)。 - 最后一圈**庄家方**大 → 不抠底(底牌分归庄家,闲家不得分)。 > 底牌分 = 底牌中 5/10/K 的面值之和 × 倍数,加入闲家总分后参与 §8 升级判定。 --- ## 8. 得分与升级判定 以**闲家(抓分方)本局总得分**计(含捡到的分牌 + 抠底翻番分 + 甩牌罚分加减),总分 200: | 闲家得分 | 结果 | | --- | --- | | 0 | 庄家方连升 **3 级** | | 1 – 39(不满40) | 庄家方升 **2 级** | | 40 – 79 | 庄家方升 **1 级** | | 80 – 119 | 轮换庄家(闲家上台,不升级) | | 120 – 159 | 闲家方升 **1 级** | | 160 – 199 | 闲家方连升 **2 级** | | ≥200(每多40) | 闲家方再加升相应级数 | > 台阶累计逻辑:0/40/80/120/160/200… 各对应 庄+3/庄+2/庄+1/闲+1/闲+2/闲+3…,之后每 40 分再 +1 级。 **轮庄**: - 庄家升级(保庄):下一副由**对家**当庄家。 - 闲家上台:下一副由**本副庄家的下家**当庄家。 **胜负**:某队打到 **A** 且本局获胜(升级过 A 或闲家上台时已达 A)→ 该队整场胜。 > 注:A 级特殊回流(如被用 A 抠底则下局级牌回退到 J)属进阶变体,【待确认,默认不实现】。 --- ## 9. 已拍板的规则选型汇总 | # | 项目 | 选型 | | --- | --- | --- | | V1 | 是否含大小王 | 含(108张) | | V2 | 2 是否常主 | 是(主2/副2) | | V3 | 无人亮牌兜底 | 翻第四张兜底(有人亮则不打翻牌);翻到王=无主,翻到花色/级牌=该花色主 | | V4 | 甩牌失败惩罚 | 罚分(单张10/对子20/拖拉机20×n);庄家失败闲家得、闲家失败闲家扣 | | V6 | 抠底倍数上限 | 64 倍封顶 | 未拍板项(实现时采用主流默认,后续可调整): - V5 亮主机制:四级抢亮(单级牌<对级牌<对小王<对大王)+ 自保/自反。 - V7 级牌起始:从 2 级起步。 - A 级回流变体:默认不实现。 - 翻牌兜底翻到"级牌"时是否允许再反主:默认不允许(翻牌为最终兜底,等同于定主)。 --- ## 10. 与现有代码库的对接要点(实现提示,非规则) - 新游戏文件:`packages/engine/src/games/double-up.ts`,导出 `TTSGame`,`name: 'DoubleUp'`,`engineName: 'DoubleUp'`,`minPlayers/maxPlayers: 4`,`setup` 发 108 张牌(含大小王),留 8 张底。 - `game.ui`:需声明主/副牌区、4 家手牌区、底牌区、已出牌区、当前级牌/主花色指示。因 4 人 + 拖拉机复杂度高,建议先实现**逻辑引擎**(moves:亮主/翻牌兜底/扣底/出牌/跟牌校验/收分/甩牌罚分/抠底/升级判定),UI 可先用 `game.ui.actions` + 简化 Board,或仿 `HoldemBoard` 写专用 `DoubleUpBoard`。 - 必实现的核心校验(出牌合法性):跟牌花色义务、对子/拖拉机跟牌、毙牌牌型匹配、甩牌全大判定 + 罚分、主副大小比较、抠底倍数(封顶64)。 - 需注册到 `packages/server/src/index.ts` 的两个数组(`Server({games})` 与 `GAMES_ENTRIES`),及 `apps/web/src/App.tsx` 的 `GAMES` 表(maxSeats=4)。 - 建议配套:在 `packages/engine/src/games/double-up.test.ts` 写单元测试覆盖亮主/反主、跟牌校验、拖拉机判定、抠底倍数、升级判定表、甩牌罚分。 --- ## 11. 参考来源 - QQ游戏"升级"规则说明(minigameimg.qq.com/help/rule36.html) - 百度百科:升级/拖拉机(baike.baidu.com/item/升级/3563150) - 知乎:升级(拖拉机)规则(zhuanlan.zhihu.com/p/2035707530240844260,甩牌罚分精确算法来源) - 知乎:升级(拖拉机)游戏基本游戏规则(zhuanlan.zhihu.com/p/101357920) - 知乎:四人升级(80分/拖拉机/双升)游戏规则说明(zhuanlan.zhihu.com/p/1900479633754948317)