review: code review + 3 critical fixes + 文档更新

Code Review 发现 (docs/code-review.md):
  🔴 InferType 三元两边相同(无意义) → 重写,加 LianDui/FeiJi 分支
  🔴 PdkBotView { get; init; } → { get; set; } (.NET 4.8 兼容)
  🔴 PdkBot.DecideBaoZhuang ≤10永远false → bigCards≥6

文档更新 (docs/pdk-bot.md):
  + 5. 牌型全覆盖表(引擎+Bot枚举覆盖10种牌型)
  + 6. 双环境兼容指南(net48/n10 差异+集成步骤)
  + 附牌策略说明(引擎允许任意牌做挂件)
This commit is contained in:
2026-07-07 14:39:50 +08:00
parent 54d9f3add3
commit ce2a4c98ef
10 changed files with 97 additions and 13 deletions

24
docs/code-review.md Normal file
View File

@ -0,0 +1,24 @@
# PdkBot Code Review
## 发现汇总
### 🔴 Critical
| # | 文件 | 行 | 问题 | 影响 |
|---|------|-----|------|------|
| 1 | IsmctsBot.cs | 421 | `InferType` 三元表达式两边相同 `... ? SanDai2 : SanDai2` | 无实际分支 |
| 2 | IsmctsBot.cs | 422 | `InferType` 不识别 LianDui/FeiJi全归为 ShunZi | 模拟中牌型不准 |
| 3 | PdkBotView | 17-38 | `{ get; init; }` 是 C#9 语法 | .NET 4.8 不兼容 |
### 🟡 Warning
| # | 文件 | 行 | 问题 | 影响 |
|---|------|-----|------|------|
| 4 | IsmctsBot.cs | 54-133, 215-307 | `SimulateWin``SimulateOneGame` 80% 重复 | 维护成本高 |
| 5 | IsmctsBot.cs | 173 | `unknownCount` 参数传入 SimulateOneGame 但从未使用 | 死参数 |
| 6 | PdkBot.cs | 62 | `DecideBaoZhuang``MyHand.Length <= 10`16张永远false | 包庄永远不触发 |
| 7 | IsmctsBot.cs | 363 | `GetMultiGroups(hand,2)` 被调两次 | 微性能浪费 |
### 🟢 OK
- `GenerateDeck()` 每次模拟调用 — 可缓存但 8000 次 × 52 元素 = 可接受
- `Pass()` 方法在两处重复 — 设计选择(两个 bot 独立)
- 三带二附带牌策略 — 已验证引擎允许任意牌做挂件
- `PickBestTip` null safety — tips 非空已外层保证

View File

@ -206,7 +206,55 @@ C 路径的技术可行性已验证DouZero 在斗地主上击败所有 344
---
## 5. 运行
## 5. 牌型全覆盖
引擎 `GetOutCard` 已验证支持所有牌型bot `AddMultiCardLeads` + `InferType` 实现完整枚举:
| 牌型 | 引擎 | Bot 先手 | Bot 跟牌 | 说明 |
|------|------|---------|---------|------|
| 单张 DanZhang | ✅ | ✅ GetTipCard | ✅ GetTipCard | |
| 对子 DuiZi | ✅ | ✅ GetMultiGroups(2) | ✅ GetTipCard | |
| 顺子 ShunZi | ✅ | ✅ PokerLogic.GetShunZi | ✅ GetTipCard | ≥5 张连续 |
| 连对 LianDui | ✅ | ✅ GetConsecutiveRuns | ✅ GetTipCard | ≥3 对连续 |
| 三带二 SanDai2 | ✅ | ✅ 三张+最小2张 | ✅ GetTipCard | 附牌不限对子 |
| 四带二 SiDai2 | ✅ | ✅ 炸弹+最小2张 | — | 关牌规则 |
| 四带三 SiDai3 | ✅ | ✅ 炸弹+最小3张 | — | 关牌规则 |
| 炸弹 ZhaDan | ✅ | ✅ GetPlayZhaDans | ✅ GetTipCard | 4 张相同 |
| 飞机 FeiJi | ✅ | ✅ GetConsecutiveRuns | ✅ GetTipCard | ≥2 组连续三张 |
| 飞机带对 FeijiDai2 | ✅ | ✅ 飞机+附对子 | ✅ GetTipCard | |
### 附牌策略
引擎 `IsSanDaiEr` / `IsSiDai2` / `IsSiDai3` 均不要求附牌为对子——允许任意单牌挂件。Bot 取手牌最小剩余牌做附牌,最大化清牌效率。
---
## 6. 双环境兼容(.NET 4.8 / .NET 10
### 6.1 已处理
| 特性 | .NET 4.8 | .NET 10 | 方案 |
|------|----------|---------|------|
| C#8 switch expression | ❌ | ✅ | 改为 ternary |
| C#9 `{ get; init; }` | ❌ | ✅ | 改为 `{ get; set; }` |
| ValueTuple | ⚠️ NuGet | ✅ | net48 加 `System.ValueTuple` 包 |
| LINQ | ✅ | ✅ | 无需改动 |
| string 插值 `$"..."` | ✅ C#6 | ✅ | 无需改动 |
| `?.` / `??` | ✅ C#6 | ✅ | 无需改动 |
### 6.2 net48 项目集成步骤
1. 复制 `PdkBot.cs` + `IsmctsBot.cs``PdkFriendServer/Logic/`
2. `PdkFriendServer.csproj` 加:
```xml
<PackageReference Include="System.ValueTuple" Version="4.5.0" />
<LangVersion>8.0</LangVersion>
```
3. `PdkGameMain.cs` 的 `WaitWanJiaShuRu()` 加入 BotMode 分支(与 net10.0 逻辑完全相同)
---
## 7. 运行
```bash
cd ~/projects/hjha-server