Search code examples
c#gethashcode

GetHashCode for a pair of playing cards C#


I have a playing card class with the GetHashCode method implemented as follows:

public override int GetHashCode()
{
   return (int)rank * 4 + (int)suit;
}

I now want to design a GetHashCode method that works for a 2 card hand/pair of cards. I thought something like this should work:

public override int GetHashCode()
{
    return (card1.GetHashCode() * 53) + card2.GetHashCode();
}

However, I would like the hashcode to be equal irrespective of the order of the cards. e.g. if card1 = Ace of Spades, card2 = King of Clubs the hashcode should be equal to that when card1 = King of Clubs, card2 = Ace of Spades. I'm now thinking perhaps I could order the cards before applying my function but wondered if anybody can suggest a nice simple approach to this. Thanks

EDIT: Would this work?

        public override int GetHashCode()
        {
            if(card1.GetHashCode() > card2.GetHashCode())
            {
                return (card1.GetHashCode() * 53) + card2.GetHashCode();
            }
            return (card2.GetHashCode() * 53) + card1.GetHashCode();
        }

Solution

  • If you're using .NET Core/Standard 2.1 or later, the HashCode struct provides some nice helpers to avoid custom calculation code, which is discouraged.

    Example leveraging HashCode.Combine() for this use case:

    public class Card
    {
        public Card(int suit, int rank)
        {
            Suit = suit;
            Rank = rank;
        }
    
        public int Suit { get; set; }
    
        public int Rank { get; set; }
    
        public override int GetHashCode() => HashCode.Combine(Suit, Rank);
    }
    
    public class Hand
    {
        public IList<Card> Cards { get; set; }
    
        public Hand(IList<Card> cards)
        {
            Cards = cards;
        }
    
        public override int GetHashCode()
        {
            var hash = new HashCode();
            foreach (var card in Cards)
            {
                hash.Add(card);
            }
    
            return hash.ToHashCode();
        }
    }