using GameData;
using MrWu.Debug;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using GameFix.Poker;
using GameFix.PaoDeKuaiF;
using GameMessage;
using GameMessage.PaoDeKuaiF;
namespace PdkFriendServer.Logic
{
public partial class PdkGameMain
{
///
/// 获取黑桃3的位置,如果都没有黑桃3那就取黑桃4
///
///
byte GetHeiTao3Pos()
{
byte result = 0;
for (byte carId = 3; carId < 14; carId++)
{//从黑桃3开始找,没有找到就依次往上查找
for (byte i = 0; i < GamePack.Info.PlayNum; i++)
{
for (int j = GamePack.CardPack.Cards[i].CardInfos.Length - 1; j >= 0; j--)
{
if (GamePack.CardPack.Cards[i].CardInfos[j].Flower != 1) continue;
if (GamePack.CardPack.Cards[i].CardInfos[j].GameNum > carId) break;
if (GamePack.CardPack.Cards[i].CardInfos[j].GameNum == carId)
{
result = (byte)(i + 1);
return result;
}
}
}
}
return result;
}
///
/// 获取红桃十的玩家位置
///
/// 0没有玩家有红桃十 大于0就是改位置的玩家
byte GetHongTaoShiPos()
{
byte result = 0;
for (byte i = 0; i < GamePack.Info.PlayNum; i++)
{
for (int j = GamePack.CardPack.Cards[i].CardInfos.Length - 1; j >= 0; j--)
{
if (GamePack.CardPack.Cards[i].CardInfos[j].Flower != 2) continue;
if (GamePack.CardPack.Cards[i].CardInfos[j].GameNum == 10)
{
result = (byte)(i + 1);
return result;
}
}
}
return 0;
}
///
/// 查找下一个玩家的位置
///
///
///
byte GetNextPos(byte pos)
{
if (pos <= 0) throw new Exception("参数错误" + pos);
byte result = (byte)(pos + 1);
if (result > GamePack.Info.PlayNum)
{
result = 1;
}
return result;
}
///
/// 游戏是否结束
///
/// true游戏结束 false游戏没有结束
bool IsGameOver(byte chupaoPos)
{
if (GamePack.Info.BaoPos > 0 && GamePack.Info.ShenYuCard[GamePack.Info.BaoPos - 1] == 0)
{
//包庄人的牌出完了,游戏结束
GamePack.Info.OverPos = GamePack.Info.BaoPos;
return true;
}
//如果是包庄的话,出牌的人
if (GamePack.Info.BaoPos > 0 && chupaoPos > 0)
{
var b = GamePack.Info.BaoPos != chupaoPos; //如果出牌的位置和包庄位置不一样。就说明被别人给压牌了,游戏结束
if (b)
{
GamePack.Info.OverPos = chupaoPos; //记录压他牌的人位置
}
return b;
}
for (int i = 0; i < GamePack.Info.PlayNum; i++)
{
if (GamePack.Info.ShenYuCard[i] <= 0)
{ //只要有一个玩家的牌出完就结束
GamePack.Info.OverPos = (byte)(i + 1);
return true;
}
}
return false;
}
///
/// 检查出牌包内容
///
///
///
public bool CheckChuPai(PlayOutCardPdkF payCard)
{
if (payCard.Pos <= 0 || payCard.Pos > 3) return false;
if (PokerLogic.CheckSameId(payCard.Ids))
{
Log($"玩家出了相同ID的牌型,{payCard}", DebugLevel.Error);
return false;
}
if (GamePack.Info.MaxPlayCard.GameNum == 0 && payCard.Type == CardType1.None) return false; //第一个出牌人不能出不要
if (GamePack.Info.MaxPlayCard.GameNum > 0 && payCard.Type == CardType1.None)
{
if (!Rule.BiYa && !Rule.XiaJiaBaoDan) return true; //不是必压的情况下,并且没有勾选下家报单,之前有人出牌,再出个不要可以出
//不必压,但是勾选下家报单,之前出的不是单张,这个时候可以出不要。
if (!Rule.BiYa && Rule.XiaJiaBaoDan && GamePack.Info.MaxPlayCard.Type != CardType1.DanZhang) return true;
if (!Rule.BiYa && Rule.XiaJiaBaoDan && GamePack.Info.ShenYuCard[GetNextPos(payCard.Pos) - 1] != 1) return true;
}
if (!CheckPaiIsInHand(payCard.Ids, payCard.Pos)) return false;
if (!Rule.AAAIsZhaDan && payCard.Type == CardType1.ZhaDan && payCard.GameNum == 14) return false; //3个A不是炸弹
if (!Rule.SiDai2 && payCard.Type == CardType1.SiDai2) return false;
if (!Rule.SiDai3 && payCard.Type == CardType1.SiDai3) return false;
//if (!Rule.BiYa && GamePack.Info.MaxPlayCard.GameNum > 0 && payCard.Type == CardType.None) return true; //如果之前有人出牌,再出个不要可以出
if ((Rule.BiYa ||
(Rule.XiaJiaBaoDan && GamePack.Info.MaxPlayCard.Type == CardType1.DanZhang && GamePack.Info.ShenYuCard[GetNextPos(payCard.Pos) - 1] == 1))
&& payCard.Type == CardType1.None)
{ //如果是必压,玩家出了不要,检查一下玩家有没有必上一家大的牌
return !PdkCardAlgorithm.CheckHaveBigger(GamePack.Info.MaxPlayCard, GamePack.CardPack.Cards[payCard.Pos - 1].CardInfos.Where(x => x.GameState == 1).ToArray(),
GamePack.CardPack.Cards[GamePack.Info.MaxPlayCard.Pos - 1].CardInfos, Rule.AAAIsZhaDan);
}
int count = GamePack.Info.ShenYuCard[payCard.Pos - 1];
//单张、对子、三带二、顺子、连对、飞机带翅膀、炸弹,四带三、四带二
if (payCard.Type == CardType1.SanDai2 && count >= 5 && payCard.Ids.Length < 5) return false;
if (payCard.Type == CardType1.SiDai3 && count >= 7 && payCard.Ids.Length < 7) return false;
if (payCard.Type == CardType1.SiDai2 && count >= 6 && payCard.Ids.Length < 6) return false;
if (payCard.Type == CardType1.FeiJi)
{//如果飞机的张数不够就返回false
if (count >= 10 && payCard.Ids.Length < 10) return false;
var sanzhang = PokerLogic.GetFeiJiCount(GetCardByIds(payCard.Pos, payCard.Ids));
var c = sanzhang * 3 + sanzhang * 2;
if (count >= c && payCard.Ids.Length < c) return false;
var maxSanZahng = PokerLogic.GetFeiJiCount(GetCardByIds(GamePack.Info.MaxPlayCard.Pos, GamePack.Info.MaxPlayCard.Ids));
if (sanzhang < maxSanZahng) return false;
}
if (GamePack.Info.MaxPlayCard.GameNum == 0)
{
//如果最大的出牌人是没有值的话,然后当前人不是出不要就可以出下去。
return payCard.Type != CardType1.None;
}
if (GamePack.Info.MaxPlayCard.Type == payCard.Type)
{
if (payCard.Type == CardType1.DanZhang || payCard.Type == CardType1.DuiZi || payCard.Type == CardType1.ShunZi || payCard.Type == CardType1.LianDui)
{
return payCard.Ids.Length == GamePack.Info.MaxPlayCard.Ids.Length && payCard.GameNum > GamePack.Info.MaxPlayCard.GameNum;
}
else
{
return payCard.GameNum > GamePack.Info.MaxPlayCard.GameNum;
}
}
else
{
if (GamePack.Info.MaxPlayCard.Type != CardType1.ZhaDan)
{
return payCard.Type == CardType1.ZhaDan;
}
}
return false;
}
///
/// 检测牌是否都在玩家手上
///
/// 要检测的牌ID集合
/// 要检测哪个玩家的手牌
/// true都在手上 false没有在手上
bool CheckPaiIsInHand(byte[] Ids, int pos)
{
if (pos <= 0 || pos > GamePack.Info.PlayNum) return false;
if (Ids == null || Ids.Length <= 0) return true; //没有牌不检测
pos--;
int count = 0;
foreach (var id in Ids)
{
foreach (var item in GamePack.CardPack.Cards[pos].CardInfos)
{
if (item.ID == id && item.GameState == 1)
{
count++;
break;
}
}
}
return count == Ids.Length;
}
///
/// 给某个玩家加炸弹,其他玩家减炸弹
///
///
///
void AddZhaDanCount(int pos, int num)
{
for (int i = 0; i < GamePack.Info.ZhaDans.Length; i++)
{
if (i + 1 == pos)
{
GamePack.Info.ZhaDans[i] += num * (GamePack.Info.ZhaDans.Length - 1);
}
else
{
GamePack.Info.ZhaDans[i] -= num;
}
}
}
///
/// 设置朋友房规则
///
public void SetFriendGz()
{
if (this.DeskGameDo == null) return;
var gz = this.DeskGameDo.GetRoomGz();
Rule = new PdkRule();
Rule.BiYa = true;//不必压
if (gz[0] == '0')
{
Rule.JingDianWanFa = true;
}
else if (gz[0] == '1')
{
Rule.Zhang15 = true;
}
else if (gz[0] == '2')
{
Rule.GuanPai = true;
Rule.BiYa = false;//不必压
}
if (gz[1] == '0')
{
Rule.ShouJu3 = true;
}
else if (gz[1] == '1')
{
Rule.MeiJu3 = true;
}
if (gz[2] == '0')
{
Rule.SiDai3 = true;
}
else if (gz[2] == '1')
{
Rule.SiDai2 = true;
}
if (gz[8] == '0')
{
GamePack.Info.PlayNum = 2;
}
else if (gz[8] == '1')
{
GamePack.Info.PlayNum = 3;
}
Rule.XianShenYuPai = gz[3] == '1';
Rule.HongTao10ZhaNiao = gz[4] == '1';
Rule.BaoZhuang = gz[5] == '1';
Rule.AAAIsZhaDan = gz[6] == '1';
Rule.XiaJiaBaoDan = gz[7] == '1';
Rule.ZhaDanDeFen = gz[9] == '1';
Rule.HeiTao3BiChu = gz[11] == '1';
switch (gz[10]) //设置托管
{
case '0':
Rule.TuoGuanNum = 0;
break;
case '1':
Rule.TuoGuanNum = 1;
break;
case '2':
Rule.TuoGuanNum = 3;
break;
case '3':
Rule.TuoGuanNum = 5;
break;
}
}
///
/// 闹钟计时器
///
public int TimeNum = 0;
///
/// 包庄托管
///
void BaoZhuangTuoGuan()
{
// var seat = GamePack.Info.WhoPlay - 1;
int count = 0;
for (int i = 0; i < GamePack.Info.PlayNum; i++)
{
var pl = this.DeskGameDo.desk[i];
if (pl != null && pl.isDePosit)
{
count++;
}
}
if (count == 0) return; //不需要托管
//GamePack.Info.PlayTuoGauan[seat] = 1;
for (byte i = 0; i < GamePack.Info.PlayNum; i++)
{
var pl = this.DeskGameDo.desk[i];
if (GamePack.Info.BaoZhuang[i] == 0 && pl != null && pl.isDePosit)
{
GamePack.Info.BaoZhuang[i] = 2;
}
}
Debug.Info("包庄托管!GameDo");
GameDo();
}
///
/// 返回黑桃三的下标
///
/// 可以出的牌组合
/// 返回黑桃三的下标
/// false没有黑桃三 true有黑桃三
bool GetHei3Index(List> cards, out int index)
{
index = -1;
try
{
if (cards == null || cards.Count <= 0) return false;
bool isfirstChu = GamePack.Info.PlayNum == 2 ? GamePack.Info.ShenYuCard[0] == GamePack.Info.ShenYuCard[1]
: GamePack.Info.ShenYuCard[0] == GamePack.Info.ShenYuCard[1] && GamePack.Info.ShenYuCard[1] == GamePack.Info.ShenYuCard[2];
if (!isfirstChu) return false; //如果不是第一次出牌, 就不管
for (int i = 0; i < cards.Count; i++)
{
if (cards[i] == null || cards[i].Count <= 0) continue;
if (cards[i][0].Flower == 1 && cards[i][0].GameNum == 3)
{
index = i;
return true;
}
}
return false;
}
catch (Exception e)
{
Debug.Error($"返回黑桃三的下标 msg:{e.Message},code:{e.StackTrace}");
}
return false;
}
///
/// 打牌托管
///
void DaPaiTuoGuan()
{
var seat = GamePack.Info.WhoPlay - 1;
var pl = this.DeskGameDo.desk[seat];
if (pl == null) return; //不需要托管
if (Rule.BiYa)
{
if (pl.outline == 0)
{//玩家没有离线
if (!pl.isDePosit) return; //不需要托管
}
else
{//玩家离线
if (!pl.isDePosit && GamePack.Info.MaxPlayCard.GameNum <= 0) return;
}
}
else
{
if (!pl.isDePosit) return; //不需要托管
}
//GamePack.Info.PlayTuoGauan[seat] = 1; //加这个是为了兼容老客户端
if (GamePack.Info.MaxPlayCard.GameNum <= 0)
{ //托管先出
var tishi = PdkCardAlgorithm.GetTipCard(GamePack.Info.MaxPlayCard,
GamePack.CardPack.Cards[GamePack.Info.WhoPlay - 1].CardInfos.Where(x => x.GameState == 1).ToArray(),
GamePack.Info.MaxPlayCard.Pos == 0 ? null : GamePack.CardPack.Cards[GamePack.Info.MaxPlayCard.Pos - 1].CardInfos,
Rule.AAAIsZhaDan);
var idx = Rule.XiaJiaBaoDan && GamePack.Info.ShenYuCard[GetNextPos(GamePack.Info.WhoPlay) - 1] == 1 ? tishi.Count - 1 : 0;
if (Rule.HeiTao3BiChu && logicMemory.WarCount == 0)
{//如果首局黑桃三首次必出,第一次出牌就必出黑桃三
var h3 = GetHei3Index(tishi, out var idx3);
if (h3 && idx3 >= 0)
{
idx = idx3;
}
}
var payCard = new PlayOutCardPdkF();
payCard.Pos = (byte)GamePack.Info.WhoPlay;
payCard.Type = CardType1.DanZhang;
payCard.GameNum = tishi[idx][0].GameNum;
payCard.Ids = tishi[idx].Select(x => x.ID).ToArray();
Log($"who:{GamePack.Info.WhoPlay}先出 ,托管出的牌:{payCard}");
GamePack.Info.ActivePlayCard = payCard;
}
else
{
var shoupai = GamePack.CardPack.Cards[GamePack.Info.WhoPlay - 1].CardInfos.Where(x => x.GameState == 1).ToArray();
var tishi = PdkCardAlgorithm.GetTipCard(GamePack.Info.MaxPlayCard,
shoupai,
GamePack.Info.MaxPlayCard.Pos == 0 ? null : GamePack.CardPack.Cards[GamePack.Info.MaxPlayCard.Pos - 1].CardInfos,
Rule.AAAIsZhaDan, true);
var payCard = new PlayOutCardPdkF();
payCard.Pos = (byte)GamePack.Info.WhoPlay;
if (tishi == null || tishi.Count <= 0)
{
payCard.Type = CardType1.None;
}
else
{
if (pl.outline == 1 && !pl.isDePosit) return; //玩家离线并且没有到托管时间
payCard.Type = PdkCardAlgorithm.IsZhaDan(tishi[tishi.Count - 1].ToArray(), Rule.AAAIsZhaDan) ? CardType1.ZhaDan : GamePack.Info.MaxPlayCard.Type;
var idx = Rule.XiaJiaBaoDan && GamePack.Info.ShenYuCard[GetNextPos(GamePack.Info.WhoPlay) - 1] == 1 && payCard.Type == CardType1.DanZhang ? 0 : tishi.Count - 1;
payCard.GameNum = tishi[idx][0].GameNum;
payCard.Ids = tishi[idx].Select(x => x.ID).ToArray();
if (payCard.Type == CardType1.FeiJi || payCard.Type == CardType1.SanDai2)
{
int n = (payCard.Ids.Length / 3) * 2;
var chaCard = shoupai.Except(tishi[idx]);
List chupais = new List(16);
chupais.AddRange(tishi[idx]);
chupais.AddRange(chaCard.Reverse().Take(n));
payCard.Ids = chupais.Select(x => x.ID).ToArray();
}
}
Log($"who:{GamePack.Info.WhoPlay}跟牌 pai:{GamePack.Info.MaxPlayCard}托管出的牌:{payCard}");
GamePack.Info.ActivePlayCard = payCard;
}
Debug.Info("打牌托管GameDo!");
GameDo();
}
///
/// 游戏临时加载的初始化
///
public void LoadInit()
{
logicMemory.Init();
TimeNum = 0;
}
}
}