Files
hjha-server/PdkFriendServer/Logic/PdkGameMain.cs

905 lines
36 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using GameData;
using MrWu.Debug;
using PdkFriendServer.GlobalManager;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using GameMessage.PaoDeKuaiF;
using GameFix.PaoDeKuaiF;
using GameMessage;
using Server.Data;
namespace PdkFriendServer.Logic
{
/// <summary>
/// 跑得快朋友房主逻辑
/// </summary>
public partial class PdkGameMain
{
/// <summary>
/// 游戏主包
/// </summary>
public PdkGamePack GamePack;
/// <summary>
/// 服务器本地内存
/// </summary>
public LogicMemory logicMemory;
/// <summary>
/// 规则
/// </summary>
public PdkRule Rule;
/// <summary>
/// 桌子对象
/// </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个botBotMode==true时首次WaitWanJiaShuRu调用
/// BotTypes: "ISMCTS" / "NEURAL" / "NEURAL_V5" / null=默认ISMCTS
/// 训练模式: ["NEURAL","NEURAL","ISMCTS"] = 2个模型bot + 1个ISMCTS</summary>
public static string[] BotTypes = null;
private static int _flushGameCounter = 0;
private void InitBots()
{
_bots = new IPdkBot[3];
for (int i = 0; i < 3; i++)
{
string type = BotTypes != null && BotTypes.Length > i ? BotTypes[i] : null;
if (type == "NEURAL")
_bots[i] = new NeuralBot("model.onnx", 0.1f);
else if (type == "NEURAL_V5")
_bots[i] = new NeuralBotV5("model_v5.onnx", 0.05f);
else
_bots[i] = new IsmctsBot();
}
}
/// <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>
public void GameStart()
{
byte shangyou = 0; //上游位置从1开始
byte overJu = (byte)(this.DeskGameDo == null ? 0 : DeskGameDo.GetDeskInt(8)); //打完了几局0就是一局都没有打完也就是首局
shangyou = GamePack.Info.OverPos;
var tg = GamePack.Info.PlayTuoGauan;
GamePack = new PdkGamePack();
if (this.DeskGameDo != null)
{
SetFriendGz();
GamePack.Init(GamePack.Info.PlayNum);
}
else
{ //测试的规则
GamePack.Init(3);
GamePack.Info.PlayNum = 3;
//设置玩法规则
Rule = new PdkRule();
Rule.GuanPai = true; //经典玩法
Rule.BiYa = true;//不必压
Rule.ShouJu3 = true;
Rule.SiDai3 = true;
Rule.BaoZhuang = true;
Rule.ZhaDanDeFen = true;
}
LoadInit();
if (overJu == 0)
{
logicMemory.BombCount = 0;
}
logicMemory.WarCount = overJu;
logicMemory.ShangYou = shangyou;
if (overJu != 0)
{
GamePack.Info.PlayTuoGauan = tg;
}
GamePack.Info.GameZT = 2;
Log(Rule.ToString());
//this.GameFaPai(); //屏蔽掉让dotime驱动流程玩下周
}
/// <summary>
/// 设置规则自动准备时间
/// </summary>
void SetAutoReadTime()
{
if (this.Rule.TuoGuanNum <= 0) return;
if (this.DeskGameDo == null) return;
if (this.DeskGameDo.desk == null) return;
if (this.DeskGameDo.desk.deskinfo == null) return;
if (this.DeskGameDo.desk.deskinfo.rule == null) return;
if (this.DeskGameDo.desk.deskinfo.rule.RuleEx == null) return;
// if (!this.DeskGameDo.desk.deskinfo.rule.RuleEx.DepositAutoDissolve) return;
if (this.DeskGameDo.desk.deskinfo.rule.RuleEx.AutoDeposit > 0) return;
this.DeskGameDo.desk.deskinfo.rule.RuleEx.AutoDeposit = this.Rule.TuoGuanNum * 60;
}
/// <summary>
/// 计时器 1秒钟执行一次
/// </summary>
public void DoTime()
{
SetAutoReadTime();
switch (GamePack.Info.GameZT)
{
//case 1:
// GameStart();
// break;
case 2:
GameFaPai();
break;
case 3:
BaoZhuangTuoGuan();
break;
case 4:
//if (Rule.TuoGuanNum > 0)
//{//需要托管
DaPaiTuoGuan();
//}
//玩家先手,并且是最后一张牌,就自动帮玩家出牌
if (GamePack.Info.MaxPlayCard.GameNum <= 0)
{
var cards = GamePack.CardPack.Cards[GamePack.Info.WhoPlay - 1].CardInfos.Where(x => x.GameState == 1).ToArray();
var b = PdkCardAlgorithm.GetOutCard(cards, cards, Rule, out var payCard);
var zhad = PdkCardAlgorithm.IsHaveBomb(cards, Rule.AAAIsZhaDan);
if (b && payCard.Ids.Length == cards.Length && payCard.Type != CardType1.SiDai2 && payCard.Type != CardType1.SiDai3 && !zhad)
{
payCard.Pos = (byte)GamePack.Info.WhoPlay;
GamePack.Info.ActivePlayCard = payCard;
Log($"最后一张牌,就自动帮玩家出牌 who:{GamePack.Info.WhoPlay}先出 ,托管出的牌:{payCard}");
GamePack.Info.ActivePlayCard = payCard;
Debug.Info("最后一手GameDo");
GameDo();
}
}
break;
case 5:
if (this.TimeNum >= 2)
{
GameOver();
}
break;
default:
// Log("DoTime default ");
break;
}
TimeNum++;
}
/// <summary>
/// 游戏发牌
/// </summary>
public void GameFaPai()
{
byte bc = 0; //计算这局的炸弹个数
for (int i = 0; i < 20; i++)
{
if (i > 0)
{
Log($"发牌i:{i} bnum:{bc} lc:{logicMemory.BombCount}", DebugLevel.ImportantLog);
}
InitCard();
bc = 0;
bool b = false;
for (int j = 0; j < GamePack.Info.PlayNum; j++)
{
byte bnum = CalcPlayBombRule(j);
Log($"玩家:{j},bombCount:{bnum}");
//if (bnum > 1) //单个人一手牌不能有超过2个炸弹
//{
// bc += (byte)bnum;
// break;
//}
if (bnum > 0)
{
bc += bnum;
}
}
if (logicMemory.BombCount + bc <= 1)
{
logicMemory.BombCount += bc;
b = true;
}
if (b)
{
break;
}
}
CheckFeiJi();
if (Rule.HongTao10ZhaNiao)
{ //红桃十扎鸟
GamePack.Info.HongTaoShiPos = GetHongTaoShiPos();
}
if (Rule.MeiJu3)
{ //每局黑桃3出
GamePack.Info.FistPlay = GetHeiTao3Pos();
Log($"第一个出牌位置:{GamePack.Info.FistPlay}");
}
else if (Rule.ShouJu3)
{ //首局黑桃三先出,下局赢家出
GamePack.Info.FistPlay = logicMemory.WarCount == 0 ? GetHeiTao3Pos() : logicMemory.ShangYou;
Log($"第一个出牌位置:{GamePack.Info.FistPlay},开始次数:{logicMemory.WarCount},上游玩家:{logicMemory.ShangYou}");
}
GamePack.Info.WhoPlay = GamePack.Info.FistPlay;
GamePack.Info.GameZT = (byte)(Rule.BaoZhuang ? 3 : 4);
TimeNum = 0;
SendPack();
}
/// <summary>
/// 包庄流程
/// </summary>
public void GameBaoZhuang()
{
int bcount = 0;//包庄的人数
byte[] pos = new byte[GamePack.Info.PlayNum]; //包庄人的位置
bool zhuangB = false;
if (GamePack.Info.BaoZhuang[GamePack.Info.FistPlay - 1] == 1)
{ //庄家包庄了,直接进入下一流程
GamePack.Info.WhoPlay = GamePack.Info.FistPlay;
GamePack.Info.BaoPos = GamePack.Info.WhoPlay;
GamePack.Info.GameZT = 4; //进入打牌
SetFalseOperation();
SendPack();
return;
}
else
{
for (byte i = 0; i < GamePack.Info.PlayNum; i++)
{
if (GamePack.Info.BaoZhuang[i] == 0)
{
GamePack.Info.WhoPlay = (byte)(i + 1);
SendPack();
return; //还有玩家没有操作,不处理流程
}
if (GamePack.Info.BaoZhuang[i] == 1)
{
pos[bcount] = (byte)(i + 1);
if (!zhuangB && pos[bcount] == GamePack.Info.FistPlay)
{
zhuangB = true;
}
bcount++;
}
}
}
if (bcount == 1)
{
GamePack.Info.WhoPlay = pos[0];
GamePack.Info.BaoPos = GamePack.Info.WhoPlay;
}
else if (bcount > 1)
{ //多个人包庄
if (zhuangB)
{//如果庄家包庄了,那么就是庄家为包庄
GamePack.Info.WhoPlay = GamePack.Info.FistPlay;
}
else
{ //如果没有包庄的话,那么靠近庄家的下一家为包庄玩家
byte npos = GetNextPos(GamePack.Info.FistPlay); //庄的下家
for (int j = 0; j < pos.Length; j++)
{
bool b = false;
for (byte i = 0; i < pos.Length; i++)
{
if (pos[i] == npos)
{
GamePack.Info.WhoPlay = pos[i];
b = true;
break;
}
}
if (!b)
{
npos = GetNextPos(npos);
}
else
{
break;
}
}
}
GamePack.Info.BaoPos = GamePack.Info.WhoPlay;
}
Log($"进入打牌play:{GamePack.Info.WhoPlay} ,包庄玩家的位置:{GamePack.Info.BaoPos}");
GamePack.Info.GameZT = 4; //进入打牌
SetFalseOperation();
SendPack();
}
/// <summary>
/// 打牌流程
/// </summary>
void GameDaPai()
{
Log("进入打牌流程,玩家出牌内容是:" + GamePack.Info.ActivePlayCard.ToString());
//如果玩家有出牌1修改牌内存2修改最大出牌信息
//记录炸弹计分
//判断一轮打完
//判断一局游戏打完
//转换控制权 一个玩家出完牌后
byte chupaiPos = 0;
if (GamePack.Info.ActivePlayCard.Type != CardType1.None)
{
chupaiPos = GamePack.Info.ActivePlayCard.Pos;
SetCardToOut(GamePack.Info.ActivePlayCard.Pos, GamePack.Info.ActivePlayCard.Ids);
if (Rule.ZhaDanDeFen && GamePack.Info.ActivePlayCard.Type == CardType1.ZhaDan)
{
//炸弹得分,并且出的是炸弹
/*炸弹+10打出炸弹+10分不勾选0分
在有大必压得玩法下,一轮中打出的炸弹只算当局最大的炸弹分,
不必压得玩法下,只要打出炸弹都算分*/
AddZhaDanCount(GamePack.Info.ActivePlayCard.Pos, 1);
// GamePack.Info.ZhaDans[GamePack.Info.ActivePlayCard.Pos - 1]++;
if (Rule.BiYa && GamePack.Info.MaxPlayCard.Type == CardType1.ZhaDan)
{
//把之前加的炸弹减回去。
//GamePack.Info.ZhaDans[GamePack.Info.MaxPlayCard.Pos - 1]--;
AddZhaDanCount(GamePack.Info.MaxPlayCard.Pos, -1);
}
}
GamePack.Info.MaxPlayCard = GamePack.Info.ActivePlayCard;
}
if (IsGameOver(chupaiPos))
{ //游戏是否结束
SendPack();
this.TimeNum = 0;
GamePack.Info.GameZT = 5;
// GameOver(); 修改为定时器驱动
return;
}
GamePack.Info.WhoPlay = GetNextPos(GamePack.Info.WhoPlay);
Debug.Info($"当前玩家:{GamePack.Info.WhoPlay},下一个出牌的人:{GamePack.Info.WhoPlay}");
if (GamePack.Info.WhoPlay == GamePack.Info.MaxPlayCard.Pos)
{ //一轮结束
Log("一轮结束");
GamePack.Info.MaxPlayCard.Pos = 0;
GamePack.Info.MaxPlayCard.GameNum = 0;
GamePack.Info.MaxPlayCard.Type = CardType1.None;
GamePack.Info.MaxPlayCard.Ids = null;
}
SendPack();
}
void GameOver()
{
Log($"进入结算 bao:{GamePack.Info.BaoPos},overpos:{GamePack.Info.OverPos}");
int count = 0;
if (Rule.JingDianWanFa || Rule.GuanPai)
{
count = 16;
}
if (Rule.Zhang15)
{
count = 15;
}
if (GamePack.Info.BaoPos > 0)
{ //有人包庄
var baoWin = GamePack.Info.BaoPos == GamePack.Info.OverPos;
Log($"baowin:{baoWin}");
for (int i = 0; i < GamePack.Info.PlayNum; i++)
{
if (i + 1 != GamePack.Info.BaoPos)
{ //先统计闲家
int bei = GamePack.Info.HongTaoShiPos == i + 1 || GamePack.Info.HongTaoShiPos == GamePack.Info.BaoPos ? 4 : 2; //红桃十扎鸟
GamePack.Info.Score[i] += (baoWin ? 0 - count * bei : count * bei);
}
}
}
else
{
for (int i = 0; i < GamePack.Info.PlayNum; i++)
{//先统计闲家
if (i + 1 != GamePack.Info.OverPos)
{
if (GamePack.Info.ShenYuCard[i] == 1) continue;
var bei = GamePack.Info.HongTaoShiPos == i + 1 || GamePack.Info.HongTaoShiPos == GamePack.Info.OverPos ? 2 : 1;//红桃十扎鸟
var num = GamePack.Info.ShenYuCard[i] == count ? count * 2 : GamePack.Info.ShenYuCard[i];
GamePack.Info.Score[i] += 0 - num * bei;
}
}
}
for (int i = 0; i < GamePack.Info.PlayNum; i++)
{
if (i + 1 == (GamePack.Info.BaoPos > 0 ? GamePack.Info.BaoPos : GamePack.Info.OverPos))
{ //统计庄家,把闲家的都加起来就是庄家的输赢
for (int j = 0; j < GamePack.Info.PlayNum; j++)
{
if (j == i) continue;
GamePack.Info.Score[i] -= GamePack.Info.Score[j];
}
}
}
for (int i = 0; i < GamePack.Info.PlayNum; i++)
{
if (GamePack.Info.ZhaDans[i] != 0)
{
GamePack.Info.Score[i] += (GamePack.Info.ZhaDans[i] * 10);
}
}
//处理托管罚分
var fafen = GetTuoGuanFaFen();
if (fafen > 0)
{
var tgPos = GetTuoGuanPlay();
if (tgPos >= 0)
{ //有玩家托管
//int fen = fafen / (GamePack.Info.PlayNum - 1);
for (int i = 0; i < GamePack.Info.PlayNum; i++)
{
if (i == tgPos)
{
GamePack.Info.Score[i] -= (fafen * (GamePack.Info.PlayNum - 1));
}
else
{
GamePack.Info.Score[i] += fafen;
}
}
}
}
#if DEBUG
for (int i = 0; i < GamePack.Info.PlayNum; i++)
{
Log($"玩家:{(i + 1)} ,输赢:{GamePack.Info.Score[i]}");
}
#endif
// 训练数据收集:输出本局所有 ISMCTS 决策
if (TrainingCollector.Enabled)
{
float[] rewards = new float[GamePack.Info.PlayNum];
for (int i = 0; i < GamePack.Info.PlayNum; i++)
{
// 赢的分 > 0 → reward=1; 输的分 < 0 → reward=-1; 否则 0
float s = GamePack.Info.Score[i];
rewards[i] = s > 0 ? 1f : s < 0 ? -1f : 0f;
}
TrainingCollector.FlushGame(_flushGameCounter++, rewards, GamePack.Info.OverPos, BotTypes);
}
if (DeskGameDo != null)
{
DeskGameDo.GameOver();
}
}
/// <summary>
/// 是否托管罚分
/// </summary>
/// <returns>0不罚分 </returns>
int GetTuoGuanFaFen()
{
if (this.DeskGameDo == null || this.DeskGameDo.desk == null || this.DeskGameDo.desk.deskinfo == null || this.DeskGameDo.desk.deskinfo.rule == null ||
this.DeskGameDo.desk.deskinfo.rule.RuleEx == null) return 0;
return this.DeskGameDo.desk.deskinfo.rule.RuleEx.DepositAutoDissolve ? this.DeskGameDo.desk.deskinfo.rule.RuleEx.OutLinePenaltyPoint : 0;
}
/// <summary>
/// 找打托管的玩家
/// </summary>
/// <returns>从0开始 -1未找到</returns>
int GetTuoGuanPlay()
{
return DeskGameDo.GetPlayerFirstDepositSeat();
//var desk = DeskGameDo.GetDesk();
//for (int i = 0; i < GamePack.Info.PlayNum; i++)
//{
// if (desk[i] != null && desk[i].isDePosit)
// {//找到在 托管的玩家
// return i;
// }
//}
//return -1;
}
/// <summary>
/// 游戏发包,发全包
/// </summary>
void SendPack()
{
Log($"whoPlay:{GamePack.Info.WhoPlay}");
if (DeskGameDo == null)
{
var str = JsonPack.GetJson(this.GamePack);
var dir = "./gamepack";
if (!Directory.Exists(dir)) Directory.CreateDirectory(dir);
File.WriteAllText(Path.Combine(dir, "gamepack.txt"), str);
var path = Path.Combine(dir, $"gamepack{DateTime.Now:yyyy-MM-dd-HH-mm-ss-fff}.txt");
Log("保存文件:" + path);
File.WriteAllText(path, str);
WaitWanJiaShuRu(); //等玩家输入。模拟玩家打牌
}
else
{
SetOperation();
DeskGameDo.SendGamePack();
}
}
void SetFalseOperation()
{
if (DeskGameDo == null) return;
for (int i = 0; i < GamePack.Info.PlayNum; i++)
{
this.SetWaitOperation(i, false);
}
}
public void SetOperation()
{
for (int i = 0; i < GamePack.Info.PlayNum; i++)
{
var pl = this.DeskGameDo.desk[i];
if (pl != null)
{
GamePack.Info.PlayTuoGauan[i] = (byte)(pl.isDePosit ? 1 : 0);
}
bool b = false; //包庄流程是同时进行的
if (GamePack.Info.GameZT == 3)
{
b = GamePack.Info.BaoZhuang[i] == 0;
}
this.SetWaitOperation(i, GamePack.Info.GameZT == 3 ? b : i + 1 == GamePack.Info.WhoPlay);
}
}
/// <summary>
/// 设置玩家的操作权
/// </summary>
/// <param name="seat">下标从0开始</param>
/// <param name="waitOperation"></param>
public void SetWaitOperation(int seat, bool waitOperation)
{
var desk = this.DeskGameDo.GetDesk();
if (seat < 0 || seat >= desk.PlayerCnt)
{
return;
}
var pl = desk[seat];
if (pl != null)
{
//之前不能操作,现在可以操作,重置托管时间
if (!pl.WaitOperation && waitOperation)
{
pl.AutoDepositTime = 0;
}
pl.WaitOperation = waitOperation;
}
}
/// <summary>
/// 检查包内容是否合法
/// </summary>
/// <param name="pack"></param>
/// <returns></returns>
public bool CheckPack(PdkLogicInfo pack)
{
if (pack.WhoPlay != GamePack.Info.WhoPlay && GamePack.Info.GameZT > 3) return false;
switch (GamePack.Info.GameZT)
{
case 3: //包庄 只能输入1和2
return pack.BaoZhuang[pack.WhoPlay - 1] == 1 || pack.BaoZhuang[pack.WhoPlay - 1] == 2;
case 4:
if (pack.WhoPlay != pack.ActivePlayCard.Pos)
{
Debug.Error($"who:{pack.WhoPlay},apos:{pack.ActivePlayCard}");
return false;
}
return CheckChuPai(pack.ActivePlayCard);
}
return true;
}
public void GameDo()
{
switch (GamePack.Info.GameZT)
{
//case 1:
// GameStart();
// break;
case 2:
GameFaPai();
break;
case 3:
GameBaoZhuang();
break;
case 4:
GameDaPai();
break;
case 5:
GameOver();
break;
default:
Log("default GameDo game over");
break;
}
}
/// <summary>
/// 等待玩家输入
/// </summary>
void WaitWanJiaShuRu()
{
if (DeskGameDo != null) return;
int pos = GamePack.Info.WhoPlay;
switch (GamePack.Info.GameZT)
{
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)
{
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 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: //打牌流程
{
// Bot 接管:懒初始化
if (BotMode && _bots == null)
InitBots();
if (_bots != null && _bots[pos - 1] != null)
{
var view = BuildBotView(pos);
var botPlay = _bots[pos - 1].DecidePlay(view);
// 非pass(有Ids)则运行 GetOutCard 获取正确牌型pass(Type=None且Ids为空)直接设
if (botPlay.Ids != null && botPlay.Ids.Length > 0)
{
var hand = view.MyHand;
var selectCards = hand.Where(c => botPlay.Ids.Contains(c.ID)).ToArray();
if (selectCards.Length > 0)
{
PdkCardAlgorithm.GetOutCard(selectCards, hand, Rule, out var payCard);
payCard.Pos = (byte)pos;
GamePack.Info.ActivePlayCard = payCard;
}
}
else
{
GamePack.Info.ActivePlayCard = botPlay;
}
return;
}
// 人工输入
Log("打牌操作 pos:" + pos);
while (true)
{
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[pos - 1].CardInfos
.Where(x => ss.Any(s => s == x.ID.ToString())).ToArray();
PlayOutCardPdkF payCard;
if (selectCards == null || selectCards.Length <= 0)
{
payCard = new PlayOutCardPdkF { Pos = (byte)pos, Type = CardType1.None };
GamePack.Info.ActivePlayCard = payCard;
if (CheckPack(GamePack.Info)) break;
Log("检测不合格,输入非法值");
}
else if (PdkCardAlgorithm.GetOutCard(selectCards,
GamePack.CardPack.Cards[pos - 1].CardInfos.Where(x => x.GameState == 1).ToArray(),
this.Rule, out payCard))
{
payCard.Pos = (byte)pos;
GamePack.Info.ActivePlayCard = payCard;
if (CheckPack(GamePack.Info)) break;
Log("检测不合格,输入非法值");
}
else
{
Log("输入的牌不符合规则,不能出下去");
}
}
break;
}
}
}
void textxxxx()
{
// GameStart();
// GameFaPai();
//PlayOutCard output = new PlayOutCard();
//output.Pos = 1; output.Type = CardType.LianDui;
//output.GameNum = 9;
//output.Ids = new byte[6];
//TCardInfo[] shoupai = new TCardInfo[16];
//shoupai[0] = new TCardInfo() { ID = 1, GameNum = 14, Flower = 1, Num = 14, Score = 0, GameOwer = 1, GameState = 1 };
//shoupai[1] = new TCardInfo() { ID = 27, GameNum = 14, Flower = 3, Num = 14, Score = 0, GameOwer = 1, GameState = 1 };
//shoupai[2] = new TCardInfo() { ID = 26, GameNum = 13, Flower = 2, Num = 13, Score = 0, GameOwer = 1, GameState = 1 };
//shoupai[3] = new TCardInfo() { ID = 25, GameNum = 12, Flower = 2, Num = 12, Score = 0, GameOwer = 1, GameState = 1 };
//shoupai[4] = new TCardInfo() { ID = 38, GameNum = 12, Flower = 3, Num = 12, Score = 0, GameOwer = 1, GameState = 1 };
//shoupai[5] = new TCardInfo() { ID = 36, GameNum = 10, Flower = 3, Num = 10, Score = 0, GameOwer = 1, GameState = 1 };
//shoupai[6] = new TCardInfo() { ID = 49, GameNum = 10, Flower = 4, Num = 10, Score = 0, GameOwer = 1, GameState = 1 };
//shoupai[7] = new TCardInfo() { ID = 35, GameNum = 9, Flower = 3, Num = 9, Score = 0, GameOwer = 1, GameState = 1 };
//shoupai[8] = new TCardInfo() { ID = 48, GameNum = 9, Flower = 4, Num = 9, Score = 0, GameOwer = 1, GameState = 1 };
//shoupai[9] = new TCardInfo() { ID = 8, GameNum = 8, Flower = 1, Num = 8, Score = 0, GameOwer = 1, GameState = 1 };
//shoupai[10] = new TCardInfo() { ID = 34, GameNum = 8, Flower = 3, Num = 8, Score = 0, GameOwer = 1, GameState = 1 };
//shoupai[11] = new TCardInfo() { ID = 5, GameNum = 5, Flower = 1, Num = 5, Score = 0, GameOwer = 1, GameState = 1 };
//shoupai[12] = new TCardInfo() { ID = 18, GameNum = 5, Flower = 2, Num = 5, Score = 0, GameOwer = 1, GameState = 1 };
//shoupai[13] = new TCardInfo() { ID = 44, GameNum = 5, Flower = 4, Num = 5, Score = 0, GameOwer = 1, GameState = 1 };
//shoupai[14] = new TCardInfo() { ID = 16, GameNum = 3, Flower =2, Num = 3, Score = 0, GameOwer = 1, GameState = 1 };
//shoupai[15] = new TCardInfo() { ID = 29, GameNum = 3, Flower = 3, Num = 3, Score = 0, GameOwer = 1, GameState = 1 };
//var tishi = PdkCardAlgorithm.GetTipCard(output, shoupai, null);
//Console.WriteLine(tishi);
}
/// <summary>
/// 测试函数
/// </summary>
public void Test(string path = "")
{
//textxxxx();
//return;
if (File.Exists("output.txt"))
{
File.Delete("output.txt");
}
string testDir = !string.IsNullOrWhiteSpace(path)
? path
: "./test";
if (!Directory.Exists(testDir))
{
Directory.CreateDirectory(testDir);
}
foreach (string file in Directory.GetFiles(testDir))
{
File.Delete(file);
}
bool b = true;
GamePack.Info.GameZT = 1;
if (!string.IsNullOrWhiteSpace(path))
{
GamePack = JsonPack.GetData<PdkGamePack>(File.ReadAllText(path));
}
while (b)
{
switch (GamePack.Info.GameZT)
{
case 1:
GameStart();
break;
case 2:
GameFaPai();
break;
case 3:
GameBaoZhuang();
break;
case 4:
GameDaPai();
break;
case 5:
GameOver();
GamePack.Info.GameZT = 11; //进入结束就结束
break;
default:
b = false;
Log("test over");
break;
}
}
}
void WriteToConsoleAndFile(StreamWriter writer, string message)
{
Console.WriteLine(message); // 写入控制台
writer.WriteLine(message); // 写入文件
}
public void Log(string msg, DebugLevel leve = DebugLevel.Info)
{
if (DeskGameDo == null)
{
using (StreamWriter writer = new StreamWriter("output.txt", true)) // 第二个参数为true表示追加到文件
{
WriteToConsoleAndFile(writer, $"[{DateTime.Now.ToString("G")}]:" + msg);
}
Thread.Sleep(1);
}
else
{
switch (leve)
{
case DebugLevel.Info:
Debug.Info(msg);
break;
case DebugLevel.Warning:
Debug.Warning(msg);
break;
case DebugLevel.ImportantLog:
Debug.ImportantLog(msg);
break;
case DebugLevel.Error:
Debug.Error(msg);
break;
case DebugLevel.Fatal:
Debug.Fatal(msg);
break;
default:
Debug.Info(msg);
break;
}
}
}
}
}