public Hand GetRandomTwoPair(int numCardsDealt, int numCardsInFinalHand) { Ranker ranker = new Ranker(numCardsInFinalHand, false); Hand hand; FullRank fRank; HandCard[] hcsRank; HandCard[] hcsFill; do { TValue pair1Value = (TValue)random.Next(2, 14); TValue pair2Value = (TValue)random.Next(2, 13); if (pair2Value >= pair1Value) { pair2Value = pair2Value.Next(); } Card[] pair1Cards = GetRandomCardsWithValue(pair1Value, 2); Card[] pair2Cards = GetRandomCardsWithValue(pair2Value, 2); Card[] fill = GetRandomCards(numCardsDealt - 4).ToArray(); hand = new Hand(fill.Concat(pair1Cards).Concat(pair2Cards)); ranker.GetFullRank(hand, null, out fRank, out hcsRank, out hcsFill); } while (fRank.SRank > SimpleRank.TwoPair); return(hand); }
private bool isStraightOrStraightFlushN(HandInfo hi, out FullRank fRank, out HandCard[] hcsRank, out HandCard[] hcsFill, bool isFlushRequired, int n) { bool isStraight = false; bool isStraightFlush = false; TValue minVal = TValue.NoValue; // Suppress compiler warning TValue maxVal; IEnumerable <IGrouping <TValue, HandCard> > valueGroups = null; TSuit flushSuit = TSuit.NoSuit; // Note: The loop could be started at Max(hcsPlain.Value) + hi.UnboundCount() for (maxVal = TValue.Ace; maxVal >= (TValue)n; // TValue.Five maxVal = maxVal.Prev()) { minVal = maxVal.Prev(n - 1); valueGroups = hi.CardsPlain .Where(hc => (hc.Value >= minVal && hc.Value <= maxVal) || (minVal == TValue.LowAce && hc.Value == TValue.Ace)) .GroupBy(hc => hc.Value); isStraight = valueGroups.Count() >= n - hi.UnboundCount(); if (isStraight && isFlushRequired) { foreach (TSuit s in Card.Suits) { if (valueGroups.All(grp => grp.Any(hc => hc.Suit == s))) { flushSuit = s; isStraightFlush = true; break; } } } if (isStraight && (isStraightFlush || !isFlushRequired)) { break; } } if (!isStraight || (isFlushRequired && !isStraightFlush)) { setToNull(out fRank, out hcsRank, out hcsFill); return(false); } Func <HandCard, bool> pred = null; if (isFlushRequired) { pred = hc => hc.Suit == flushSuit; } IEnumerable <HandCard> hcsAvail = valueGroups.EnumerableChoice(pred); hcsRank = new HandCard[n]; hcsFill = new HandCard[NumCardsInFinalHand - n]; int index = 0; List <HandCard> hcsUnbound = new List <HandCard>(hi.CardsUnbound); // Need random access for (TValue val = minVal; val <= maxVal; val = val.Next()) { HandCard nextCard = hcsAvail.Where(hc => hc.Value == val).FirstOrDefault(); if (nextCard != null) { hcsRank[index] = nextCard; } else { Debug.Assert(hcsUnbound.Count > 0, "Error: Not enough cards to form straight"); IEnumerable <HandCard> hcDesired = hcsUnbound.Where(hc => hc.Value == val).Take(1); if (hcDesired.Count() > 0) { hcsRank[index] = hcDesired.ElementAt(0); hcsUnbound.Remove(hcsRank[index]); } else { hcsRank[index] = hcsUnbound[0]; hcsUnbound.RemoveAt(0); } hcsRank[index].TamedValue = val; if (isFlushRequired) { hcsRank[index].TamedSuit = flushSuit; } } index++; } fRank = new FullRank( isFlushRequired ? SimpleRank.StraightFlush5 : SimpleRank.Straight5, Enumerable.Range((int)minVal, ((int)maxVal - (int)minVal) + 1) .OrderByDescending(x => x) .Select(x => (TValue)x) .ToArray() ); return(true); }
public static TValue Prev(this TValue val, int n = 1) { return(val.Next(-1 * n)); }