private bool doCommonDiscardClick() { pokerface.MsgCardHand prevCardHand = null; int specialCardID = -1; if (CurrentAllowPlayerReAction != null) { prevCardHand = CurrentAllowPlayerReAction.prevActionHand; if (CurrentAllowPlayerReAction.timeoutInSeconds > 255) { specialCardID = (int)pokerface.CardID.R2H; } } else if (CurrentAllowPlayerAction != null) { if (CurrentAllowPlayerAction.timeoutInSeconds > 255) { specialCardID = (int)pokerface.CardID.R3H; } } var discardedList = new List <int>(); if (!DiscardWnd.ShowDialog(discardedList, prevCardHand, specialCardID, this)) { return(false); } OnTakeActionDiscardTile(discardedList); return(true); }
/// <summary> /// 判断当前的手牌是否大于上一手牌 /// </summary> /// <param name="prevCardHand">上一手牌</param> /// <param name="current">当前的手牌</param> /// <returns>如果大于则返回true,其他各种情形都会返回false</returns> public static bool agariGreatThan(pokerface.MsgCardHand prevCardHand, pokerface.MsgCardHand current) { // 如果当前的是炸弹 if (current.cardHandType == (int)pokerface.CardHandType.Bomb) { // 上一手不是炸弹 if (prevCardHand.cardHandType != (int)pokerface.CardHandType.Bomb) { return(true); } // 上一手也是炸弹,则比较炸弹牌的大小,大丰关张不存在多于4个牌的炸弹 return(current.cards[0] / 4 > prevCardHand.cards[0] / 4); } // 如果上一手牌是炸弹 if (prevCardHand.cardHandType == (int)pokerface.CardHandType.Bomb) { return(false); } // 必须类型匹配 if (prevCardHand.cardHandType != current.cardHandType) { return(false); } // 张数匹配 if (prevCardHand.cards.Count != current.cards.Count) { return(false); } // 单张时,2是最大的 if (prevCardHand.cardHandType == (int)pokerface.CardHandType.Single) { if (prevCardHand.cards[0] / 4 == 0) { return(false); } if (current.cards[0] / 4 == 0) { return(true); } } // 现在只比较最大牌的大小 return(current.cards[0] / 4 > prevCardHand.cards[0] / 4); }
/// <summary> /// 根据牌列表,构造MsgCardHand对象 /// </summary> /// <param name="hai">手牌列表</param> /// <returns>如果牌列表是一个有效的组合,则返回一个pokerface.MsgCardHand对象,否则返回null</returns> public static pokerface.MsgCardHand agariConvertMsgCardHand(int[] hai) { var key = calcKey(hai); if (!agariTable.ContainsKey(key)) { return(null); } var agari = agariTable[key]; var ct = (pokerface.CardHandType)(agari & 0xff); var msgCardhand = new pokerface.MsgCardHand(); msgCardhand.cardHandType = (int)ct; // 排序,让大的牌在前面 Array.Sort(hai, (x, y) => { return(y - x); }); // 如果是顺子类型则需要检查 int flushLength = ((int)agari >> 16) & 0xff; if (flushLength > 0) { if (!agariFlushVerify(ct, flushLength)) { return(null); } } var cardsNew = new List <int>(); switch (ct) { case pokerface.CardHandType.TripletPair: case pokerface.CardHandType.Triplet2X2Pair: // 确保3张在前面,对子在后面 for (var i = 0; i < hai.Length; i++) { var h = hai[i]; if (slots[h / 4] == 3) { cardsNew.Add(h); } } for (var i = 0; i < hai.Length; i++) { var h = hai[i]; if (slots[h / 4] != 3) { cardsNew.Add(h); } } break; default: cardsNew.AddRange(hai); break; } msgCardhand.cards.AddRange(cardsNew); if (ct == pokerface.CardHandType.Triplet) { if (msgCardhand.cards[0] / 4 == (int)pokerface.CardID.R3H / 4) { // 如果是3个3,而且不包含红桃3,则把牌组改为炸弹,而不是三张 var foundR3H = false; foreach (var c in msgCardhand.cards) { if (c == (int)pokerface.CardID.R3H) { foundR3H = true; break; } } if (!foundR3H) { msgCardhand.cardHandType = (int)pokerface.CardHandType.Bomb; } } else if (msgCardhand.cards[0] / 4 == (int)pokerface.CardID.AH / 4) { // 3张A也是炸弹 msgCardhand.cardHandType = (int)pokerface.CardHandType.Bomb; } } return(msgCardhand); }
/// <summary> /// 寻找比上一手牌大的所有有效牌组 /// 这个主要用于自动打牌以及给出提示之类 /// </summary> /// <param name="prev">上一手牌</param> /// <param name="hands">当前手上所有的牌</param> /// <returns>返回一个牌组列表,如果没有有效牌组,该列表长度为0</returns> public static List <pokerface.MsgCardHand> FindGreatThanCardHand(pokerface.MsgCardHand prev, List <int> hands, int specialCardID) { var prevCT = (pokerface.CardHandType)prev.cardHandType; bool isBomb = false; List <pokerface.MsgCardHand> tt = null; if (specialCardID >= 0) { tt = new List <MsgCardHand>(); var cardHand = new MsgCardHand(); cardHand.cardHandType = (int)pokerface.CardHandType.Single; cardHand.cards.AddRange(extractCardByRank(hands, 0, 1)); tt.Add(cardHand); return(tt); } switch (prevCT) { case pokerface.CardHandType.Bomb: tt = FindBombGreatThan(prev, hands); isBomb = true; break; case pokerface.CardHandType.Flush: tt = FindFlushGreatThan(prev, hands); break; case pokerface.CardHandType.Single: tt = FindSingleGreatThan(prev, hands); break; case pokerface.CardHandType.Pair: tt = FindPairGreatThan(prev, hands); break; case pokerface.CardHandType.Pair2X: tt = FindPair2XGreatThan(prev, hands); break; case pokerface.CardHandType.Triplet: tt = FindTripletGreatThan(prev, hands); break; case pokerface.CardHandType.Triplet2X: tt = FindTriplet2XGreatThan(prev, hands); break; case pokerface.CardHandType.Triplet2X2Pair: tt = FindTriplet2X2PairGreatThan(prev, hands); break; case pokerface.CardHandType.TripletPair: tt = FindTripletPairGreatThan(prev, hands); break; } if (!isBomb) { var tt2 = FindBomb(hands); tt.AddRange(tt2); } return(tt); }
public static bool ShowDialog(List <int> tileDiscarded, pokerface.MsgCardHand prevCardHand, int specialCardID, TileStackWnd owner) { var tiles2Discarded = owner.TilesHandList; tileDiscarded.Clear(); var x = new DiscardWnd(); x.SetOwner(owner); x.BtnExtra.Visibility = Visibility.Hidden; x.BtnExtraXX.Visibility = Visibility.Hidden; x.SetReadyHandTips(tiles2Discarded); x.prevCardHand = prevCardHand; x.specialCardID = specialCardID; if (prevCardHand != null) { var currents = AgariIndex.FindGreatThanCardHand(prevCardHand, tiles2Discarded, specialCardID); if (null == currents || currents.Count == 0) { MessageBox.Show("oh shit, a huge bug"); throw new System.Exception("huge bug"); } if (currents.Count > 1) { x.BtnExtra.Visibility = Visibility.Visible; x.BtnExtra.Content = "下一个提示"; } var current = currents[0]; x.SelectedTiles.AddRange(current.cards); foreach (var c in current.cards) { x.HandTiles.Remove(c); } x.discardAbleTips = currents; x.discardAbleTipsIndex = 0; x.Hand2UI(); x.Selected2UI(); } else { var current = AgariIndex.SearchLongestDiscardCardHand(tiles2Discarded, specialCardID); x.SelectedTiles.AddRange(current.cards); foreach (var c in current.cards) { x.HandTiles.Remove(c); } x.Hand2UI(); x.Selected2UI(); } var result = x.ShowDialog(); if (result == null || !result.Value) { // snip return(false); } tileDiscarded.AddRange(x.SelectedTiles); return(true); }