Results 1 to 11 of 11

Thread: [RESOLVED] Ordering a row of picturebox by colour using merge sort

  1. #1

    Thread Starter
    New Member
    Join Date
    May 2019
    Posts
    8

    Resolved [RESOLVED] Ordering a row of picturebox by colour using merge sort

    I'm making a snakes game . Every time the snake eats, a new picturebox is created with a random colour. I'm trying to sort the order of the pictureboxes by colour using merge sort by using the pictureboxes' assigned tabindex. And I've only included the relevant subroutines as the whole program is rather big.

    I've coded in the merge sort subroutine but get caught with an error.I get an "index is out of bounds" error.

    Code:
    Public class game
    
    Dim snake(1000) as picture box
    Dim DataStore() As Integer
    Dim TempStore() As Integer
    Private Sub MergeSort(ByVal ptrFirst As Integer, ByVal ptrLast As Integer)
        Dim ptrMiddle As Integer
    
        If (ptrLast > ptrFirst) Then
            ptrMiddle = (ptrFirst + ptrLast) \ 2
            MergeSort(ptrFirst, ptrMiddle)
            MergeSort(ptrMiddle + 1, ptrLast)
            Merge(ptrFirst, ptrMiddle, ptrLast)
        End If
    
    End Sub
    
    Private Sub Merge(ByVal beginning As Integer, ByVal ptrMiddle As Integer, ByVal ending As Integer)
        ReDim TempStore(snake(body).TabIndex)
        Dim CountLeft As Integer
        Dim CountRight As Integer
        Dim counterMain As Integer
    
        For counter = 0 To body
            TempStore(counter) = DataStore(counter)
        Next
        CountLeft = beginning
        CountRight = ptrMiddle + 1
        counterMain = beginning
    
        Do While (CountLeft <= ptrMiddle) And (CountRight <= ending)
    
            If (TempStore(CountLeft) <= TempStore(CountRight)) Then
                DataStore(counterMain) = TempStore(CountLeft)
                CountLeft = CountLeft + 1
            Else
                DataStore(counterMain) = TempStore(CountRight)
                CountRight = CountRight + 1
            End If
            counterMain = counterMain + 1
        Loop
        If CountLeft <= ptrMiddle Then
            For counter = 1 To ptrMiddle - CountLeft + 1
                DataStore(counterMain + counter - 1) = TempStore(CountLeft + counter - 1)
            Next
        Else
            For counter = 1 To ending - CountRight + 1
                DataStore(counterMain + counter - 1) = TempStore(CountRight + counter - 1)
            Next
        End If
    End Sub
    
    Private Sub CreatePlayerHead()
        body = 0
        snake(0) = New PictureBox
        With snake(0)
            .Width = 15
            .Height = 15
            .BackColor = Color.Green
            .Top = Me.Height / 2 - snake(0).Height
            .Left = Me.Width / 2 - snake(0).Width
        End With
    
        Me.Controls.Add(snake(0))
    End Sub
    Private Sub PlayerSnakeBodyWithColour()
        Dim body_colour As Integer
        body += 1
        snake(body) = New PictureBox
    
        With snake(body)
            .Width = 15
            .Height = 15
            .Top = Me.Height + 100
            .Left = Me.Width + 100
        End With
    
        body_colour = Int(Rnd() * 8 + 1)
        Select Case body_colour
            Case 1
                snake(body).BackColor = Color.Green
                snake(body).TabIndex = 1
            Case 2
                snake(body).BackColor = Color.Blue
                snake(body).TabIndex = 2
            Case 3
                snake(body).BackColor = Color.Purple
                snake(body).TabIndex = 3
            Case 4
                snake(body).BackColor = Color.Red
                snake(body).TabIndex = 4
            Case 5
                snake(body).BackColor = Color.Yellow
                snake(body).TabIndex = 5
            Case 6
                snake(body).BackColor = Color.White
                snake(body).TabIndex = 6
            Case 7
                snake(body).BackColor = Color.Pink
                snake(body).TabIndex = 7
            Case 8
                snake(body).BackColor = Color.Orange
                snake(body).TabIndex = 8
        End Select
        Me.Controls.Add(snake(body))
    
        ReDim DataStore(body)
    
        For counter = 0 To body
            DataStore(counter) = snake(counter).TabIndex
        Next
        MergeSort(1, snake(body).TabIndex)
        For counter = 0 To body
           Textbox1.text = DataStore(counter) & vbCrLf
        Next
    End Sub
    End Class
    I'm using a textbox as the output for the mean time to ensure the merge sort is working.
    If anyone could help, it would mean a lot.Thank you.

  2. #2
    eXtreme Programmer .paul.'s Avatar
    Join Date
    May 2007
    Location
    Chelmsford UK
    Posts
    25,481

    Re: Ordering a row of picturebox by colour using merge sort

    It looks like DataStore hasn't been assigned dimension

  3. #3
    eXtreme Programmer .paul.'s Avatar
    Join Date
    May 2007
    Location
    Chelmsford UK
    Posts
    25,481

    Re: Ordering a row of picturebox by colour using merge sort

    If it isn't the DataStore array, it is definitely because you're trying to use an array index that is < 0 or > your array upperbound

  4. #4

    Thread Starter
    New Member
    Join Date
    May 2019
    Posts
    8

    Re: Ordering a row of picturebox by colour using merge sort

    The DataStore array is assigned towards the end of the code to the length of body of the snake

  5. #5
    Frenzied Member
    Join Date
    Jul 2011
    Location
    UK
    Posts
    1,335

    Re: Ordering a row of picturebox by colour using merge sort

    I really do not understand what you are trying to do here.

    You have an array of PictureBoxes, Snake(). Each PictureBox has a TabIndex whose value can be from 1 up to 8.

    You store those TabIndex values in a parallel array, DataStore()

    You merge sort that parallel array (DataStore()).

    So you'll end up with the DataStore() array containing numbers 1 through 8 sorted in ascending order (apart from the first element, at index 0).

    However, the contents of the DataStore() array bear no relationship to the Snake() array??


    As to the IndexOutOfRange exception, I think you are trying to sort the DataStore() array from index 1 to the end of the array, so
    Code:
    MergeSort(1, snake(body).TabIndex)
    should be
    Code:
    MergeSort(1, body)
    and similarly
    Code:
    ReDim TempStore(snake(body).TabIndex)
    should be
    Code:
    ReDim TempStore(body)

  6. #6
    Sinecure devotee
    Join Date
    Aug 2013
    Location
    Southern Tier NY
    Posts
    6,582

    Re: Ordering a row of picturebox by colour using merge sort

    Yeah, I don't see where you're tying the array of colors to the pictureboxes that have that color, so how does sorting the colors end up drawing the pictureboxes in sorted order.

    It doesn't seem like you really need a sort, per se.
    If you're going to have eight different colors for the body parts, just have an array of eight that you increment each element, one element for each color.

    So, when you add a new body part, pick a random color, increment the corresponding index in your color array, then loop through that and use it to change the backcolor of your pictureboxes, in the order thay are in the original array.
    Code:
    Dim ColorCounters(7) As Integer
    Dim ColorVals() as Color = {Color.Green, Color.Yellow, etc...}
    
    part = 1
    For colorIdx = 0 to 7
      For colorNum = 1 to ColorCounters(colorIdx)
         snake(part).BackColor = ColorVals(colorIdx)
         part += 1
      Next
    Next
    No need to use tabindex, or swap colors and pictureboxes around, or maintain a way of keeping track of what order the pictureboxes are in.

  7. #7

    Thread Starter
    New Member
    Join Date
    May 2019
    Posts
    8

    Re: Ordering a row of picturebox by colour using merge sort

    Quote Originally Posted by Inferrd View Post
    I really do not understand what you are trying to do here.

    You have an array of PictureBoxes, Snake(). Each PictureBox has a TabIndex whose value can be from 1 up to 8.

    You store those TabIndex values in a parallel array, DataStore()

    You merge sort that parallel array (DataStore()).

    So you'll end up with the DataStore() array containing numbers 1 through 8 sorted in ascending order (apart from the first element, at index 0).

    However, the contents of the DataStore() array bear no relationship to the Snake() array??


    As to the IndexOutOfRange exception, I think you are trying to sort the DataStore() array from index 1 to the end of the array, so
    Code:
    MergeSort(1, snake(body).TabIndex)
    should be
    Code:
    MergeSort(1, body)
    and similarly
    Code:
    ReDim TempStore(snake(body).TabIndex)
    should be
    Code:
    ReDim TempStore(body)
    This sorted the problem thanks.

  8. #8

    Thread Starter
    New Member
    Join Date
    May 2019
    Posts
    8

    Re: Ordering a row of picturebox by colour using merge sort

    Quote Originally Posted by passel View Post
    Yeah, I don't see where you're tying the array of colors to the pictureboxes that have that color, so how does sorting the colors end up drawing the pictureboxes in sorted order.

    It doesn't seem like you really need a sort, per se.
    If you're going to have eight different colors for the body parts, just have an array of eight that you increment each element, one element for each color.

    So, when you add a new body part, pick a random color, increment the corresponding index in your color array, then loop through that and use it to change the backcolor of your pictureboxes, in the order thay are in the original array.
    Code:
    Dim ColorCounters(7) As Integer
    Dim ColorVals() as Color = {Color.Green, Color.Yellow, etc...}
    
    part = 1
    For colorIdx = 0 to 7
      For colorNum = 1 to ColorCounters(colorIdx)
         snake(part).BackColor = ColorVals(colorIdx)
         part += 1
      Next
    Next
    No need to use tabindex, or swap colors and pictureboxes around, or maintain a way of keeping track of what order the pictureboxes are in.
    I know I don't need to use such a complicated algorithm. I'm doing my coursework and to get into the top mark band, I've included the merge sort.
    I have not yet code for how the ordered list will become the snakes body.The sorting part is just the first part of a feature I'll include in the game.
    If possible I will implement your code to the sorted list.
    Thank you.
    Last edited by Furqan Raheem; May 18th, 2019 at 04:52 PM.

  9. #9
    Frenzied Member
    Join Date
    Jul 2011
    Location
    UK
    Posts
    1,335

    Re: Ordering a row of picturebox by colour using merge sort

    Having had the chance to think on this for a while, I suppose the DataStore() and Snake() arrays don't need a direct relationship.

    Assuming you are not reordering the actual picture boxes in the Snake() array then, once you have performed the merge sort, you could simply iterate through both arrays updating the colour of the picture boxes based on the colour values stored in the DataStore() array.

    Based on passel's code:
    Code:
    Dim ColorVals() as Color = {Color.Green, Color.Yellow, etc...}
    
    For part = 1 To body
        snake(part).BackColor = ColorVals(DataStore(part) - 1)
    Next
    If you want to get rid of the -1, then you might want to use zero based values for the colour codes:
    Code:
     body_colour = Int(Rnd() * 8)
     Select Case body_colour
         Case 0
            etc....
    Also, one of the things that I found confusing when initially reading through your code was your use of the TabIndex to store the colour codes along with the PictureBoxes. It would be more usual to use the Tag Property (if you are not already using it for something else). The Tag Property stores Object Types, and so can be used for storing just about anything. When you retrieve the value from the Tag Property, you should convert it to the appropriate Type: CInt(snake(counter).Tag) in this case.

  10. #10
    Sinecure devotee
    Join Date
    Aug 2013
    Location
    Southern Tier NY
    Posts
    6,582

    Re: Ordering a row of picturebox by colour using merge sort

    I thought using TabIndex was a bit odd as well, but since the picturebox doesn't support input focus and doesn't use the TabIndex as a TabIndex, it isn't clobbered by the control as it would be by a control that does support input focus. I wouldn't have used it, but I guess it technically works without any apparent repercussions.

  11. #11

    Thread Starter
    New Member
    Join Date
    May 2019
    Posts
    8

    Re: Ordering a row of picturebox by colour using merge sort

    Thank you very much.This cleared up a lot of stuffs. I will look into the tag property as tabindex isn't what I thought it was supposed to be. Really appreciate the further help on using the sorted list for the snakes body. Thank you.

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