问题8 登录系统: - node:sqlite 账号存储(scrypt 哈希 + HMAC 签名 token),preset admin 改为 e2hang/evan1115 - /api/auth/register|login|me,me 返回 room 供重联 - 网关拦截 create/join 需登录(401),列表保持开放 踢人逻辑修正(问题2 延伸): - kickMove 真正释放座位(folded=false, name=null)而非锁死 - war/mill 去掉永久封禁语义 管理员越权:管理员 token 可删任意房间、踢任意房间内的人 单房间约束(用户新需求): - 同一用户同时只能在一个房间,create/join 他房返回 409 - 踢人后若房间仅剩踢人者则自动解散并释放其记录(修复 2 人局踢光对手后被困 409) - 陈旧房间记录兜底清理 UI 清理:移除"改名"按钮与"你的名字"输入框;删除房间按钮仅房主/管理员可见 docs: 新增 12-auth-kick-single-room.md 汇总本会话全部需求/根因/修复/边界测试 Co-Authored-By: Claude (CodeBuddy) <noreply@codebuddy.ai>
4.9 KiB
4.9 KiB
问题 5:打牌顺序(标准德州扑克行动顺序调查)
用户原话:“打牌顺序好像有点问题……现在的逻辑每次都从庄家的下一位开始,但是标准德州扑克是这样的吗?”
标准德州扑克的行动顺序(权威规则)
翻牌前(preflop)
- 小盲(SB)在大盲(BB)左边第一个座位,大盲在 SB 左边。
- 第一个行动者 = 大盲左边的玩家(UTG,Under The Gun),即顺时针从庄家(按钮)数:庄家 → SB → BB → UTG 先行动。
- 行动顺时针进行:UTG → … → SB → BB。
- 大盲有“BB option”:若无人加注,轮到大盲时他可以选择过牌(看注)或加注。
翻牌后(flop / turn / river)
- 第一个行动者 = 小盲(按钮左边第一个仍在手的玩家)。
- 行动顺时针:SB → … → 庄家(按钮)。
- 即:翻牌后由庄家左边第一个玩家先行动(与翻牌前不同,翻牌前是 BB 左边)。
每次有人加注(raise)之后
- 加注会重置所有其他玩家的“已行动”标记(他们必须再次面对这个加注做决定)。
- 行动从加注者顺时针的下一位开始,逐一回到加注者之前那一位;
所有人都对当前最高注
call/raise/fold且下注额一致、且都“已行动”后,该街才结束。 - 若某人 all-in 且金额不足以构成完整加注(incomplete raise),则不重置已行动者的标记
(已行动且面对未匹配注的人只能 call 或 fold,不能再加注)—— 本项目已实现此规则(
holdem.ts:438)。
单挑(heads-up)特例
- 只有两人时:庄家 = 小盲,大盲是另一人。
- 翻牌前:庄家(SB)先行动。
- 翻牌后:大盲先行动(因为大盲是“庄家左边第一个”)。
现有代码核对(holdem.ts)
| 街 | 代码 firstToAct |
是否标准 | 结论 |
|---|---|---|---|
| preflop 多人 | nextSeat(bbPid, canAct) = BB 顺时针下一位 = UTG |
✅ 标准 | 正确 |
| preflop 单挑 | sbPid(= 庄家)先行动 |
✅ 标准(单挑庄家先) | 正确 |
| flop/turn/river 多人 | nextSeat(dealerButton, canAct) = 庄家顺时针第一人 = SB |
✅ 标准 | 正确 |
| flop/turn/river 单挑 | nextSeat(dealerButton, canAct) = 大盲 |
✅ 标准(单挑大盲先) | 正确 |
每次 raise 后的顺序
raiseMove:完整加注时for pid: G.acted[pid] = false(holdem.ts:443),即重置其他人的已行动标记 → ✅ 标准。advance()→nextActor(G, ctx)=nextSeat(ctx.currentPlayer, canAct)(holdem.ts:230): 从当前行动者(加注者)顺时针下一位继续 → ✅ 标准。roundComplete要求全部acted && betThisRound === currentBet→ ✅ 标准(不完整加注不重置已行动者也已处理)。
调查结论
现有代码的行动顺序实际上符合标准德州扑克规则(preflop=UTG、postflop=SB、raise 后重置并顺时针推进)。 用户感知到的“每次都从庄家的下一位开始”可能来自以下混淆之一:
- 单挑时庄家先行动(preflop) 被误以为“从庄家下一位开始”——其实单挑就是庄家(SB)先动,标准如此。
- postflop 从 SB(庄家下一位)开始 被当成“所有街都从庄家下一位”——但 preflop 是从 UTG(庄家下两位),两街起点不同,代码已区分,属正确。
- 可能真实存在的 bug 不在“首行动者”,而在
advance的流转(例如events.endTurn({next})在ActivePlayers.ALL下是否被 boardgame.io 正确采纳)。
仍需落实的验证(防误判)
- 加一个确定性集成测试,打印每一街的 currentPlayer 序列,人工核对:
- 3 人:preflop 顺序应为
UTG(0) → SB(1) → BB(2) →(BB option)→ flop 起SB(1) → ...。 - 在某玩家中途 raise 后,确认顺序从 raise 者下家继续、且其他人被重新要求行动。
- 3 人:preflop 顺序应为
- 若测试发现
endTurn({next})未被采纳(currentPlayer 回到错误座位),则问题在 boardgame.io 的ActivePlayers.ALL+turn.order交互,需改用events.setActivePlayers或显式endTurn序列。
拟采用方案
- 先写 顺序验证测试(不改逻辑),确认当前行为。
- 若测试通过与标准一致 → 无需改顺序逻辑,仅在文档/UI 上澄清(例如在行动条显示“(庄家左 X 位行动)”),
并在
HoldemBoard高亮当前行动者(已有data-actor)。 - 若测试暴露异常 → 定位
advance/turn.order问题并修复(届时更新本文件结论)。
一句话答复用户:标准德州扑克不是“每次都从庄家下一位”——翻牌前从大盲下一位(UTG),翻牌后从小盲(庄家下一位); 当前代码已按此实现,但我会用测试再次核实并保留证据。