perf: FastSim rollout 支持对子 (DuiZi) — 模拟更真实
FastSim改进: - 新轮次: 优先找最大对子 → 再出最大单张 - 跟牌: 对子跟牌→找≥2张同rank且大于对手 - 单张跟牌: 找最小可压牌 效果: 多牌29%, ShunZi 8.8%, DuiZi 19.0%, 0.8s/局 已知局限: 贪婪rollout低估清牌效率, 后续需全局序列优化
This commit is contained in:
@ -190,7 +190,7 @@ namespace PdkFriendServer.Logic
|
||||
return FastSim(o1g, o2g, mg, current, myGameNum, CardType1.DanZhang, myPos - 1, 0);
|
||||
}
|
||||
|
||||
// 快速模拟核心:全部用 byte[]
|
||||
// 快速模拟核心:全部用 byte[]。支持单张+对子。
|
||||
private bool FastSim(List<byte> h1, List<byte> h2, List<byte> my,
|
||||
int current, byte maxGameNum, CardType1 maxType, int maxPlayer, int depth)
|
||||
{
|
||||
@ -202,10 +202,19 @@ namespace PdkFriendServer.Logic
|
||||
var cur = current == 0 ? h1 : current == 1 ? h2 : my;
|
||||
bool isNewRound = maxPlayer == current || maxGameNum == 0;
|
||||
|
||||
// 贪心:找最大可出牌
|
||||
if (isNewRound)
|
||||
{
|
||||
if (cur.Count == 0) return false;
|
||||
// 找对子(贪心:出最大的对子)
|
||||
var groups = cur.GroupBy(g => g).Where(g => g.Count() >= 2).OrderByDescending(g => g.Key).ToList();
|
||||
if (groups.Count > 0)
|
||||
{
|
||||
var pair = groups[0];
|
||||
var toRemove = pair.Take(2).ToList();
|
||||
foreach (var g in toRemove) cur.Remove(g);
|
||||
return FastSim(h1, h2, my, (current + 1) % 3, pair.Key, CardType1.DuiZi, current, depth + 1);
|
||||
}
|
||||
// 单张
|
||||
var sorted = cur.OrderByDescending(g => g).ToList();
|
||||
byte play = sorted[0];
|
||||
cur.Remove(play);
|
||||
@ -213,8 +222,20 @@ namespace PdkFriendServer.Logic
|
||||
}
|
||||
else
|
||||
{
|
||||
// 找能压制的最大牌
|
||||
// 跟牌:找能压制的同类型牌
|
||||
var bigger = cur.Where(g => g > maxGameNum).OrderBy(g => g).ToList();
|
||||
if (maxType == CardType1.DuiZi)
|
||||
{
|
||||
// 对子:找 ≥2 张且大于 maxGameNum
|
||||
var pairGroups = cur.GroupBy(g => g).Where(g => g.Count() >= 2 && g.Key > maxGameNum).OrderBy(g => g.Key).ToList();
|
||||
if (pairGroups.Count > 0)
|
||||
{
|
||||
var pair = pairGroups[0];
|
||||
var toRemove = pair.Take(2).ToList();
|
||||
foreach (var g in toRemove) cur.Remove(g);
|
||||
return FastSim(h1, h2, my, (current + 1) % 3, pair.Key, CardType1.DuiZi, current, depth + 1);
|
||||
}
|
||||
}
|
||||
if (bigger.Count > 0)
|
||||
{
|
||||
byte play = bigger[0];
|
||||
|
||||
Reference in New Issue
Block a user