private bool isKindN( HandInfo hi, out FullRank fRank, out HandCard[] hcsRank, out HandCard[] hcsFill, int n, int maxFillCount = int.MaxValue) { Contract.Requires(n >= 2 && n <= 5, String.Format("Error: Unrecognized n-of-a-kind: {0:d}", n)); bool hasKindN = (!hi.HasPlainCards() && hi.UnboundCount() >= n) || (hi.ValueGram.Values.Max() >= n - hi.UnboundCount()); if (!hasKindN) { setToNull(out fRank, out hcsRank, out hcsFill); return false; } TValue kindVal; int numChosen; HandCard[] hcsChosen; var plainValues = hi.ValueGram.Keys; if (plainValues.Count() == 0) { kindVal = TValue.Ace; numChosen = 0; hcsChosen = new HandCard[0]; } else { kindVal = plainValues.Where(val => hi.ValueGram[val] >= n - hi.UnboundCount()).Max(); HandCard[] hcsAvail = hi.CardsPlain.Where(hc => hc.Value == kindVal).ToArray(); numChosen = Math.Min(n, hcsAvail.Count()); hcsChosen = hcsAvail.Take(numChosen).ToArray(); } int numTamed = Math.Min(n - numChosen, hi.UnboundCount()); HandCard[] hcsTamed = hi.CardsUnbound.Take(numTamed).ToArray(); foreach (HandCard hc in hcsTamed) { hc.TamedValue = kindVal; } List<HandCard> fillTamed; List<HandCard> fillPlain; Util.TakeFill(Math.Min(NumCardsInFinalHand - n, maxFillCount), hi.CardsUnbound.Except(hcsTamed).OrderByDescending(hc => hc.Value), out fillTamed, hi.CardsPlain.Except(hcsChosen).OrderByDescending(hc => hc.Value), out fillPlain); foreach (HandCard hc in fillTamed) { hc.TamedValue = TValue.Ace; } SimpleRank sRank; switch (n) { case 5: sRank = SimpleRank.Kind5; break; case 4: sRank = SimpleRank.Kind4; break; case 3: sRank = SimpleRank.Kind3; break; case 2: sRank = SimpleRank.Kind2; break; default: throw new ArgumentException("n"); } fRank = new FullRank(sRank, Util.SingletonEnumerable(kindVal) .Concat(fillTamed.Select(hc => hc.TamedValue)) .Concat(fillPlain.Select(hc => hc.Value)) ); hcsRank = hcsChosen.Concat(hcsTamed).ToArray(); hcsFill = fillTamed.Concat(fillPlain).ToArray(); return true; }
private bool isKindN( HandInfo hi, out FullRank fRank, out HandCard[] hcsRank, out HandCard[] hcsFill, int n, int maxFillCount = int.MaxValue) { Contract.Requires(n >= 2 && n <= 5, String.Format("Error: Unrecognized n-of-a-kind: {0:d}", n)); bool hasKindN = (!hi.HasPlainCards() && hi.UnboundCount() >= n) || (hi.ValueGram.Values.Max() >= n - hi.UnboundCount()); if (!hasKindN) { setToNull(out fRank, out hcsRank, out hcsFill); return(false); } TValue kindVal; int numChosen; HandCard[] hcsChosen; var plainValues = hi.ValueGram.Keys; if (plainValues.Count() == 0) { kindVal = TValue.Ace; numChosen = 0; hcsChosen = new HandCard[0]; } else { kindVal = plainValues.Where(val => hi.ValueGram[val] >= n - hi.UnboundCount()).Max(); HandCard[] hcsAvail = hi.CardsPlain.Where(hc => hc.Value == kindVal).ToArray(); numChosen = Math.Min(n, hcsAvail.Count()); hcsChosen = hcsAvail.Take(numChosen).ToArray(); } int numTamed = Math.Min(n - numChosen, hi.UnboundCount()); HandCard[] hcsTamed = hi.CardsUnbound.Take(numTamed).ToArray(); foreach (HandCard hc in hcsTamed) { hc.TamedValue = kindVal; } List <HandCard> fillTamed; List <HandCard> fillPlain; Util.TakeFill(Math.Min(NumCardsInFinalHand - n, maxFillCount), hi.CardsUnbound.Except(hcsTamed).OrderByDescending(hc => hc.Value), out fillTamed, hi.CardsPlain.Except(hcsChosen).OrderByDescending(hc => hc.Value), out fillPlain); foreach (HandCard hc in fillTamed) { hc.TamedValue = TValue.Ace; } SimpleRank sRank; switch (n) { case 5: sRank = SimpleRank.Kind5; break; case 4: sRank = SimpleRank.Kind4; break; case 3: sRank = SimpleRank.Kind3; break; case 2: sRank = SimpleRank.Kind2; break; default: throw new ArgumentException("n"); } fRank = new FullRank(sRank, Util.SingletonEnumerable(kindVal) .Concat(fillTamed.Select(hc => hc.TamedValue)) .Concat(fillPlain.Select(hc => hc.Value)) ); hcsRank = hcsChosen.Concat(hcsTamed).ToArray(); hcsFill = fillTamed.Concat(fillPlain).ToArray(); return(true); }
private bool isFlushN(HandInfo hi, out FullRank fRank, out HandCard[] hcsRank, out HandCard[] hcsFill, int n) { Contract.Requires(n >= 4 && n <= 5, String.Format("Error: Unrecognized flush size: {0:d}", n)); bool hasFlushN = (!hi.HasPlainCards() && hi.UnboundCount() >= n) || (hi.SuitGram.Values.Max() >= n - hi.UnboundCount()); if (!hasFlushN) { setToNull(out fRank, out hcsRank, out hcsFill); return false; } TSuit flushSuit; int numChosen = 0; IEnumerable<HandCard> hcsChosen; if (!hi.HasPlainCards()) { flushSuit = Card.Suits.First(); // Any suit will do numChosen = 0; hcsChosen = new HandCard[0]; } else { var sg = hi.SuitGram; // Note: suits can only have Length > 1 if the hand has >= 2 * numCardsInFullHand cards. TSuit[] candidateSuits = sg.Keys.Where(s => sg[s] >= n - hi.UnboundCount()).ToArray(); if (candidateSuits.Length == 1) { flushSuit = candidateSuits[0]; } else { // Determine which suit is best var cardSeqEnum = candidateSuits .Select(s => hi.CardsPlain .Where(hc => hc.Suit == s) .OrderByDescending(hc => hc.Value)); var cardSeqOrd = cardSeqEnum .OrderByDescending(hcs => (IEnumerable<HandCard>) hcs, new EnumerableComparer<HandCard>()); var cardSeq = cardSeqOrd.First(); flushSuit = cardSeq.First().Suit; } HandCard[] hcsAvail = hi.CardsPlain.Where(hc => hc.Suit == flushSuit).ToArray(); numChosen = Math.Min(n, hcsAvail.Count()); hcsChosen = hcsAvail.OrderByDescending(hc => hc.Value).Take(numChosen); } HandCard[] hcsTamed = hi.CardsUnbound.Take(n - numChosen).ToArray(); foreach (HandCard hcs in hcsTamed) { hcs.TamedValue = TValue.Ace; hcs.TamedSuit = flushSuit; } List<HandCard> fillTamed; List<HandCard> fillPlain; Util.TakeFill(NumCardsInFinalHand - n, hi.CardsUnbound.Except(hcsTamed), out fillTamed, hi.CardsPlain.Except(hcsChosen), out fillPlain); foreach (HandCard hcs in fillTamed) { hcs.TamedValue = TValue.Ace; } ; SimpleRank sRank; switch (n) { case 4: sRank = SimpleRank.Flush4; break; case 5: sRank = SimpleRank.Flush5; break; default: throw new ApplicationException(String.Format( String.Format("Error: Unrecognized flush size: {0:d}", n))); }; fRank = new FullRank(sRank, hcsTamed.Select(hc => hc.TamedValue) .Concat(hcsChosen.Select(hc => hc.Value).OrderByDescending(v => v)) .Concat(fillTamed.Select(hc => hc.TamedValue)) .Concat(fillPlain.Select(hc => hc.Value).OrderByDescending(v => v))); hcsRank = hcsChosen.Concat(hcsTamed).ToArray(); hcsFill = fillTamed.Concat(fillPlain).ToArray(); return true; }
private bool isFlushN(HandInfo hi, out FullRank fRank, out HandCard[] hcsRank, out HandCard[] hcsFill, int n) { Contract.Requires(n >= 4 && n <= 5, String.Format("Error: Unrecognized flush size: {0:d}", n)); bool hasFlushN = (!hi.HasPlainCards() && hi.UnboundCount() >= n) || (hi.SuitGram.Values.Max() >= n - hi.UnboundCount()); if (!hasFlushN) { setToNull(out fRank, out hcsRank, out hcsFill); return(false); } TSuit flushSuit; int numChosen = 0; IEnumerable <HandCard> hcsChosen; if (!hi.HasPlainCards()) { flushSuit = Card.Suits.First(); // Any suit will do numChosen = 0; hcsChosen = new HandCard[0]; } else { var sg = hi.SuitGram; // Note: suits can only have Length > 1 if the hand has >= 2 * numCardsInFullHand cards. TSuit[] candidateSuits = sg.Keys.Where(s => sg[s] >= n - hi.UnboundCount()).ToArray(); if (candidateSuits.Length == 1) { flushSuit = candidateSuits[0]; } else { // Determine which suit is best var cardSeqEnum = candidateSuits .Select(s => hi.CardsPlain .Where(hc => hc.Suit == s) .OrderByDescending(hc => hc.Value)); var cardSeqOrd = cardSeqEnum .OrderByDescending(hcs => (IEnumerable <HandCard>)hcs, new EnumerableComparer <HandCard>()); var cardSeq = cardSeqOrd.First(); flushSuit = cardSeq.First().Suit; } HandCard[] hcsAvail = hi.CardsPlain.Where(hc => hc.Suit == flushSuit).ToArray(); numChosen = Math.Min(n, hcsAvail.Count()); hcsChosen = hcsAvail.OrderByDescending(hc => hc.Value).Take(numChosen); } HandCard[] hcsTamed = hi.CardsUnbound.Take(n - numChosen).ToArray(); foreach (HandCard hcs in hcsTamed) { hcs.TamedValue = TValue.Ace; hcs.TamedSuit = flushSuit; } List <HandCard> fillTamed; List <HandCard> fillPlain; Util.TakeFill(NumCardsInFinalHand - n, hi.CardsUnbound.Except(hcsTamed), out fillTamed, hi.CardsPlain.Except(hcsChosen), out fillPlain); foreach (HandCard hcs in fillTamed) { hcs.TamedValue = TValue.Ace; } ; SimpleRank sRank; switch (n) { case 4: sRank = SimpleRank.Flush4; break; case 5: sRank = SimpleRank.Flush5; break; default: throw new ApplicationException(String.Format( String.Format("Error: Unrecognized flush size: {0:d}", n))); } ; fRank = new FullRank(sRank, hcsTamed.Select(hc => hc.TamedValue) .Concat(hcsChosen.Select(hc => hc.Value).OrderByDescending(v => v)) .Concat(fillTamed.Select(hc => hc.TamedValue)) .Concat(fillPlain.Select(hc => hc.Value).OrderByDescending(v => v))); hcsRank = hcsChosen.Concat(hcsTamed).ToArray(); hcsFill = fillTamed.Concat(fillPlain).ToArray(); return(true); }