Results 1 to 4 of 4
  1. #1

    Thread Starter
    type Woss is new Grumpy; wossname's Avatar
    Join Date
    Aug 2002

    [VB.NET] Sorting Array of Custom Class objects

    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
    		For i = 0 To 99
    		Next i
    	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
    			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
    			Return _Suit
    		End Get
    		Set(ByVal RHS As CARDSUIT)
    			_Suit = RHS
    		End Set
    	End Property
    	Public ReadOnly Property IsHighAce() As Boolean
    			Return (_Value = CARDVALUE.Ace) And AcesHigh
    		End Get
    	End Property
    	Public ReadOnly Property IsRoyalty() As Boolean
    			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
    			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
    				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...
    I don't live here any more.

  2. #2
    Banned WonkoTheSane's Avatar
    Join Date
    Nov 2004
    Jersey, nr France
    That works fine!

    Nice work wossname.

  3. #3
    Banned plenderj's Avatar
    Join Date
    Jan 2001
    Dublin, Ireland

  4. #4
    Super Moderator Hack's Avatar
    Join Date
    Aug 2001
    Searching for mendhak

    Re: [VB.NET] Sorting Array of Custom Class objects

    Moved to Games CodeBank
    Please use [Code]your code goes in here[/Code] tags when posting code.
    When you have received an answer to your question, please mark it as resolved using the Thread Tools menu.
    Before posting your question, did you look here?
    Got a question on Linux? Visit our Linux sister site.
    I dont answer coding questions via PM or EMail. Please post a thread in the appropriate forum section.

    Creating A Wizard In VB.NET
    Paging A Recordset
    What is wrong with using On Error Resume Next
    Good Article: Language Enhancements In Visual Basic 2010
    Upgrading VB6 Code To VB.NET
    Microsoft MVP 2005/2006/2007/2008/2009/2010/2011/2012/Defrocked

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts


Click Here to Expand Forum to Full Width

By using this site, you agree to the Privacy Policy