Generating all 5 card poker hands

前端 未结 11 660
再見小時候
再見小時候 2020-12-23 09:53

This problem sounds simple at first glance, but turns out to be a lot more complicated than it seems. It\'s got me stumped for the moment.

There are 52c5 = 2,598,960

11条回答
  •  清酒与你
    2020-12-23 10:34

    Initial input:

    H 0 0 0 0 0 0 0 0 0 0 0 0 0
    C 1 0 0 0 0 0 0 0 0 0 0 0 0
    D 1 0 0 0 0 0 0 0 0 0 0 0 0
    S 1 1 0 0 0 0 0 0 0 0 0 0 0
    + A 2 3 4 5 6 7 8 9 T J Q K
    

    Step 1: for each rank greater than or equal the highest rank used, set all suits in that rank to 0. you can get away with only checking higher cards because lower combinations will be checked by the lower starting points.

    H 0 0 0 0 0 0 0 0 0 0 0 0 0
    C 1 0 0 0 0 0 0 0 0 0 0 0 0
    D 1 0 0 0 0 0 0 0 0 0 0 0 0
    S 1 0 0 0 0 0 0 0 0 0 0 0 0
    + A 2 3 4 5 6 7 8 9 T J Q K
    

    Step 2: Collapse to distinct rows

    0 0 0 0 0 0 0 0 0 0 0 0 0
    1 0 0 0 0 0 0 0 0 0 0 0 0
    A 2 3 4 5 6 7 8 9 T J Q K
    

    Step 3: Climb back up determining first suit that match each distinct row, and choose the suits which match the distinct rows (identified by a *)

    H 0 * 0 0 0 0 0 0 0 0 0 0 0
    C 1 0 0 0 0 0 0 0 0 0 0 0 0
    D 1 * 0 0 0 0 0 0 0 0 0 0 0
    S 1 1 0 0 0 0 0 0 0 0 0 0 0
    + A 2 3 4 5 6 7 8 9 T J Q K
    

    Now showing the repeat for rank 3

    H 0 0 0 0 0 0 0 0 0 0 0 0 0
    C 1 0 0 0 0 0 0 0 0 0 0 0 0
    D 1 0 0 0 0 0 0 0 0 0 0 0 0
    S 1 1 0 0 0 0 0 0 0 0 0 0 0
    + A 2 3 4 5 6 7 8 9 T J Q K
    
    0 0 0 0 0 0 0 0 0 0 0 0 0
    1 0 0 0 0 0 0 0 0 0 0 0 0
    1 1 0 0 0 0 0 0 0 0 0 0 0
    A 2 3 4 5 6 7 8 9 T J Q K
    
    H 0 0 * 0 0 0 0 0 0 0 0 0 0
    C 1 0 0 0 0 0 0 0 0 0 0 0 0
    D 1 0 * 0 0 0 0 0 0 0 0 0 0
    S 1 1 * 0 0 0 0 0 0 0 0 0 0
    + A 2 3 4 5 6 7 8 9 T J Q K
    

    Step 4: Once there are 5 cells set to 1, increment the total possible suit abstracted hands count by 1 and recurse up.

    The total number of suit abstracted hands possible is 134,459. This is the code I wrote to test it out:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    
    namespace ConsoleApplication20
    {
        struct Card
        {
            public int Suit { get; set; }
            public int Rank { get; set; }
        }
        
        class Program
        {
            static int ranks = 13;
            static int suits = 4;
            static int cardsInHand = 5;
    
            static void Main(string[] args)
            {
                List cards = new List();
                //cards.Add(new Card() { Rank = 0, Suit = 0 });
                int numHands = GenerateAllHands(cards);
        
                Console.WriteLine(numHands);
                Console.ReadLine();
            }
      
            static int GenerateAllHands(List cards)
            {
                if (cards.Count == cardsInHand) return 1;
        
                List possibleNextCards = GetPossibleNextCards(cards);
        
                int numSubHands = 0;
        
                foreach (Card card in possibleNextCards)
                {
                    List possibleNextHand = cards.ToList(); // copy list
                    possibleNextHand.Add(card);
                    numSubHands += GenerateAllHands(possibleNextHand);
                }
        
                return numSubHands;
            }
        
            static List GetPossibleNextCards(List hand)
            {
                int maxRank = hand.Max(x => x.Rank);
                
                List result = new List();
        
                // only use ranks >= max
                for (int rank = maxRank; rank < ranks; rank++)
                {
                    List suits = GetPossibleSuitsForRank(hand, rank);
                    var possibleNextCards = suits.Select(x => new Card { Rank = rank, Suit = x });
                    result.AddRange(possibleNextCards);
                }
        
                return result;
            }
        
            static List GetPossibleSuitsForRank(List hand, int rank)
            {
                int maxSuit = hand.Max(x => x.Suit);
        
                // select number of ranks of different suits
                int[][] card = GetArray(hand, rank);
        
                for (int i = 0; i < suits; i++)
                {
                    card[i][rank] = 0;
                }
        
                int[][] handRep = GetArray(hand, rank);
        
                // get distinct rank sets, then find which ranks they correspond to
                IEnumerable distincts = card.Distinct(new IntArrayComparer());
        
                List possibleSuits = new List();
        
                foreach (int[] row in distincts)
                {
                    for (int i = 0; i < suits; i++)
                    {
                        if (IntArrayComparer.Compare(row, handRep[i]))
                        {
                            possibleSuits.Add(i);
                            break;
                        }
                    }
                }
        
                return possibleSuits;
            }
        
            class IntArrayComparer : IEqualityComparer
            {
                #region IEqualityComparer Members
        
                public static bool Compare(int[] x, int[] y)
                {
                    for (int i = 0; i < x.Length; i++)
                    {
                        if (x[i] != y[i]) return false;
                    }
        
                    return true;
                }
        
                public bool Equals(int[] x, int[] y)
                {
                    return Compare(x, y);
                }
        
                public int GetHashCode(int[] obj)
                {
                    return 0;
                }
    
                #endregion
            }
    
            static int[][] GetArray(List hand, int rank)
            {
                int[][] cards = new int[suits][];
                for (int i = 0; i < suits; i++)
                {
                    cards[i] = new int[ranks];
                }
    
                foreach (Card card in hand)
                {
                    cards[card.Suit][card.Rank] = 1;
                }
        
                return cards;
            }
        }
    }
    

    Hopefully it is broken up enough to be easily understandable.

提交回复
热议问题