Files
huajishe-tts/docs/texas/05-betting-order.md
e2hang 04d0af515c feat: 登录系统落地 + 踢人修正 + 单房间约束 + 权限收口
问题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>
2026-08-25 14:13:59 +08:00

68 lines
4.9 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.
# 问题 5打牌顺序标准德州扑克行动顺序调查
> 用户原话:“打牌顺序好像有点问题……现在的逻辑每次都从庄家的下一位开始,但是标准德州扑克是这样的吗?”
## 标准德州扑克的行动顺序(权威规则)
### 翻牌前preflop
- 小盲SB在大盲BB**左边**第一个座位,大盲在 SB 左边。
- **第一个行动者 = 大盲左边的玩家UTGUnder 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 后重置并顺时针推进)。
用户感知到的“每次都从庄家的下一位开始”可能来自以下混淆之一:
1. **单挑时庄家先行动preflop** 被误以为“从庄家下一位开始”——其实单挑就是庄家SB先动标准如此。
2. **postflop 从 SB庄家下一位开始** 被当成“所有街都从庄家下一位”——但 preflop 是从 UTG庄家下两位两街起点不同代码已区分属正确。
3. 可能真实存在的 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 者下家继续、且其他人被重新要求行动。
- 若测试发现 `endTurn({next})` 未被采纳currentPlayer 回到错误座位),则问题在 boardgame.io 的
`ActivePlayers.ALL` + `turn.order` 交互,需改用 `events.setActivePlayers` 或显式 `endTurn` 序列。
## 拟采用方案
1. 先写 **顺序验证测试**(不改逻辑),确认当前行为。
2. 若测试通过与标准一致 → **无需改顺序逻辑**,仅在文档/UI 上澄清(例如在行动条显示“(庄家左 X 位行动)”),
并在 `HoldemBoard` 高亮当前行动者(已有 `data-actor`)。
3. 若测试暴露异常 → 定位 `advance`/`turn.order` 问题并修复(届时更新本文件结论)。
> 一句话答复用户:**标准德州扑克不是“每次都从庄家下一位”**——翻牌前从大盲下一位(UTG),翻牌后从小盲(庄家下一位)
> 当前代码已按此实现,但我会用测试再次核实并保留证据。