Ejemplo n.º 1
0
        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;
        }
Ejemplo n.º 2
0
        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);
        }
Ejemplo n.º 3
0
        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;
        }
Ejemplo n.º 4
0
        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);
        }