using System.Collections.Generic;
using System.Linq;
using GameFix.Poker;
using GameMessage;
using GameMessage.PaoDeKuaiF;
namespace GameFix.PaoDeKuaiF
{
///
/// 跑得快牌运算逻辑
///
public class PdkCardAlgorithm
{
///
/// 获取提示的牌
///
/// 当前出的牌
/// 玩家在手里的牌,没有出下去的牌
/// 当前出牌人的手牌
/// 3A是不是炸弹,默认不是
/// 只要一种提示 true是 false不是
///
public static List> GetTipCardByBtn(PlayOutCardPdkF outCard, TCardInfoPdkF[] shoupai,
TCardInfoPdkF[] maxShouPai, bool aaaIsZhaDan = false, bool isOne = false)
{
if (shoupai == null || shoupai.Length <= 0) return null;
List> result = new List>();
if (outCard.GameNum <= 0)
{
//如果是自己先出的话, 就从尾部一张一张提示过去
for (int i = shoupai.Length - 1; i >= 0; i--)
{
List chu = new List();
chu.Add(shoupai[i]);
result.Add(chu);
}
return result;
}
switch (outCard.Type)
{
case CardType1.DanZhang:
var danzhangs = PokerLogic.GetDanZhang(outCard, shoupai);
if (danzhangs == null || danzhangs.Count <= 0)
{
danzhangs = PokerLogic.GetDanZhang(outCard, shoupai, true);
}
if (danzhangs != null && danzhangs.Count > 0)
{
danzhangs.Sort((x, y) => x.GameNum.CompareTo(y.GameNum));
foreach (var item in danzhangs)
{
List chu = new List { item };
result.Add(chu);
}
}
break;
case CardType1.DuiZi:
result = PokerLogic.GetCountCard(outCard, shoupai, 2);
if (result == null || result.Count <= 0)
{
result = PokerLogic.GetCountCard(outCard, shoupai, 2, true);
}
if (result != null)
{
result.Sort((x, y) => x[0].GameNum.CompareTo(y[0].GameNum));
}
break;
case CardType1.SanDai2:
result = PokerLogic.GetCountCard(outCard, shoupai, 3, true);
if (result != null) result.Sort((x, y) => x[0].GameNum.CompareTo(y[0].GameNum));
break;
case CardType1.ShunZi:
result = PokerLogic.GetShunZi(outCard, shoupai);
if (result != null) result.Sort((x, y) => x[0].GameNum.CompareTo(y[0].GameNum));
break;
case CardType1.LianDui:
result = PokerLogic.GetLianCount(outCard, shoupai, 2, null);
if (result != null) result.Sort((x, y) => x[0].GameNum.CompareTo(y[0].GameNum));
break;
case CardType1.FeiJi:
result = PokerLogic.GetLianCount(outCard, shoupai, 3, maxShouPai);
if (result != null) result.Sort((x, y) => x[0].GameNum.CompareTo(y[0].GameNum));
break;
case CardType1.ZhaDan:
PokerLogic.GetPlayZhaDan(shoupai, out var cards);
if (cards.Count > 4)
{
int c = cards.Count / 4;
for (int i = 0; i < c; i++)
{
var tx = cards.Skip(i * 4).Take(4).ToList();
if (tx != null && tx[0].GameNum > outCard.GameNum)
{
result.Add(tx);
}
}
}
else
{
if (cards != null && cards.Count > 0 && cards[0].GameNum > outCard.GameNum)
{
result.Add(cards);
}
}
break;
}
if (isOne && result != null && result.Count > 0)
{
//只要一种提示
}
else
{
if (result == null) result = new List>();
if (aaaIsZhaDan)
{
var aaa = GetAAAZhaDan(shoupai);
if (aaa != null && aaa.Count >= 3)
{
result.Add(aaa);
}
}
if (outCard.Type != CardType1.ZhaDan)
{
PokerLogic.GetPlayZhaDan(shoupai, out var cards);
if (cards != null && cards.Count > 0)
{
int c = cards.Count / 4;
if (c <= 0)
{
result.Add(cards);
}
else
{
for (int i = 0; i < c; i++)
{
result.Add(cards.Skip(i * 4).Take(4).ToList());
}
}
}
}
}
return result;
}
///
/// 获取提示的牌
///
/// 当前出的牌
/// 玩家在手里的牌,没有出下去的牌
/// 当前出牌人的手牌
/// 3A是不是炸弹,默认不是
/// 只要一种提示 true是 false不是
///
public static List> GetTipCard(PlayOutCardPdkF outCard, TCardInfoPdkF[] shoupai, TCardInfoPdkF[] maxShouPai,
bool aaaIsZhaDan = false, bool isOne = false)
{
if (shoupai == null || shoupai.Length <= 0) return null;
List> result = new List>();
if (outCard.GameNum <= 0)
{
//如果是自己先出的话, 就从尾部一张一张提示过去
for (int i = shoupai.Length - 1; i >= 0; i--)
{
List chu = new List();
chu.Add(shoupai[i]);
result.Add(chu);
}
return result;
}
switch (outCard.Type)
{
//飞机带翅膀、炸弹,四带三、四带二
case CardType1.DanZhang:
var danzhangs = shoupai.Where(x => x.GameNum > outCard.GameNum);
if (danzhangs.Count() > 0)
{
foreach (var item in danzhangs)
{
List chu = new List();
chu.Add(item);
result.Add(chu);
}
}
break;
case CardType1.DuiZi:
result = PokerLogic.GetCountCard(outCard, shoupai, 2, true);
break;
case CardType1.SanDai2:
result = PokerLogic.GetCountCard(outCard, shoupai, 3, true);
break;
case CardType1.ShunZi:
result = PokerLogic.GetShunZi(outCard, shoupai);
break;
case CardType1.LianDui:
result = PokerLogic.GetLianCount(outCard, shoupai, 2, null);
break;
case CardType1.FeiJi:
result = PokerLogic.GetLianCount(outCard, shoupai, 3, maxShouPai);
break;
case CardType1.ZhaDan:
PokerLogic.GetPlayZhaDan(shoupai, out var cards);
if (cards != null && cards.Count > 0 && cards[0].GameNum > outCard.GameNum)
{
result.Add(cards);
}
break;
}
if (result == null) result = new List>();
if (isOne && result != null && result.Count > 0)
{
//只要一种提示
}
else
{
if (aaaIsZhaDan)
{
var aaa = GetAAAZhaDan(shoupai);
if (aaa != null && aaa.Count >= 3)
{
result.Add(aaa);
}
}
if (outCard.Type != CardType1.ZhaDan)
{
PokerLogic.GetPlayZhaDan(shoupai, out var cards);
if (cards != null && cards.Count > 0)
{
result.Add(cards);
}
}
}
return result;
}
///
/// 判断是否是炸弹
///
///
///
///
///
public static bool IsZhaDan(TCardInfoPdkF[] cards, bool aaaIsZhaDan, bool isCheckPaiCount = true)
{
if (cards == null || cards.Length < 3 || cards.Length > 4) return false;
if (aaaIsZhaDan && cards.Length == 3)
{
return Is3A(cards);
}
if (cards.Length == 4)
{
return IsZhaDan(cards, isCheckPaiCount);
}
return false;
}
///
/// 检查玩家是否有比出的牌更大的牌
///
/// 玩家出的牌
/// 自己的手牌-在手里的牌,并且是排序过的。
/// 出牌人的手牌
/// 3A是不是炸弹,默认不是
/// true有比玩家大的牌 false没有
public static bool CheckHaveBigger(PlayOutCardPdkF outCard, TCardInfoPdkF[] shouPai, TCardInfoPdkF[] maxShouPai,
bool aaaIsZhaDan = false)
{
if (shouPai == null || shouPai.Length <= 0) return false;
List> cs = null;
List cards = null;
switch (outCard.Type)
{
case CardType1.DanZhang:
if (shouPai.Where(x => x.GameNum > outCard.GameNum).Count() > 0)
{
return true;
}
break;
case CardType1.DuiZi:
cs = PokerLogic.GetCountCard(outCard, shouPai, 2, true);
if (cs != null && cs.Count > 0)
{
return true;
}
break;
case CardType1.SanDai2:
cs = PokerLogic.GetCountCard(outCard, shouPai, 3, true);
if (cs != null && cs.Count > 0)
{
return true;
}
break;
case CardType1.ShunZi:
cs = PokerLogic.GetShunZi(outCard, shouPai);
if (cs != null && cs.Count > 0)
{
return true;
}
break;
case CardType1.LianDui:
cs = PokerLogic.GetLianCount(outCard, shouPai, 2, null);
if (cs != null && cs.Count > 0)
{
return true;
}
break;
case CardType1.FeiJi:
cs = PokerLogic.GetLianCount(outCard, shouPai, 3, maxShouPai);
if (cs != null && cs.Count > 0)
{
return true;
}
break;
case CardType1.ZhaDan:
var b = PokerLogic.GetPlayZhaDan(shouPai, out cards);
if (!b) return false;
foreach (var item in cards)
{
if (item.GameNum > outCard.GameNum) return true;
}
break;
}
if (aaaIsZhaDan)
{
var aaa = GetAAAZhaDan(shouPai);
if (aaa != null && aaa.Count >= 3)
{
return true;
}
}
if (outCard.Type != CardType1.ZhaDan)
{
return PokerLogic.GetPlayZhaDan(shouPai, out cards);
}
return false;
}
///
/// 通过选中的牌返回出下去牌的类型 否则选中的牌就不能出下去
/// 一般客户端用
///
/// 选中的牌
/// 玩家手牌,不包含已经出下去的牌
/// 规则玩法
/// 返回出牌内容
/// true可以出牌 false不能出牌
public static bool GetOutCard(TCardInfoPdkF[] selectCards, TCardInfoPdkF[] shouPai, PdkRule wangfa,
out PlayOutCardPdkF paycard)
{
paycard = new PlayOutCardPdkF();
if (selectCards == null || selectCards.Length <= 0 || shouPai == null || shouPai.Length <= 0) return false;
var chaCard = shouPai.Except(selectCards); //获取差集,如果个数大于0说明牌的张数是够的,如果是0,说明牌不够
PokerLogic.SortCardByGameNum(ref selectCards);
var bugou = chaCard.Count() <= 0;
byte gameNum = 0;
if (selectCards.Length == 1)
{
//单张可以出
paycard.Ids = new byte[] { selectCards[0].ID };
paycard.GameNum = selectCards[0].GameNum;
paycard.Type = CardType1.DanZhang;
return true;
}
else if (selectCards.Length == 2)
{
//对子
if (PokerLogic.IsDuiZi(selectCards))
{
paycard.Ids = selectCards.Select(x => x.ID).ToArray();
paycard.GameNum = selectCards[0].GameNum;
paycard.Type = CardType1.DuiZi;
return true;
}
}
else if (selectCards.Length == 3)
{
if (wangfa.AAAIsZhaDan && Is3A(selectCards)) //3A是炸弹
{
paycard.Ids = selectCards.Select(x => x.ID).ToArray();
paycard.GameNum = selectCards[0].GameNum;
paycard.Type = CardType1.ZhaDan;
return true;
}
else
{
bool xt = selectCards[0].GameNum == selectCards[1].GameNum &&
selectCards[2].GameNum == selectCards[1].GameNum;
if (xt && bugou)
{
paycard.GameNum = selectCards[0].GameNum;
paycard.Type = CardType1.SanDai2;
paycard.Ids = selectCards.Select(x => x.ID).ToArray();
return true;
}
}
}
else
{
if (IsZhaDan(selectCards)) //炸弹
{
paycard.GameNum = selectCards[0].GameNum; //因为该值会根据大小排序
paycard.Type = CardType1.ZhaDan;
paycard.Ids = selectCards.Select(x => x.ID).ToArray();
return true;
}
if (wangfa.SiDai2 && IsSiDai2(selectCards, !bugou, out gameNum))
{
//四带二
paycard.GameNum = gameNum;
paycard.Type = CardType1.SiDai2;
paycard.Ids = selectCards.Select(x => x.ID).ToArray();
return true;
}
if (wangfa.SiDai3 && IsSiDai3(selectCards, !bugou, out gameNum))
{
//四带二
paycard.GameNum = gameNum;
paycard.Type = CardType1.SiDai3;
paycard.Ids = selectCards.Select(x => x.ID).ToArray();
return true;
}
if (PokerLogic.IsShunzi(selectCards))
{
//顺子
paycard.GameNum = selectCards[0].GameNum;
paycard.Type = CardType1.ShunZi;
paycard.Ids = selectCards.Select(x => x.ID).ToArray();
return true;
}
if (PokerLogic.IsLianDui(selectCards)) //连对
{
paycard.GameNum = selectCards[0].GameNum;
paycard.Type = CardType1.LianDui;
paycard.Ids = selectCards.Select(x => x.ID).ToArray();
return true;
}
if (PokerLogic.IsSanDaiEr(selectCards, bugou, out gameNum)) //三带二、
{
paycard.GameNum = gameNum;
paycard.Type = CardType1.SanDai2;
paycard.Ids = selectCards.Select(x => x.ID).ToArray();
return true;
}
if (PokerLogic.IsFeiJi(selectCards, bugou, true, out gameNum)) //飞机带翅膀
{
paycard.GameNum = gameNum;
paycard.Type = CardType1.FeiJi;
paycard.Ids = selectCards.Select(x => x.ID).ToArray();
return true;
}
}
return false;
}
///
/// 是否是3张A
///
///
/// true是 false不是
static bool Is3A(TCardInfoPdkF[] cards)
{
if (cards == null || cards.Length != 3) return false;
return cards[0].GameNum == 14 && cards[1].GameNum == 14 && cards[2].GameNum == 14;
}
///
/// 获取3A炸弹
///
/// 玩家手里没有打下去的牌
///
static List GetAAAZhaDan(TCardInfoPdkF[] cards)
{
if (cards == null || cards.Length < 3) return null;
List result = new List();
for (int i = 0; i < cards.Length; i++)
{
if (cards[i].GameNum == 14)
{
result.Add(cards[i]);
}
}
if (result.Count >= 3)
{
return result;
}
return null;
}
static bool IsSiDai3(TCardInfoPdkF[] selectCards, bool isPaiBuGou, out byte gameNum)
{
gameNum = 0;
if (selectCards == null || selectCards.Length < 5 || selectCards.Length > 7) return false;
if (isPaiBuGou && selectCards.Length != 7) return false;
var b = PokerLogic.GetPlayZhaDan(selectCards, out var cards);
if (!b) return b;
gameNum = cards[0].GameNum;
return true;
}
///
/// 是否是四带二
///
///
/// true牌够,false牌不够
/// true是 false不是
#pragma warning disable CS1573 // 参数在 XML 注释中没有匹配的 param 标记(但其他参数有)
static bool IsSiDai2(TCardInfoPdkF[] selectCards, bool isPaiBuGou, out byte gameNum)
#pragma warning restore CS1573 // 参数在 XML 注释中没有匹配的 param 标记(但其他参数有)
{
gameNum = 0;
if (selectCards == null || selectCards.Length < 5 || selectCards.Length > 6) return false;
if (isPaiBuGou && selectCards.Length != 6) return false;
var b = PokerLogic.GetPlayZhaDan(selectCards, out var cards);
if (!b) return b;
gameNum = cards[0].GameNum;
return true;
}
///
/// 判断是否是炸弹
///
///
/// 是否要校验牌的张数对不对
///
static bool IsZhaDan(TCardInfoPdkF[] selectCards, bool isCheckPaiCount = true)
{
if (selectCards == null || selectCards.Length < 4) return false;
int gameNum = 0;
foreach (var item in selectCards)
{
if (gameNum == 0)
{
gameNum = item.GameNum;
continue;
}
if (gameNum != item.GameNum)
{
//炸弹的牌不是一样的牌
return false;
}
}
var b = PokerLogic.GetPlayZhaDan(selectCards, out var cards);
if (!b) return b;
if (isCheckPaiCount)
{
//校验返回的炸弹牌数量和传入的牌数量是不是一样多
return selectCards.Length == cards.Count;
}
return true;
}
///
/// 判断是否有炸弹
///
///
/// AAA是否是炸弹 true是 false不是
///
public static bool IsHaveBomb(TCardInfoPdkF[] selectCards, bool aaaIsBomb)
{
if (selectCards == null || selectCards.Length < 3) return false;
if (!aaaIsBomb && selectCards.Length < 4) return false;
Dictionary dic = new Dictionary();
for (int i = 0; i < selectCards.Length; i++)
{
if (dic.ContainsKey(selectCards[i].GameNum))
{
dic[selectCards[i].GameNum]++;
}
else
{
dic[selectCards[i].GameNum] = 1;
}
}
foreach (var item in dic)
{
if (aaaIsBomb && item.Key == 14 && item.Value == 3) return true;
if (item.Value >= 4) return true;
}
return false;
}
}
}