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; } } }