diff --git a/PdkFriendServer/Logic/CardTracker.cs b/PdkFriendServer/Logic/CardTracker.cs
index dbca7c6e..4948fd79 100644
--- a/PdkFriendServer/Logic/CardTracker.cs
+++ b/PdkFriendServer/Logic/CardTracker.cs
@@ -242,6 +242,63 @@ namespace PdkFriendServer.Logic
return false;
}
+ ///
+ /// 确定性手牌强度:基于绝对牌计数评估手牌实力,0.0-1.0。
+ /// 核心思想:我的手牌 + 已见牌 = 对手的牌池完全确定,
+ /// 可以精确计算哪些 rank 已被我控制、哪些出牌无敌。
+ /// 用于修正 ISMCTS 模拟噪声。
+ ///
+ public double AbsoluteHandStrength(TCardInfoPdkF[] myHand)
+ {
+ if (myHand.Length == 0) return 1.0;
+
+ double score = 0.0;
+
+ // 1. Rank 绝对控制率:我持有该 rank 所有剩余牌的百分比
+ int controlledRanks = 0;
+ int[] ranks = { 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 16 };
+ foreach (int r in ranks)
+ {
+ int remaining = RemainingCount(r, myHand);
+ int myCount = myHand.Count(c => c.GameState == 1 && c.GameNum == r);
+ if (remaining == 0 && myCount > 0)
+ {
+ // 我持有该 rank 所有剩余牌 → 绝对控制
+ controlledRanks++;
+ if (myCount >= 3) controlledRanks++; // 三张以上价值更高
+ }
+ }
+ score += controlledRanks * 0.04; // 每个控制 rank +4%
+
+ // 2. 绝对最高牌:持有 ♠2 或所有2
+ int myTwos = myHand.Count(c => c.GameState == 1 && c.GameNum == 16);
+ int remainingTwos = RemainingCount(16, myHand);
+ if (remainingTwos == 0 && myTwos > 0)
+ {
+ score += myTwos * 0.06; // 每张独占 2 +6%
+ }
+
+ // 3. 持有的炸弹数
+ var byRank = myHand.Where(c => c.GameState == 1)
+ .GroupBy(c => c.GameNum)
+ .Where(g => g.Count() >= 4);
+ int myBombs = byRank.Count();
+ score += myBombs * 0.08; // 每个炸弹 +8%
+
+ // 4. 手牌效率(通过 HandOptimizer 间接)
+ int minPlays = HandOptimizer.MinPlays(myHand);
+ int handSize = myHand.Count(c => c.GameState == 1);
+ double efficiency = (double)(handSize - minPlays)
+ / Math.Max(handSize, 1);
+ score += efficiency * 0.15; // 效率贡献最多 15%
+
+ // 5. 已知牌越多 → 确定性权重越高
+ double seenRatio = _seenCardIds.Count / (double)Math.Max(48 - handSize, 1);
+ score += seenRatio * 0.10; // 已知牌占比 +10%
+
+ return Math.Min(score, 1.0);
+ }
+
/// 在外面可能存在的炸弹数(按 rank 计)
public int BombsOutside(TCardInfoPdkF[] myHand)
{
diff --git a/PdkFriendServer/Logic/IsmctsBot.cs b/PdkFriendServer/Logic/IsmctsBot.cs
index cfb294bd..7042bc5c 100644
--- a/PdkFriendServer/Logic/IsmctsBot.cs
+++ b/PdkFriendServer/Logic/IsmctsBot.cs
@@ -68,6 +68,11 @@ namespace PdkFriendServer.Logic
private double EstimateWinProbability(PdkBotView view)
{
+ // 确定性安全检查:手牌极弱 → 直接否定包庄
+ double detStrength = _tracker.AbsoluteHandStrength(view.MyHand);
+ if (detStrength < 0.15) return 0.0;
+
+ // ISMCTS 模拟(确定性只做否决,不混入加成以避免虚假信心)
int sims = Math.Min(_simulations, 600);
int wins = 0;
for (int s = 0; s < sims; s++)
diff --git a/exe/PdkFriendServer/PdkFriendServer.dll b/exe/PdkFriendServer/PdkFriendServer.dll
index cc3e6ec3..de535739 100644
Binary files a/exe/PdkFriendServer/PdkFriendServer.dll and b/exe/PdkFriendServer/PdkFriendServer.dll differ
diff --git a/exe/PdkFriendServer/PdkFriendServer.pdb b/exe/PdkFriendServer/PdkFriendServer.pdb
index 1daf6035..06491c6c 100644
Binary files a/exe/PdkFriendServer/PdkFriendServer.pdb and b/exe/PdkFriendServer/PdkFriendServer.pdb differ
diff --git a/exe/hjha-console/PdkFriendServer.dll b/exe/hjha-console/PdkFriendServer.dll
index cc3e6ec3..de535739 100644
Binary files a/exe/hjha-console/PdkFriendServer.dll and b/exe/hjha-console/PdkFriendServer.dll differ
diff --git a/exe/hjha-console/PdkFriendServer.pdb b/exe/hjha-console/PdkFriendServer.pdb
index 1daf6035..06491c6c 100644
Binary files a/exe/hjha-console/PdkFriendServer.pdb and b/exe/hjha-console/PdkFriendServer.pdb differ
diff --git a/exe/hjha-console/hjha-console.dll b/exe/hjha-console/hjha-console.dll
index 8b9b480c..b38bea20 100644
Binary files a/exe/hjha-console/hjha-console.dll and b/exe/hjha-console/hjha-console.dll differ
diff --git a/exe/hjha-console/hjha-console.pdb b/exe/hjha-console/hjha-console.pdb
index ce88349c..85b2e1b6 100644
Binary files a/exe/hjha-console/hjha-console.pdb and b/exe/hjha-console/hjha-console.pdb differ