using ObjectModel.Tool; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using GameFix.Poker; using GameMessage.PaoDeKuaiF; using GameFix.PaoDeKuaiF; namespace PdkFriendServer.Logic { public partial class PdkGameMain { /// /// 随机值 /// public readonly Random Random = new Random(unchecked((int)DateTime.UtcNow.Ticks)); /// /// 发牌 /// public void InitCard() { /*1、经典玩法(必压)、--经典玩法(16张玩法):一副牌,去掉大小王、三个2(保留黑桃2)和黑桃 A ,共48张,每人16张 15张玩法(必压)、--15张玩法(有大必压):一副牌,去掉大小王、三个2(保留黑桃2)和三个A(保留黑桃 A ),去掉一个K,共45张,每人15张 关牌(不必压) --一副牌,去掉大小王、三个2(保留黑桃2)和黑桃 A ,共48张,每人16张*/ byte count = 0;//每个人分多少张牌 int del2 = 3; //删除2的张数 int delA = 1;//删除A的张数 int delK = 3;//删除K的张数 TCardInfoPdkF[] allCards = null; //初始化牌库 if (Rule.JingDianWanFa || Rule.GuanPai) { count = 16; delK = 0; allCards = new TCardInfoPdkF[48]; } if (Rule.Zhang15) { delA = 3; delK = 1; count = 15; allCards = new TCardInfoPdkF[45]; } int idx = 0; for (byte i = 1; i <= 52; i++) { PukeTool.ConvertCard(i, out var flower, out var num); if (del2 > 0 && num == 2 && flower != 1) { del2--; continue; } if (delA > 0 && num == 1 && flower != 1) { delA--; continue; } if (delK > 0 && num == 13 && flower != 1) { delK--; continue; } allCards[idx].ID = i; allCards[idx].Flower = (byte)flower; allCards[idx].Num = (byte)num; allCards[idx].GameNum = (byte)(num == 1 ? 14 : num == 2 ? 16 : num); allCards[idx].GameOwer = 0; allCards[idx].Score = 0; allCards[idx].GameState = 1; idx++; } for (byte i = 1; i < GamePack.Info.PlayNum; i++) { PukeTool.ShuffleArray(ref allCards, Random); } idx = 0; //给玩家发牌 int hei3Wei = -1;//黑桃三发牌的位置 if (logicMemory.WarCount == 0 && Rule.HeiTao3BiChu) {//如果是首局而且是每局黑桃三必出,则第一局必须要发黑桃三 hei3Wei = Random.Next(0, GamePack.Info.PlayNum); } if (hei3Wei >= 0) { //要发黑桃3 List cards = allCards.ToList(); for (int i = 0; i < GamePack.Info.PlayNum; i++) { GamePack.CardPack.Cards[i].Init(count); int j = 0; while (j < count) { if (j == 0 && i == hei3Wei) { TCardInfoPdkF temp = cards.Find(x => x.GameNum == 3 && x.Flower == 1); if (temp.ID > 0) { this.GamePack.CardPack.Cards[i].CardInfos[j] = temp; cards.Remove(temp); } else { //如果没有找到,说明黑桃3已经被别人拿走了,就不找了。 this.GamePack.CardPack.Cards[i].CardInfos[j] = cards[0]; cards.RemoveAt(0); } } else { this.GamePack.CardPack.Cards[i].CardInfos[j] = cards[0]; cards.RemoveAt(0); } j++; } GamePack.Info.ShenYuCard[i] = count; } } else { //以前写法 for (int i = 0; i < GamePack.Info.PlayNum; i++) { GamePack.CardPack.Cards[i].Init(count); for (int j = 0; j < count; j++) { this.GamePack.CardPack.Cards[i].CardInfos[j] = allCards[idx++]; } GamePack.Info.ShenYuCard[i] = count; } } for (int i = 0; i < GamePack.Info.PlayNum; i++) { SortWanJiaPaiByGameNum(i + 1); #if DEBUG if (this.DeskGameDo == null) { Log($"-------------{(i + 1)}开始-----------------------------"); for (int j = 0; j < this.GamePack.CardPack.Cards[i].CardInfos.Length; j++) { Log(this.GamePack.CardPack.Cards[i].CardInfos[j].ToString()); } } #endif } } /// /// 排序某个玩家手牌,按游戏中的大小排序 /// /// 玩家位置从1开始 void SortWanJiaPaiByGameNum(int pos) { if (pos <= 0 || pos > GamePack.Info.PlayNum) throw new Exception($"参数错误 pos:{pos}"); pos--; Array.Sort(this.GamePack.CardPack.Cards[pos].CardInfos, (x, y) => (y.GameNum * 10 - y.Flower).CompareTo((x.GameNum * 10 - x.Flower))); } /// /// 设置玩家出牌 /// /// /// void SetCardToOut(int pos, byte[] ids) { if (ids == null || ids.Length <= 0) return; if (pos <= 0 || pos > GamePack.Info.PlayNum) throw new Exception($"参数错误 pos:{pos}"); pos--; GamePack.Info.ShenYuCard[pos] = (byte)(GamePack.Info.ShenYuCard[pos] - ids.Length); foreach (var id in ids) { for (int i = 0; i < this.GamePack.CardPack.Cards[pos].CardInfos.Length; i++) { if (this.GamePack.CardPack.Cards[pos].CardInfos[i].ID == id) { this.GamePack.CardPack.Cards[pos].CardInfos[i].GameState = 0; break; } } } #if DEBUG Log($"---------------------{(pos + 1)}----- shengyu:{GamePack.Info.ShenYuCard[pos]}-------------"); //for (int i = 0; i < this.GamePack.CardPack.Cards[pos].CardInfos.Length; i++) //{ // if (this.GamePack.CardPack.Cards[pos].CardInfos[i].GameState == 0) continue; // Log(this.GamePack.CardPack.Cards[pos].CardInfos[i].ToString()); //} #endif } /// /// 根据牌的绝对Id返回牌的详细信息 /// /// 玩家位置从1开始 /// 牌的Id集合 /// TCardInfoPdkF[] GetCardByIds(int pos, byte[] ids) { if (ids == null || ids.Length <= 0) return null; if (pos <= 0 || pos > GamePack.Info.PlayNum) return null; pos--; return PokerLogic.GetCardByIds(GamePack.CardPack.Cards[pos].CardInfos, ids); } /// /// 计算玩家炸弹个数 /// /// 玩家位置,从0开始 /// byte CalcPlayBombRule(int pos) { if (pos < 0 || pos >= GamePack.Info.PlayNum) return 0; Dictionary dic = new Dictionary(); foreach (var item in GamePack.CardPack.Cards[pos].CardInfos) { if (dic.ContainsKey(item.GameNum)) { dic[item.GameNum]++; } else { dic[item.GameNum] = 1; } } byte result = 0; foreach (var item in dic) { if (item.Value <= 2) continue; if (Rule.AAAIsZhaDan && item.Key == 14 && item.Value == 3) { result++; continue; } if (item.Value == 4) { result++; } } return result; } /// /// 检测玩家的飞机,如果有4连以上的飞机就需要换牌 /// /// /// void CheckFeiJi() { try { int pos = -1; //有4连飞机的位置 List feiji = null; for (int j = 0; j < GamePack.Info.PlayNum; j++) { feiji = GetFeiJiCount(GamePack.CardPack.Cards[j].CardInfos); if (feiji != null && feiji.Count > 3) { pos = j; Log($"飞机数量:{string.Join(",", feiji)},飞机位置:{pos + 1},房号:{this.DeskGameDo.desk.deskinfo.roomNum}", MrWu.Debug.DebugLevel.Warning); break; } } if (pos < 0) return; for (int i = 0; i < GamePack.Info.PlayNum; i++) { if (i != pos) { int idx = -1; for (int j = 0; j < GamePack.CardPack.Cards[pos].CardInfos.Length; j++) { if (GamePack.CardPack.Cards[pos].CardInfos[j].GameNum == feiji[2]) { idx = j; break; } } if (idx < 0) { Log($"没有找到4连飞机的下标日:{idx}", MrWu.Debug.DebugLevel.Warning); return; } for (int i3 = 0; i3 < GamePack.CardPack.Cards[i].CardInfos.Length - 1; i3++) { //交换其中一张牌 TCardInfoPdkF temp = GamePack.CardPack.Cards[i].CardInfos[i3]; if (feiji.IndexOf(temp.GameNum) >= 0) continue; //换的牌不能是飞机的牌,要不容易重复和换出新的炸弹 Log($"换牌信息:{temp.GameNum}", MrWu.Debug.DebugLevel.Warning); GamePack.CardPack.Cards[i].CardInfos[i3] = GamePack.CardPack.Cards[pos].CardInfos[idx]; GamePack.CardPack.Cards[pos].CardInfos[idx] = temp; for (int i2 = 0; i2 < GamePack.Info.PlayNum; i2++) { SortWanJiaPaiByGameNum(i2 + 1); } return; } } } } catch (Exception e) { Log($"CheckFeiJi msg:{e.Message}, code:{e.StackTrace}", MrWu.Debug.DebugLevel.Error); } } /// /// 获取一个玩家的飞机牌型 /// /// 玩家手里的牌 /// 玩家的飞机集合 public static List GetFeiJiCount(TCardInfoPdkF[] selectCards) { if (selectCards == null || selectCards.Length < 6) return null; List list = new List(); foreach (var item in selectCards) { var t = list.Find(x => x.x == item.GameNum); if (t != null) { t.y++; } else { list.Add(new PokerLogic.XY { x = item.GameNum, y = 1 }); } } int num = list.Count(x => x.y >= 3); if (num < 2) return null; list = list.Where(x => x.y >= 3).ToList(); List fj = new List(); for (int i = 0; i < list.Count - 1; i++) { if (list[i].x - 1 == list[i + 1].x) { if (!fj.Contains(list[i].x)) { fj.Add(list[i].x); } if (!fj.Contains(list[i + 1].x)) { fj.Add(list[i + 1].x); } } } return fj; } } }