From 13fe07ea1132fe73624feb9d16bba8210dd12a23 Mon Sep 17 00:00:00 2001 From: xiaoou Date: Tue, 7 Jul 2026 14:56:43 +0800 Subject: [PATCH] =?UTF-8?q?chore:=20=E6=B8=85=E7=90=86=E5=86=97=E4=BD=99?= =?UTF-8?q?=20+=20=E6=96=87=E6=A1=A3=E6=9B=B4=E6=96=B0=E8=87=B3v3.1=20+=20?= =?UTF-8?q?=E6=89=93=E5=8C=85=E6=B8=85=E5=8D=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 清理: - 删除 C:\Users\... Windows残留路径 - analyze_stress.py → docs/ - .gitignore 覆盖 stress_* runtime产物 文档更新: - pdk-bot.md: 包庄阈值45%→70%、RolloutPolicy描述、选牌策略 - code-review.md: 7/7 全部清零 - PACKAGE.md: 新建打包清单(代码+集成+文档+net48步骤+压测记录) bot 文件总览: 核心: PdkBot.cs(194行) + IsmctsBot.cs(331行) = 525行 文档: pdk-bot.md + code-review.md + stress-test-report.md + PACKAGE.md --- docs/PACKAGE.md | 49 +++++++++++++++++++++++++++++++++++++++++++++ docs/code-review.md | 34 +++++++++++++------------------ docs/pdk-bot.md | 13 +++++++++--- 3 files changed, 73 insertions(+), 23 deletions(-) create mode 100644 docs/PACKAGE.md diff --git a/docs/PACKAGE.md b/docs/PACKAGE.md new file mode 100644 index 00000000..767e00f5 --- /dev/null +++ b/docs/PACKAGE.md @@ -0,0 +1,49 @@ +# PdkBot 打包清单 + +## 核心代码(2 文件,525 行) + +``` +PdkFriendServer/Logic/PdkBot.cs IPdkBot 接口 + PdkBotView + 启发式基线 +PdkFriendServer/Logic/IsmctsBot.cs ISMCTS 蒙特卡洛搜索(默认,推荐) +``` + +## 引擎集成点(已有修改,无需额外文件) + +``` +PdkFriendServer/Logic/PdkGameMain.cs BotMode 开关、BuildBotView、WaitWanJiaShuRu +hjha-console/Program.cs main.BotMode = true 入口 + --stress N 模式 +``` + +## 文档 + +``` +docs/pdk-bot.md 架构、算法、引擎整合、双兼容、压测报告 +docs/code-review.md 7 项 review 发现 + 修复记录(已清零) +docs/stress-test-report.md 1000 局首次压测分析 +docs/analyze_stress.py 压测日志分析脚本 +``` + +## .NET 4.8 集成步骤 + +1. 复制 `PdkBot.cs` + `IsmctsBot.cs` → `PdkFriendServer/Logic/` +2. `PdkFriendServer.csproj` 加: + ```xml + + 8.0 + ``` +3. `PdkGameMain.cs` 中复制 `BotMode`/`_bots`/`BuildBotView`/`InitBots` 成员和 `WaitWanJiaShuRu` 的 bot 分支 + +## 当前默认配置 + +- Bot: IsmctsBot (800 sims) +- 包庄阈值: 70%(成功率 57%) +- 多牌加权: +10%/张 +- 牌型覆盖: 10 种(全) + +## 压测记录 + +| 版本 | 局数 | 单张 | 多牌 | 包庄成功率 | 提交 | +|------|------|------|------|-----------|------| +| v1 (启发式) | 1000 | 100% | 0% | 5.2% | - | +| v3.0 (ISMCTS) | 100 | 47% | 53% | 30% | 750e364 | +| v3.1 (阈值70%) | 100 | 44% | 56% | 57% | aa30bfa | diff --git a/docs/code-review.md b/docs/code-review.md index 9dcf83dc..a71316fb 100644 --- a/docs/code-review.md +++ b/docs/code-review.md @@ -1,24 +1,18 @@ # PdkBot Code Review -## 发现汇总 +**状态: ✅ 全部清零(7/7)** -### 🔴 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 不兼容 | +| # | 文件 | 问题 | 状态 | 修复 | +|---|------|------|------|------| +| 1 | IsmctsBot.cs:421 | `InferType` 三元表达式两边相同 | ✅ | 重写,加 LianDui/FeiJi 分支 | +| 2 | IsmctsBot.cs:422 | `InferType` 不识别 LianDui/FeiJi | ✅ | ShunZi/LianDui/FeiJi 各自分支 | +| 3 | PdkBotView:17 | `{ get; init; }` C#9→.NET 4.8 不兼容 | ✅ | → `{ get; set; }` | +| 4 | IsmctsBot.cs | `SimulateWin`/`SimulateOneGame` 80% 重复 | ✅ | 合并为 `SimulateToEnd(firstPlay?)` | +| 5 | IsmctsBot.cs:173 | `unknownCount` 死参数 | ✅ | 移除 | +| 6 | PdkBot.cs:62 | `DecideBaoZhuang` 用 `≤10`(永远false) | ✅ | → 大牌计数 ≥6 | +| 7 | IsmctsBot.cs:363 | `GetMultiGroups(hand,2)` 调两次 | ✅ | `pairs` 变量复用 | -### 🟡 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 非空已外层保证 +**代码规模:** +- IsmctsBot.cs: 331 行(原始 583 行,-43%) +- PdkBot.cs: 194 行 +- 总计: 525 行 diff --git a/docs/pdk-bot.md b/docs/pdk-bot.md index a69e64ec..9a4f6932 100644 --- a/docs/pdk-bot.md +++ b/docs/pdk-bot.md @@ -114,17 +114,24 @@ DecidePlay(view): return 胜率最高的方案 ``` -**RolloutPolicy(模拟策略)**:用 `GetTipCard` 取第一个方案(最小牌),快速推进对局。不需要最优——大量采样后统计收敛。 +**RolloutPolicy(模拟策略)**:用 `PickBestTip` 选最优方案(优先多牌组合 + 最大牌),模拟更强的对手行为。大量采样后 ISMCTS 胜率统计收敛。 #### 包庄决策 ``` DecideBaoZhuang(view): 模拟 600 局完整对局 → 统计我第一个出完的概率 P(win) - P(win) ≥ 45% → 包庄 + P(win) ≥ 70% → 包庄 ``` -**为什么 45% 而不是 50%?** 包庄是零和博弈中的多方决策。你不包但别人包了,你也要扣双倍。阈值略微向攻方倾斜以弥补防守的机会成本。 +**阈值校准历程:** 45%(v1)→ 60%(v2,成功率 30%)→ **70%(v3.1,成功率 57%)**。100 局压测验证:70% 阈值下包庄成功率翻倍。 + +#### 选牌策略 + +两阶段选择: +1. ISMCTS 评估所有候选胜率 +2. 多牌组合 +10%/张加权 → 优先出对子/顺子/三带二等 +3. 多牌 ≥ 单张 → 无条件优先多牌 #### 性能