Need help randomizing 9 picture locations

     I have a sub that isn't working well.  Let me explain what I'm trying to do:

I've made a little game as an easter egg for my web app.  It's a picture broken into 9 blocks.  3 x 3.  It's one of those sliding game puzzles.  One chunk of picture (which had nothing in it anyway) has been replaced by a white square, whitespot.bmp.  The layout is this:

cmdA1 cmdA2 cmdA3
cmdB1 cmdB2 cmdB3
cmdC1 cmdC2 cmdC3

That's the image button layout.  

foxj1a.jpg foxj1b.jpg whitespot.bmp
foxj2a.jpg foxj2b.jpg foxj2c.jpg
foxj3a.jpg foxj3b.jpg foxj3c.jpg

That's the initial setout of the graphic files.

I've got the sliding part working.  So now all I need to do is scramble the picture with the push of a button.   My code is really bad however, and I haven't been able to wait long enough for it to finish running.  So let me show what I tried, and then any ideas to help optimize that code would be great.

    Private Sub cmdScramble_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmdScramble.Click
        Dim makeStr As String
        Dim PlaceHolder As String
        Dim MyValue As Integer
        Dim counter As Integer = 0
        Randomize() ' Initialize random-number generator.

        Dim a1 As Boolean = False
        Dim a2 As Boolean = False
        Dim a3 As Boolean = False
        Dim b1 As Boolean = False
        Dim b2 As Boolean = False
        Dim b3 As Boolean = False
        Dim c1 As Boolean = False
        Dim c2 As Boolean = False
        Dim c3 As Boolean = False

        Dim DidTake As Boolean = True

        PlaceHolder = "A1"

        For a As Integer = 1 To 9
            DidTake = True
            MyValue = CInt(Int((9 * Rnd()) + 1)) ' Generate random value between 1 and 9.

            Select Case MyValue
                Case 1
                    If a1 = True Then
                        DidTake = False
                        Exit Select
                    End If
                    makeStr = "jfox1a.jpg"
                    a1 = True
                    counter = counter + 1
                Case 2
                    If a2 = True Then
                        DidTake = False
                        Exit Select
                    End If
                    makeStr = "jfox1b.jpg"
                    a2 = True
                    counter = counter + 1
                Case 3
                    If a3 = True Then
                        DidTake = False
                        Exit Select
                    End If
                    makeStr = "whitespot.bmp"
                    a3 = True
                    counter = counter + 1
                Case 4
                    If b1 = True Then
                        DidTake = False
                        Exit Select
                    End If
                    makeStr = "jfox2a.jpg"
                    b1 = True
                    counter = counter + 1
                Case 5
                    If b2 = True Then
                        DidTake = False
                        Exit Select
                    End If
                    makeStr = "jfox2b.jpg"
                    b2 = True
                    counter = counter + 1
                Case 6
                    If b3 = True Then
                        DidTake = False
                        Exit Select
                    End If
                    makeStr = "jfox2c.jpg"
                    b3 = True
                    counter = counter + 1
                Case 7
                    If c1 = True Then
                        DidTake = False
                        Exit Select
                    End If
                    makeStr = "jfox3a.jpg"
                    c1 = True
                    counter = counter + 1
                Case 8
                    If c2 = True Then
                        DidTake = False
                        Exit Select
                    End If
                    makeStr = "jfox3b.jpg"
                    c2 = True
                    counter = counter + 1
                Case 9
                    If c3 = True Then
                        DidTake = False
                        Exit Select
                    End If
                    makeStr = "jfox3c.jpg"
                    c3 = True
                    counter = counter + 1
            End Select

            If DidTake = False Then GoTo Redo

            Select Case PlaceHolder
                Case "A1"
                    Session("A1") = makeStr
                    PlaceHolder = "A2"
                Case "A2"
                    Session("A2") = makeStr
                    PlaceHolder = "A3"
                Case "A3"
                    Session("A3") = makeStr
                    PlaceHolder = "B1"
                Case "B1"
                    Session("B1") = makeStr
                    PlaceHolder = "B2"
                Case "B2"
                    Session("B2") = makeStr
                    PlaceHolder = "B3"
                Case "B3"
                    Session("B3") = makeStr
                    PlaceHolder = "C1"
                Case "C1"
                    Session("C1") = makeStr
                    PlaceHolder = "C2"
                Case "C2"
                    Session("C2") = makeStr
                    PlaceHolder = "C3"
                Case "C3"
                    Session("A3") = makeStr
            End Select


        cmdA1.ImageUrl = Session("A1")
        cmdA2.ImageUrl = Session("A2")
        cmdA3.ImageUrl = Session("A3")
        cmdB1.ImageUrl = Session("B1")
        cmdB2.ImageUrl = Session("B2")
        cmdB3.ImageUrl = Session("B3")
        cmdC1.ImageUrl = Session("C1")
        cmdC2.ImageUrl = Session("C2")
        cmdC3.ImageUrl = Session("C3")

    End Sub


Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

First, it looks like you have an infinite loop.  Since, DidTake is initialized before the Redo: -- I don't see where didtake will ever be true?

Try putting the DidTake = True after the Redo so it re-initializes after every pass.



Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
Conceptually, I think I would try to name my files Pic1, Pic2, Pic3, Pic4, Pic5 etc...  Then I would generate a random array of number between 1 and 9, like -- 371892546.  Then append the file name as string in the session variable like Pic & Array(0) which would return Pic3 and assign it to variable 1.

Then to determine when the player has got the correct combo:  after every move evaluate the current pic array with the winning array of 123456789.

I made a tic tac toe game with great AI using a similar technique.

I'll try to post some code.

Here's my stab at some code:

I used a string for the random order instead of an array because I think it's easier and a string is a type of array anyway.

(I did this with VB, but it should similar in ASP)

   'Module level var's
    Dim RandomCombo As String
    Dim Session(8) As String

    Private Sub GenerateRandomOrder()

        Dim IsUsed As Boolean = False

        For x As Integer = 0 To 100 'enough random numbers to generate a random order

            Dim MyValue As Integer


            MyValue = CInt(Int((9 * Rnd())) + 1)

            If x = 0 Then 'first number generated
                RandomCombo = CStr(MyValue)
                'determine if number is already used

                IsUsed = False

                For Each c As Char In RandomCombo

                    If c = CStr(MyValue) Then 'number used

                        IsUsed = True
                        Exit For

                    End If


                If Not IsUsed Then 'number not used

                    RandomCombo &= MyValue

                    'check length to see if we have 9 numbers
                    If Len(RandomCombo) = 9 Then
                        Exit Sub
                    End If

                End If

            End If


    End Sub

    Private Sub SetPicArray()

        'assign pic order

        For x As Integer = 0 To 8

            Session(x) = "Pic" & RandomCombo.Substring(x, 1) & ".jpg"


    End Sub

Mike TomlinsonMiddle School Assistant TeacherCommented:
This is a little simpler.  Just add all of your buttons to an arraylist.  Then iterate the arraylist and for each button, pick another random button and swap the images from the two:

    Private Sub cmdShuffle_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmdShuffle.Click
        Dim r As New Random
        Dim cmdArray As New ArrayList
        Dim tmpImage As Image
        Dim rndIndex As Integer
        Dim curCmd As Button
        Dim rndCmd As Button


        For Each curCmd In cmdArray
            tmpImage = curCmd.Image
            rndIndex = r.Next(0, cmdArray.Count)
            rndCmd = CType(cmdArray(rndIndex), Button)
            curCmd.Image = rndCmd.Image
            rndCmd.Image = tmpImage
    End Sub
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Visual Basic.NET

From novice to tech pro — start learning today.