feat: LockDetector — 残局锁手必胜序列检测

LockDetector.cs (新文件, 170行):
- BFS搜索: 手牌≤8张时寻找无人能压制的出牌序列
- 硬锁: 每步绝对无人可挡→跳过ISMCTS,直接走必胜路径
- 支持5种牌型: 炸弹/对子/三张/三带二/顺子/单张
- 利用CardTracker.CanAnyoneBeat()判断压制可能性
- 优先大牌型(炸弹>顺子>三带二>对子>单张)

IsmctsBot集成:
- DecidePlay开头: hand≤8→调用LockDetector
- 发现锁手→跳过ISMCTS模拟,直接出牌(Console打LOG)
- Type=CardType1.None交给引擎GetOutCard重新算

生效条件: 残局+CardTracker累积足够已知牌信息+手牌有压制力
This commit is contained in:
2026-07-12 22:40:49 +08:00
parent e67b06caa3
commit cb33dcac6c
2 changed files with 187 additions and 1 deletions

View File

@ -82,7 +82,26 @@ namespace PdkFriendServer.Logic
{
_tracker.Update(view);
var hand = view.MyHand;
if (hand.Length == 0) return Pass(view);
if (hand.Length == 0) return Pass(view);
// 锁手检测:残局时跳过 ISMCTS走必胜序列
if (hand.Length <= 8)
{
var lockSeq = LockDetector.FindLockSequence(hand, _tracker, view.MyPos);
if (lockSeq != null)
{
var firstPlay = lockSeq[0];
Console.WriteLine($"[ISMCTS pos{view.MyPos}] LOCK {lockSeq.Count}步必胜 → 跳过模拟");
// 通过引擎的出牌验证
return new PlayOutCardPdkF
{
Pos = (byte)view.MyPos,
GameNum = firstPlay.GameNum,
Ids = firstPlay.Ids,
Type = CardType1.None
};
}
}
bool isFirstPlay = view.MaxPlayCard.GameNum <= 0;