feat: AddMultiCardLeads 补全 — 连对/飞机/飞机带对
新增枚举: - 连对(LianDui): 提取对子 → 排序 → 找≥3连续段(如334455) - 飞机(FeiJi): 提取三张 → 排序 → 找≥2连续段(如333444) - 飞机带对(FeijiDai2): 连续三张 + 每组附带1对子 辅助方法: SortByGameNum/AddConsecutiveGroups/GetConsecutiveRuns 10局验证: LianDui 5次出现 完整牌型: DanZhang 76 | DuiZi 37 | ShunZi 17 | SanDai2 7 | LianDui 5 | SiDai3 1 (飞机需≥2连续三张,16张牌罕见但逻辑已就位)
This commit is contained in:
@ -359,6 +359,33 @@ namespace PdkFriendServer.Logic
|
||||
// else: 炸弹已在上面处理
|
||||
}
|
||||
|
||||
// 连对(≥3对连续, 如 334455)
|
||||
var pairs = GetMultiGroups(hand, 2);
|
||||
SortByGameNum(pairs);
|
||||
AddConsecutiveGroups(pairs, 3, pos, candidates, ref multiCount);
|
||||
|
||||
// 飞机(≥2组连续三张, 如 333444)
|
||||
SortByGameNum(triples);
|
||||
AddConsecutiveGroups(triples, 2, pos, candidates, ref multiCount);
|
||||
|
||||
// 飞机带对: 连续三张 + 每组附带一个对子
|
||||
var tripleConsecRuns = GetConsecutiveRuns(triples, 2);
|
||||
foreach (var run in tripleConsecRuns)
|
||||
{
|
||||
var runCards = run.SelectMany(t => t).ToList();
|
||||
int pairCount = run.Count; // 需要这么多对子
|
||||
// 找不重叠的对子
|
||||
var remainingPairs = GetMultiGroups(
|
||||
hand.Where(c => !runCards.Any(r => r.ID == c.ID)).ToArray(), 2);
|
||||
if (remainingPairs.Count >= pairCount)
|
||||
{
|
||||
SortByGameNum(remainingPairs);
|
||||
var attached = remainingPairs.Take(pairCount).SelectMany(p => p).ToList();
|
||||
runCards.AddRange(attached);
|
||||
AddCandidate(runCards, pos, candidates, ref multiCount);
|
||||
}
|
||||
}
|
||||
|
||||
// 顺子(≥5 张连续)
|
||||
var straights = PokerLogic.GetShunZi(hand);
|
||||
if (straights != null)
|
||||
@ -391,6 +418,56 @@ namespace PdkFriendServer.Logic
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>按 GameNum 排序多牌组列表</summary>
|
||||
private static void SortByGameNum(List<List<TCardInfoPdkF>> groups)
|
||||
{
|
||||
groups.Sort((a, b) => a[0].GameNum.CompareTo(b[0].GameNum));
|
||||
}
|
||||
|
||||
/// <summary>找出所有连续段(≥minLen),每段生成一个候选</summary>
|
||||
private static void AddConsecutiveGroups(List<List<TCardInfoPdkF>> groups, int minLen,
|
||||
int pos, List<(PlayOutCardPdkF play, bool isMulti)> candidates, ref int multiCount)
|
||||
{
|
||||
var runs = GetConsecutiveRuns(groups, minLen);
|
||||
foreach (var run in runs)
|
||||
{
|
||||
var cards = run.SelectMany(g => g).ToList();
|
||||
AddCandidate(cards, pos, candidates, ref multiCount);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>从已排序的组中提取所有连续段(≥minLen 组)</summary>
|
||||
private static List<List<List<TCardInfoPdkF>>> GetConsecutiveRuns(
|
||||
List<List<TCardInfoPdkF>> groups, int minLen)
|
||||
{
|
||||
var runs = new List<List<List<TCardInfoPdkF>>>();
|
||||
if (groups.Count < minLen) return runs;
|
||||
|
||||
var current = new List<List<TCardInfoPdkF>> { groups[0] };
|
||||
int prevNum = groups[0][0].GameNum;
|
||||
|
||||
for (int i = 1; i < groups.Count; i++)
|
||||
{
|
||||
int curNum = groups[i][0].GameNum;
|
||||
if (curNum == prevNum + 1)
|
||||
{
|
||||
current.Add(groups[i]);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (current.Count >= minLen)
|
||||
runs.Add(new List<List<TCardInfoPdkF>>(current));
|
||||
current.Clear();
|
||||
current.Add(groups[i]);
|
||||
}
|
||||
prevNum = curNum;
|
||||
}
|
||||
if (current.Count >= minLen)
|
||||
runs.Add(current);
|
||||
|
||||
return runs;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 从合法方案中选最优:优先出多张牌的组合,其次出最大的
|
||||
/// P2修复: 之前只取 tips[0](最小单张),改为优先多牌组合
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Reference in New Issue
Block a user