// Arrange cards , 7 pick 5 , Main Algorithm public CardCombinationData GetBestCardCombination(CCardData [] sources) { CardCombinationData result = new CardCombinationData(); List <CCardData> newSet = new List <CCardData> (); foreach (CCardData data in sources) { newSet.Add(data); } foreach (CCardData data in HandCards) { newSet.Add(data); } newSet = SortList(false, newSet); // run best pattern match algorithm bool isFlush = false; bool isStraight = false; bool isFourOfaKind = false; // Straight check int startIndex_continuous = 0; isStraight = StraightCheck(newSet, out startIndex_continuous); // the same card special cehck method int [] valueCounter = new int[16]; // zero fields for (int i = 0; i < valueCounter.Length; ++i) { valueCounter [i] = 0; } foreach (CCardData card in newSet) { valueCounter [card.Value]++; } // check each value counter // check Four of a Kind , Three of a kind , and pair count int valueIndex = 0; int arrayIndex = -1; int fourOfaKindIndex = 0; List <int> ThreeOfaKindIndexList = new List <int> (); List <int> PairIndexList = new List <int> (); List <int> newSetValueList = new List <int> (); foreach (CCardData card in newSet) { newSetValueList.Add(card.Value); } foreach (int count in valueCounter) { arrayIndex = newSetValueList.IndexOf(valueIndex); if (count == 4) { isFourOfaKind = true; fourOfaKindIndex = arrayIndex; } if (count == 3) { ThreeOfaKindIndexList.Add(arrayIndex); } if (count == 2) { PairIndexList.Add(arrayIndex); } valueIndex++; } // Flush Check CardType flushType = FlushTypeCheck(newSet); isFlush = flushType != CardType.Undefine; // ------------------------------------------------------------------------------------- // default set as High Card (Zitch) result.type = E_CardCombinationType.HighCard; // one pair check if (PairIndexList.Count == 1) { result.type = E_CardCombinationType.OnePair; } // two pair check if (PairIndexList.Count >= 2) { result.type = E_CardCombinationType.TwoPair; } // three of kind check if (ThreeOfaKindIndexList.Count == 1) { result.type = E_CardCombinationType.ThreeOfAKind; } // Straight check if (isStraight) { result.type = E_CardCombinationType.Straight; } // Flush check if (isFlush) { result.type = E_CardCombinationType.Flush; } // Full house check , situation 1 if (ThreeOfaKindIndexList.Count == 2) { result.type = E_CardCombinationType.FullHouse; } // Full house check , situation 2 if (ThreeOfaKindIndexList.Count == 1 && PairIndexList.Count >= 1) { result.type = E_CardCombinationType.FullHouse; } // Four of a kind check if (isFourOfaKind) { result.type = E_CardCombinationType.FourOfaKind; } // pick card List <CCardData> pickedCardList = new List <CCardData> (); Queue <CCardData> valueSetQueue = new Queue <CCardData>(); // need reverse once , for the right order of the pair ( small -> big => big -> small ) PairIndexList.Reverse(); // very low chance to get two ThreeOfaKind set , still need Reverse if (ThreeOfaKindIndexList.Count >= 2) { ThreeOfaKindIndexList.Reverse(); } int pair1Index = -1; int pair2Index = -1; switch (result.type) { case E_CardCombinationType.Straight: for (int i = startIndex_continuous; i < startIndex_continuous + MaxHandCardCount; ++i) { pickedCardList.Add(newSet [i]); } // check flush again after pick ( check hand card only ) if (flushType != CardType.Undefine) { for (int i = startIndex_continuous; i < startIndex_continuous + MaxHandCardCount; ++i) { if (newSet [i].Type == flushType) { result.type = E_CardCombinationType.StraigthFlush; } } } // Royal straigth flush check if (result.type == E_CardCombinationType.StraigthFlush) { if (newSet [startIndex_continuous].Value == ACE_value) { result.type = E_CardCombinationType.RoyalStraigthFlush; } } break; case E_CardCombinationType.FourOfaKind: pickedCardList.Add(newSet [fourOfaKindIndex]); pickedCardList.Add(newSet [fourOfaKindIndex + 1]); pickedCardList.Add(newSet [fourOfaKindIndex + 2]); pickedCardList.Add(newSet [fourOfaKindIndex + 3]); foreach (CCardData card in newSet) { if (card.Value != newSet [fourOfaKindIndex].Value) { valueSetQueue.Enqueue(card); } } pickedCardList.Add(valueSetQueue.Dequeue()); break; case E_CardCombinationType.FullHouse: int threeOfaKindIndex = ThreeOfaKindIndexList [0]; int pairIndex = -1; if (PairIndexList.Count > 0) { pairIndex = PairIndexList [0]; } else { pairIndex = ThreeOfaKindIndexList [1]; } pickedCardList.Add(newSet [threeOfaKindIndex]); pickedCardList.Add(newSet [threeOfaKindIndex + 1]); pickedCardList.Add(newSet [threeOfaKindIndex + 2]); pickedCardList.Add(newSet [pairIndex]); pickedCardList.Add(newSet [pairIndex + 1]); break; case E_CardCombinationType.Flush: List <CCardData> flushList = new List <CCardData> (); foreach (CCardData card in newSet) { if (card.Type == flushType) { flushList.Add(card); } } // check Straight again in flush list int startIndex_flush = 0; if (StraightCheck(flushList, out startIndex_flush)) { for (int i = startIndex_flush; i < startIndex_flush + MaxHandCardCount; ++i) { pickedCardList.Add(flushList [i]); } if (pickedCardList [startIndex_flush].Value == ACE_value) { result.type = E_CardCombinationType.RoyalStraigthFlush; } else { // straigth flush check result.type = E_CardCombinationType.StraigthFlush; } } else { // flush , add five card in pick list for (int i = 0; i < MaxHandCardCount; ++i) { pickedCardList.Add(flushList [i]); } } break; case E_CardCombinationType.ThreeOfAKind: int startIndex = ThreeOfaKindIndexList [0]; pickedCardList.Add(newSet [startIndex]); pickedCardList.Add(newSet [startIndex + 1]); pickedCardList.Add(newSet [startIndex + 2]); foreach (CCardData card in newSet) { if (card.Value != newSet [startIndex].Value) { valueSetQueue.Enqueue(card); } } pickedCardList.Add(valueSetQueue.Dequeue()); pickedCardList.Add(valueSetQueue.Dequeue()); break; case E_CardCombinationType.TwoPair: pair1Index = PairIndexList [0]; pair2Index = PairIndexList [1]; pickedCardList.Add(newSet [pair1Index]); pickedCardList.Add(newSet [pair1Index + 1]); pickedCardList.Add(newSet [pair2Index]); pickedCardList.Add(newSet [pair2Index + 1]); foreach (CCardData card in newSet) { if (card.Value != newSet [pair1Index].Value && card.Value != newSet [pair2Index].Value) { valueSetQueue.Enqueue(card); } } pickedCardList.Add(valueSetQueue.Dequeue()); break; case E_CardCombinationType.OnePair: pair1Index = PairIndexList [0]; pickedCardList.Add(newSet [pair1Index]); pickedCardList.Add(newSet [pair1Index + 1]); foreach (CCardData card in newSet) { if (card.Value != newSet [pair1Index].Value) { valueSetQueue.Enqueue(card); } } pickedCardList.Add(valueSetQueue.Dequeue()); pickedCardList.Add(valueSetQueue.Dequeue()); pickedCardList.Add(valueSetQueue.Dequeue()); break; case E_CardCombinationType.HighCard: for (int i = 0; i < MaxHandCardCount; i++) { pickedCardList.Add(newSet [i]); } break; default: break; } if (pickedCardList.Count == MaxHandCardCount) { result.SetData(result.type, pickedCardList.ToArray()); for (int i = 0; i < MaxHandCardCount; i++) { CurrentBestCardList[i].SetData(pickedCardList [i]); } CurrentBestCardCombination = result; TextBestCardForm.text = result.type.GetDescription(); return(result); } else { // something error Debug.LogWarning("GetBestCardCombination : pickedCardList count not match MaxHandCardCount ! "); return(null); } }
// 7 pick 5 , Main Algorithm public CardCombinationData GetBestCardCombination(CCardData [] sources) { CardCombinationData result = new CardCombinationData(); List <CCardData> newSet = new List <CCardData> (); foreach (CCardData data in sources) { newSet.Add(data); } foreach (CCardData data in HandCards) { newSet.Add(data); } // newSet.Sort (CardComparer); newSet = SortList(false, newSet); // run best pattern match algorithm bool isFlush = false; bool isStraight = false; bool isFourOfaKind = false; bool isAceLead = false; // Check first card is ACE or not isAceLead = newSet [0].Value == ACE_value; // Straight check int maxContinuousCount = 0; int continuousCounter = 0; int startIndex_continuous = 0; bool hasStartIndex_continuous = false; int [] subValueArray = new int [newSet.Count - 1]; for (int i = 0; i < newSet.Count - 1; ++i) { subValueArray [i] = newSet [i].Value - newSet [i + 1].Value; if (subValueArray [i] == 1) { continuousCounter++; if (hasStartIndex_continuous == false) { if (continuousCounter >= maxContinuousCount) { startIndex_continuous = i; hasStartIndex_continuous = true; } } } else { continuousCounter = 0; hasStartIndex_continuous = false; } // save max counter if (continuousCounter > maxContinuousCount) { maxContinuousCount = continuousCounter; } } if (maxContinuousCount >= 4) { isStraight = true; } // the same card special cehck method int [] valueCounter = new int[16]; foreach (CCardData card in newSet) { valueCounter [card.Value]++; } // check each value counter // check Four of a Kind , Three of a kind , and pair count int valueIndex = 0; int arrayIndex = -1; int fourOfaKindIndex = 0; List <int> ThreeOfaKindIndexList = new List <int> (); List <int> PairIndexList = new List <int> (); List <int> newSetValueList = new List <int> (); foreach (CCardData card in newSet) { newSetValueList.Add(card.Value); } foreach (int count in valueCounter) { if (count == 4) { isFourOfaKind = true; arrayIndex = newSetValueList.IndexOf(valueIndex); fourOfaKindIndex = arrayIndex; } if (count == 3) { arrayIndex = newSetValueList.IndexOf(valueIndex); ThreeOfaKindIndexList.Add(arrayIndex); } if (count == 2) { arrayIndex = newSetValueList.IndexOf(valueIndex); PairIndexList.Add(arrayIndex); } valueIndex++; } // Flush Check int spadeCount = 0; int heartCount = 0; int diamondCount = 0; int cludCount = 0; CardType flushType = CardType.Undefine; foreach (CCardData card in newSet) { if (card.Type == CardType.Spade) { spadeCount++; } if (card.Type == CardType.Heart) { heartCount++; } if (card.Type == CardType.Diamond) { diamondCount++; } if (card.Type == CardType.Club) { cludCount++; } } if (spadeCount >= MaxHandCardCount) { flushType = CardType.Spade; } if (heartCount >= MaxHandCardCount) { flushType = CardType.Heart; } if (diamondCount >= MaxHandCardCount) { flushType = CardType.Diamond; } if (cludCount >= MaxHandCardCount) { flushType = CardType.Club; } if (flushType != CardType.Undefine) { isFlush = true; } // ------------------------------------------------------------------------------------- // default set as High Card (Zitch) result.type = E_CardCombinationType.HighCard; // one pair check if (PairIndexList.Count == 1) { result.type = E_CardCombinationType.OnePair; } // two pair check if (PairIndexList.Count >= 2) { result.type = E_CardCombinationType.TwoPair; } // three of kind check if (ThreeOfaKindIndexList.Count == 1) { result.type = E_CardCombinationType.ThreeOfAKind; } // Straight check if (isStraight) { result.type = E_CardCombinationType.Straight; } // Flush check if (isFlush) { result.type = E_CardCombinationType.Flush; } // Full house check , situation 1 if (ThreeOfaKindIndexList.Count == 2) { result.type = E_CardCombinationType.FullHouse; } // Full house check , situation 2 if (ThreeOfaKindIndexList.Count == 1 && PairIndexList.Count >= 1) { result.type = E_CardCombinationType.FullHouse; } // Four of a kind check if (isFourOfaKind) { result.type = E_CardCombinationType.FourOfaKind; } if (isStraight && isFlush) { // Royal straigth flush check if (isAceLead) { result.type = E_CardCombinationType.RoyalStraigthFlush; } else { // straigth flush check result.type = E_CardCombinationType.StraigthFlush; } } // pick card CCardData[] pickedCardValue = new CCardData [MaxHandCardCount]; List <CCardData> pickedCardList = new List <CCardData> (); Queue <CCardData> valueSetQueue = new Queue <CCardData>(); // need reverse once , for the right order of the pair ( small -> big => big -> small ) PairIndexList.Reverse(); // very low chance to get two ThreeOfaKind set , still need Reverse if (ThreeOfaKindIndexList.Count >= 2) { ThreeOfaKindIndexList.Reverse(); } int pair1Index = -1; int pair2Index = -1; switch (result.type) { case E_CardCombinationType.RoyalStraigthFlush: case E_CardCombinationType.StraigthFlush: case E_CardCombinationType.Straight: for (int i = startIndex_continuous; i < startIndex_continuous + MaxHandCardCount; ++i) { pickedCardValue [i - startIndex_continuous] = newSet [i]; } break; case E_CardCombinationType.FourOfaKind: pickedCardList.Add(newSet [fourOfaKindIndex]); pickedCardList.Add(newSet [fourOfaKindIndex + 1]); pickedCardList.Add(newSet [fourOfaKindIndex + 2]); pickedCardList.Add(newSet [fourOfaKindIndex + 3]); foreach (CCardData card in newSet) { if (card.Value != newSet [fourOfaKindIndex].Value) { valueSetQueue.Enqueue(card); } } pickedCardList.Add(valueSetQueue.Dequeue()); break; case E_CardCombinationType.FullHouse: int threeOfaKindIndex = ThreeOfaKindIndexList [0]; int pairIndex = -1; if (PairIndexList.Count > 0) { pairIndex = PairIndexList [0]; } else { pairIndex = ThreeOfaKindIndexList [1]; } pickedCardList.Add(newSet [threeOfaKindIndex]); pickedCardList.Add(newSet [threeOfaKindIndex + 1]); pickedCardList.Add(newSet [threeOfaKindIndex + 2]); pickedCardList.Add(newSet [pairIndex]); pickedCardList.Add(newSet [pairIndex + 1]); break; case E_CardCombinationType.Flush: int pickedCardCount = 0; foreach (CCardData card in newSet) { if (pickedCardCount < MaxHandCardCount) { if (card.Type == flushType) { pickedCardValue [pickedCardCount] = card; pickedCardCount++; } } } break; case E_CardCombinationType.ThreeOfAKind: int startIndex = ThreeOfaKindIndexList [0]; pickedCardList.Add(newSet [startIndex]); pickedCardList.Add(newSet [startIndex + 1]); pickedCardList.Add(newSet [startIndex + 2]); foreach (CCardData card in newSet) { if (card.Value != newSet [startIndex].Value) { valueSetQueue.Enqueue(card); } } pickedCardList.Add(valueSetQueue.Dequeue()); pickedCardList.Add(valueSetQueue.Dequeue()); break; case E_CardCombinationType.TwoPair: pair1Index = PairIndexList [0]; pair2Index = PairIndexList [1]; pickedCardList.Add(newSet [pair1Index]); pickedCardList.Add(newSet [pair1Index + 1]); pickedCardList.Add(newSet [pair2Index]); pickedCardList.Add(newSet [pair2Index + 1]); foreach (CCardData card in newSet) { if (card.Value != newSet [pair1Index].Value && card.Value != newSet [pair2Index].Value) { valueSetQueue.Enqueue(card); } } pickedCardList.Add(valueSetQueue.Dequeue()); break; case E_CardCombinationType.OnePair: pair1Index = PairIndexList [0]; pickedCardList.Add(newSet [pair1Index]); pickedCardList.Add(newSet [pair1Index + 1]); foreach (CCardData card in newSet) { if (card.Value != newSet [pair1Index].Value) { valueSetQueue.Enqueue(card); } } pickedCardList.Add(valueSetQueue.Dequeue()); pickedCardList.Add(valueSetQueue.Dequeue()); pickedCardList.Add(valueSetQueue.Dequeue()); break; case E_CardCombinationType.HighCard: for (int i = 0; i < MaxHandCardCount; i++) { pickedCardList.Add(newSet [i]); } break; default: break; } if (pickedCardList.Count > 0) { pickedCardValue = pickedCardList.ToArray(); } result.SetData(result.type, pickedCardValue); for (int i = 0; i < MaxHandCardCount; i++) { CurrentBestCardList[i].SetData(pickedCardValue [i]); } CurrentBestCardCombination = result; TextBestCardForm.text = result.type.GetDescription(); return(result); }