# VBForums CodeBank > Codebank - Game Programming >  [VB.NET] Sorting Array of Custom Class objects

## wossname

Lets say you are writing a card game and you need to be able to sort a player's cards into numerical and suit order.

You have written a PlayingCard class, and you have to find a way of sorting by these 2 criteria.

The .Net (OOP) way is to make that class implement the IComparable interface.  This simply adds a function that decides if one class instance is 'greater then, less than or equal to' another instance of the same class.  Write your sorting rules into this function body and that is.  You don't have to worry about moving items into the right places in the array, or type conversion problems, or anything like that.  The Array.Sort() function calls your implementation of the IComparable interface and communicates directly with it without your intervention.

Here is a nice example I just cooked up.
(The important parts are highlighted in red).




```
Module Module1

	Sub Main()

		Dim Deck() As PlayingCard = New PlayingCard(99) {}
		Dim i As Integer
		Dim r As Random = New Random

		For i = 0 To 99		  'randomize the array
			Deck(i) = New PlayingCard(r.Next(PlayingCard.CARDVALUE.Ace, PlayingCard.CARDVALUE.King + 1), r.Next(PlayingCard.CARDSUIT.Spades, PlayingCard.CARDSUIT.Diamonds + 1))
		Next i

		PlayingCard.AcesHigh = True
		Array.Sort(Deck)

		For i = 0 To 99
			Console.WriteLine(Deck(i))
		Next i

		Console.ReadLine()

	End Sub

End Module

Public Class PlayingCard
	Implements IComparable	'IMPORTANT

#Region "Game Specific"
#Region "Enums"
	Public Enum CARDVALUE
		Ace = 1
		Two = 2
		Three = 3
		Four = 4
		Five = 5
		Six = 6
		Seven = 7
		Eight = 8
		Nine = 9
		Ten = 10
		Jack = 11
		Queen = 12
		King = 13
		HighAce = 14
	End Enum
	Public Enum CARDSUIT
		Spades = 0
		Hearts = 1
		Clubs = 2
		Diamonds = 3
	End Enum
#End Region
#Region "Shared"
	Public Shared AcesHigh As Boolean = False
#End Region
#Region "Member Data"
	Private _Value As CARDVALUE = CARDVALUE.Ace
	Private _Suit As CARDSUIT = CARDSUIT.Spades
#End Region

	Public Property Value() As CARDVALUE
		Get
			Return _Value
		End Get
		Set(ByVal RHS As CARDVALUE)
			If RHS = CARDVALUE.HighAce Then Throw New ArgumentException("Cannot set Value to HighAce directly, set Value to Ace and set AcesHigh variable to True")
			_Value = RHS
		End Set
	End Property
	Public Property Suit() As CARDSUIT
		Get
			Return _Suit
		End Get
		Set(ByVal RHS As CARDSUIT)
			_Suit = RHS
		End Set
	End Property
	Public ReadOnly Property IsHighAce() As Boolean
		Get
			Return (_Value = CARDVALUE.Ace) And AcesHigh
		End Get
	End Property
	Public ReadOnly Property IsRoyalty() As Boolean
		Get
			Return (_Value >= CARDVALUE.Jack) And (_Value <= CARDVALUE.King)
		End Get
	End Property
	Public Overrides Function ToString() As String

		Dim s As String

		Select Case _Value
			Case CARDVALUE.Ace
				s = "Ace of "
			Case CARDVALUE.Two
				s = "Two of "
			Case CARDVALUE.Three
				s = "Three of "
			Case CARDVALUE.Four
				s = "Four of "
			Case CARDVALUE.Five
				s = "Five of "
			Case CARDVALUE.Six
				s = "Six of "
			Case CARDVALUE.Seven
				s = "Seven of "
			Case CARDVALUE.Eight
				s = "Eight of "
			Case CARDVALUE.Nine
				s = "Nine of "
			Case CARDVALUE.Ten
				s = "Ten of "
			Case CARDVALUE.Jack
				s = "Jack of "
			Case CARDVALUE.Queen
				s = "Queen of "
			Case CARDVALUE.King
				s = "King of "
		End Select

		Select Case _Suit
			Case CARDSUIT.Spades
				s &= "Spades"
			Case CARDSUIT.Hearts
				s &= "Hearts"
			Case CARDSUIT.Clubs
				s &= "Clubs"
			Case CARDSUIT.Diamonds
				s &= "Diamonds"
		End Select

		Return s

	End Function

#End Region

	Public Sub New(ByVal itsValue As CARDVALUE, ByVal itsSuit As CARDSUIT)
		Value = itsValue
		Suit = itsSuit
	End Sub

	Public Function CompareTo(ByVal obj As Object) As Integer Implements System.IComparable.CompareTo

		'where the Sorting logic is run

		'Basically says: "if ME greater than the obj card then return 1, if equal return 0 and if less than, return -1"

		If Not TypeOf obj Is PlayingCard Then Throw New ArgumentException 'make sure obj is a card before continuing

		Dim temp As PlayingCard = CType(obj, PlayingCard)
		Dim vObj As CARDVALUE = temp.Value
		Dim vMe As CARDVALUE = _Value
		Dim s As CARDSUIT = temp.Suit

		If _Suit < s Then		  'suits take precedence
			Return -1
		ElseIf _Suit > s Then
			Return 1
		Else
			If AcesHigh Then		  'some games require aces to have a value of 14 rather than 1, hence "Aces High"
				If vObj = CARDVALUE.Ace Then vObj = CARDVALUE.HighAce
				If vMe = CARDVALUE.Ace Then vMe = CARDVALUE.HighAce
			End If
			'if suite are the same, check the card numbers...
			If vMe < vObj Then
				Return -1
			ElseIf vMe > vObj Then
				Return 1
			Else
				Return 0				   'cards are identical (if you are using more than 1 deck deck of cards in a program)
			End If
			End If

	End Function

End Class
```

Copy this code into a console app and run it.  It also demonstrates the overriding of the Tostring() function.

The output looks like this...

----------


## WonkoTheSane

That works fine!

Nice work wossname.

----------


## plenderj

Or how about this  :Smilie: 
http://www.irishdev.com/blogs/kieran...11/16/285.aspx

----------


## Hack

Moved to Games CodeBank

----------

