Search code examples
c#enumsicomparableicomparer

IComparer compare value of enum


I am implementing a compare method (IComparer) for the game Manille and I need to compare certain cards (enum values) with each other.

I want to order them in a certain way so that Number 10 is the biggest card and Ace the second biggest.

There is also a certain symbol that is always higher then other cards (for example Hearts)

The problem:

I don't know how to tell that Nummer.Tien is bigger then B, D, H

Also Ace has to be the second highest card, but the algorithm is putting him on the first place.

public class ManilleComparer : IComparer<Kaart>
{
        private Kleur symbol; // the symbol that is higher

        public ManilleComparer(Kleur symbol)
        {
            this.symbol = symbol;
        }

        public int Compare(Kaart x, Kaart y)
        {
            int compareTo = x.Kleur.CompareTo(y.Kleur); //check symbols against each other

            if (compareTo == 0) // if value is 0 they have the same symbol
            {
                compareTo = x.Nummer.CompareTo(y.Nummer); // order them 
                return compareTo;
            }

            return x.Nummer.CompareTo(y.Nummer); // else compare values
        }
}

public enum Nummer { Aas, Twee, Drie, Vier, Vijf, Zes, Zeven, Acht, Negen, Tien, Boer, Dame, Heer } // Ace, Two, Three, Four, Five, Six, Zeven, Eight, Nine, Ten, 11, 12, 13

public enum Kleur { Schoppen, Harten, Klaveren, Ruiten }

I have a Sort methot that sorts all the cards in the correct orde, which words fine:

public int CompareTo(object obj)
        {
            Kaart dezeKaart = this;
            Kaart andereKaart = obj as Kaart;
            int compareTo = dezeKaart.Kleur.CompareTo(andereKaart.Kleur);
            if(compareTo == 0)
            {
                compareTo = dezeKaart.Nummer.CompareTo(andereKaart.Nummer);
                return compareTo;
            }
            return compareTo;
        }

The outcome of this sort method is:

   // ♠A -  ♠2 -  ♠3 -  ♠4 -  ♠5 -  ♠6 -  ♠7 -  ♠8 -  ♠9 - ♠10 -  ♠B -  ♠D -  ♠H
    // ♥A -  ♥2 -  ♥3 -  ♥4 -  ♥5 -  ♥6 -  ♥7 -  ♥8 -  ♥9 - ♥10 -  ♥B -  ♥D -  ♥H
    // ♣A -  ♣2 -  ♣3 -  ♣4 -  ♣5 -  ♣6 -  ♣7 -  ♣8 -  ♣9 - ♣10 -  ♣B -  ♣D -  ♣H
    // ♦A -  ♦2 -  ♦3 -  ♦4 -  ♦5 -  ♦6 -  ♦7 -  ♦8 -  ♦9 - ♦10 -  ♦B -  ♦D -  ♦H

I now want to implement Icompare
to have this as an outcome:

    // ♦7 -  ♦8 -  ♦9 -  ♦B -  ♦D -  ♦H -  ♦A - ♦10
    // ♣7 -  ♣8 -  ♣9 -  ♣B -  ♣D -  ♣H -  ♣A - ♣10
    // ♠7 -  ♠8 -  ♠9 -  ♠B -  ♠D -  ♠H -  ♠A - ♠10
    // ♥7 -  ♥8 -  ♥9 -  ♥B -  ♥D -  ♥H -  ♥A - ♥10

Solution

  • You can do the following:

        public class ManilleComparer : IComparer<Kaart>
                    {
                        public ManilleComparer(){}
    
                        public ManilleComparer(List<Kleur> PrefKleurRank)
                        {
                            KleurRank = PrefKleurRank;
                        }
    
                        public ManilleComparer(Kleur LastColor)
                        {
                            KleurRank.Remove(LastColor);
                            KleurRank.Add(LastColor);
                        }
    
                        private List<Kleur> KleurRank = new List<Kleur>() { Kleur.Ruiten , Kleur.Klaveren, Kleur.Schoppen, Kleur.Harten };
                        private List<Nummer> NummerRank = new List<Nummer>() { Nummer.Twee, Nummer.Drie, Nummer.Vier, Nummer.Vier, Nummer.Zes, Nummer.Zeven,  Nummer.Acht, Nummer.Negen, Nummer.Boer, Nummer.Dame, Nummer.Heer, Nummer.Aas, Nummer.Tien };
    
                        public int Compare(Kaart x, Kaart y)
                        {
                            int compareTo = KleurRank.IndexOf(x.Kleur).CompareTo(KleurRank.IndexOf(y.Kleur)); //check symbols against each other
    
                            if (compareTo == 0) // if value is 0 they have the same symbol
                            {
                                compareTo = NummerRank.IndexOf(x.Nummer).CompareTo(NummerRank.IndexOf(y.Nummer));  
                            }
    
                            return compareTo; 
                        }
                    }
    

    you can also pass the order to the contructor to be more flexible

    This is how to use it:

                    Kaart k1 = new Kaart() { Kleur = Kleur.Ruiten, Nummer = Nummer.Drie };
                    Kaart k2 = new Kaart() { Kleur = Kleur.Harten, Nummer = Nummer.Heer };
                    Kaart k3 = new Kaart() { Kleur = Kleur.Ruiten, Nummer = Nummer.Aas };
    
                    Kaart.ManilleComparer m = new Kaart.ManilleComparer();
    
                    List<Kaart> mylist = new List<Kaart>();
                    mylist.Add(k1);
                    mylist.Add(k2);
                    mylist.Add(k3);
    
                    mylist.Sort(m);
    
                    private List<Kleur> MyKleurRank = new List<Kleur>() { Kleur.Ruiten , Kleur.Klaveren, Kleur.Harten , Kleur.Schoppen};
    
                    Kaart.ManilleComparer m2 = new Kaart.ManilleComparer(MyKleurRank);
    
                    mylist.Sort(m2);