feat: PdkBot — 外挂式自动出牌机器人
架构: - IPdkBot 接口:外挂接入点,与核心逻辑解耦 - PdkBotView:只传自己手牌+公开信息(MaxPlayCard/ShenYuCard/Rule) 不暴露其他玩家手牌——模拟真人视角 - PdkBot:score-based 最优策略 评分维度:直接获胜>>对手威胁>>牌效率>>炸弹保留>>先手权>>黑桃3 对接: - PdkGameMain.BotMode=true 启用 - WaitWanJiaShuRu中BuildBotView→bot.DecidePlay/DecideBaoZhuang - GameBaoZhuang解除WhoPlay=GetNextPos注释以支持逐人轮询 - SetFalseOperation加DeskGameDo null守卫 文件: - PdkFriendServer/Logic/PdkBot.cs(核心机器人) - PdkFriendServer/Logic/PdkGameMain.cs(BotMode+对接) - hjha-console/Program.cs(main.BotMode=true启动)
This commit is contained in:
@ -40,12 +40,47 @@ namespace PdkFriendServer.Logic
|
||||
/// </summary>
|
||||
public PdkGameDo DeskGameDo = null;
|
||||
|
||||
/// <summary>
|
||||
/// 机器人玩家 [pos0,pos1,pos2],null=人工
|
||||
/// </summary>
|
||||
private IPdkBot[] _bots = null;
|
||||
|
||||
/// <summary>
|
||||
/// 启用 Bot 自动对局
|
||||
/// </summary>
|
||||
public bool BotMode { get; set; }
|
||||
|
||||
public PdkGameMain(PdkGameDo _gamedo)
|
||||
{
|
||||
this.DeskGameDo = _gamedo;
|
||||
this.GamePack = new PdkGamePack();
|
||||
}
|
||||
|
||||
/// <summary>懒初始化3个bot(BotMode==true时首次WaitWanJiaShuRu调用)</summary>
|
||||
private void InitBots()
|
||||
{
|
||||
_bots = new IPdkBot[3];
|
||||
for (int i = 0; i < 3; i++)
|
||||
_bots[i] = new PdkBot();
|
||||
}
|
||||
|
||||
/// <summary>构建当前玩家的可见视图——只看自己手牌+公开信息</summary>
|
||||
private PdkBotView BuildBotView(int pos)
|
||||
{
|
||||
return new PdkBotView
|
||||
{
|
||||
MyHand = GamePack.CardPack.Cards[pos - 1].CardInfos
|
||||
.Where(x => x.GameState == 1).ToArray(),
|
||||
MaxPlayCard = GamePack.Info.MaxPlayCard,
|
||||
WhoPlay = pos,
|
||||
MyPos = pos,
|
||||
ShenYuCard = GamePack.Info.ShenYuCard,
|
||||
ZhaDans = GamePack.Info.ZhaDans,
|
||||
Rule = this.Rule,
|
||||
GameZT = GamePack.Info.GameZT
|
||||
};
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 游戏开始
|
||||
/// </summary>
|
||||
@ -241,7 +276,7 @@ namespace PdkFriendServer.Logic
|
||||
{
|
||||
if (GamePack.Info.BaoZhuang[i] == 0)
|
||||
{
|
||||
// GamePack.Info.WhoPlay = GetNextPos(GamePack.Info.WhoPlay);
|
||||
GamePack.Info.WhoPlay = (byte)(i + 1);
|
||||
SendPack();
|
||||
return; //还有玩家没有操作,不处理流程
|
||||
}
|
||||
@ -505,6 +540,7 @@ namespace PdkFriendServer.Logic
|
||||
|
||||
void SetFalseOperation()
|
||||
{
|
||||
if (DeskGameDo == null) return;
|
||||
for (int i = 0; i < GamePack.Info.PlayNum; i++)
|
||||
{
|
||||
this.SetWaitOperation(i, false);
|
||||
@ -611,75 +647,79 @@ namespace PdkFriendServer.Logic
|
||||
void WaitWanJiaShuRu()
|
||||
{
|
||||
if (DeskGameDo != null) return;
|
||||
//正式连客户端以后要屏蔽这些代码。return
|
||||
string str = "";
|
||||
byte num = 0;
|
||||
int pos = GamePack.Info.WhoPlay;
|
||||
switch (GamePack.Info.GameZT)
|
||||
{
|
||||
case 3://包庄流程,只能输入1和2
|
||||
Log("包庄操作 pos:" + GamePack.Info.WhoPlay);
|
||||
case 3://包庄流程
|
||||
{
|
||||
// Bot 接管:懒初始化
|
||||
if (BotMode && _bots == null)
|
||||
InitBots();
|
||||
if (_bots != null && _bots[pos - 1] != null)
|
||||
{
|
||||
var view = BuildBotView(pos);
|
||||
var bao = _bots[pos - 1].DecideBaoZhuang(view);
|
||||
GamePack.Info.BaoZhuang[pos - 1] = bao ? (byte)1 : (byte)2;
|
||||
Log($"bot-包庄: pos{pos}={(bao ? "包" : "不包")}");
|
||||
return;
|
||||
}
|
||||
// 人工输入
|
||||
Log("包庄操作 pos:" + pos);
|
||||
while (true)
|
||||
{
|
||||
str = Console.ReadLine();
|
||||
string str = Console.ReadLine();
|
||||
if (string.IsNullOrWhiteSpace(str)) continue;
|
||||
Log(str);
|
||||
var ss = str.Split(',');
|
||||
if (ss.Length < 2) continue;
|
||||
byte.TryParse(ss[0], out var pos);
|
||||
byte.TryParse(ss[1], out num);
|
||||
GamePack.Info.WhoPlay = pos;
|
||||
GamePack.Info.BaoZhuang[pos - 1] = num;
|
||||
if (CheckPack(GamePack.Info))
|
||||
{
|
||||
break; //如果包输入正确就跳走
|
||||
}
|
||||
else
|
||||
{
|
||||
Log("检测不合格,输入非法值");
|
||||
}
|
||||
byte.TryParse(ss[0], out var ipos);
|
||||
byte.TryParse(ss[1], out byte num);
|
||||
GamePack.Info.WhoPlay = ipos;
|
||||
GamePack.Info.BaoZhuang[ipos - 1] = num;
|
||||
if (CheckPack(GamePack.Info)) break;
|
||||
Log("检测不合格,输入非法值");
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 4: //打牌流程
|
||||
Log("打牌操作 pos:" + GamePack.Info.WhoPlay);
|
||||
{
|
||||
// Bot 接管:懒初始化
|
||||
if (BotMode && _bots == null)
|
||||
InitBots();
|
||||
if (_bots != null && _bots[pos - 1] != null)
|
||||
{
|
||||
var view = BuildBotView(pos);
|
||||
var botPlay = _bots[pos - 1].DecidePlay(view);
|
||||
GamePack.Info.ActivePlayCard = botPlay;
|
||||
return;
|
||||
}
|
||||
// 人工输入
|
||||
Log("打牌操作 pos:" + pos);
|
||||
while (true)
|
||||
{
|
||||
str = Console.ReadLine(); //逗号分隔
|
||||
string str = Console.ReadLine();
|
||||
if (string.IsNullOrWhiteSpace(str)) continue;
|
||||
var ss = str.Split(',');
|
||||
if (ss.Length <= 0) continue;
|
||||
Log(str);
|
||||
var selectCards = GamePack.CardPack.Cards[GamePack.Info.WhoPlay - 1].CardInfos.Where(x => ss.Any(s => s == x.ID.ToString())).ToArray();
|
||||
var selectCards = GamePack.CardPack.Cards[pos - 1].CardInfos
|
||||
.Where(x => ss.Any(s => s == x.ID.ToString())).ToArray();
|
||||
PlayOutCardPdkF payCard;
|
||||
if (selectCards == null || selectCards.Length <= 0) //不要
|
||||
if (selectCards == null || selectCards.Length <= 0)
|
||||
{
|
||||
payCard = new PlayOutCardPdkF();
|
||||
payCard.Pos = GamePack.Info.WhoPlay;
|
||||
payCard.Type = CardType1.None;
|
||||
payCard = new PlayOutCardPdkF { Pos = (byte)pos, Type = CardType1.None };
|
||||
GamePack.Info.ActivePlayCard = payCard;
|
||||
if (CheckPack(GamePack.Info))
|
||||
{
|
||||
break; //如果包输入正确就跳走
|
||||
}
|
||||
else
|
||||
{
|
||||
Log("检测不合格,输入非法值");
|
||||
}
|
||||
|
||||
if (CheckPack(GamePack.Info)) break;
|
||||
Log("检测不合格,输入非法值");
|
||||
}
|
||||
else if (PdkCardAlgorithm.GetOutCard(selectCards,
|
||||
GamePack.CardPack.Cards[GamePack.Info.WhoPlay - 1].CardInfos.Where(x => x.GameState == 1).ToArray(),
|
||||
GamePack.CardPack.Cards[pos - 1].CardInfos.Where(x => x.GameState == 1).ToArray(),
|
||||
this.Rule, out payCard))
|
||||
{
|
||||
payCard.Pos = GamePack.Info.WhoPlay;
|
||||
payCard.Pos = (byte)pos;
|
||||
GamePack.Info.ActivePlayCard = payCard;
|
||||
if (CheckPack(GamePack.Info))
|
||||
{
|
||||
break; //如果包输入正确就跳走
|
||||
}
|
||||
else
|
||||
{
|
||||
Log("检测不合格,输入非法值");
|
||||
}
|
||||
if (CheckPack(GamePack.Info)) break;
|
||||
Log("检测不合格,输入非法值");
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -687,10 +727,7 @@ namespace PdkFriendServer.Logic
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case 6:
|
||||
//GameOver();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user