Need help randomizing 9 picture locations

Posted on 2004-11-24
Last Modified: 2010-04-23
     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


Question by:gleznov
    LVL 3

    Accepted Solution

    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.


    LVL 3

    Expert Comment

    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.

    LVL 3

    Expert Comment

    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

    LVL 85

    Expert Comment

    by:Mike Tomlinson
    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

    Write Comment

    Please enter a first name

    Please enter a last name

    We will never share this with anyone.

    Featured Post

    Top 6 Sources for Identifying Threat Actor TTPs

    Understanding your enemy is essential. These six sources will help you identify the most popular threat actor tactics, techniques, and procedures (TTPs).

    A while ago, I was working on a Windows Forms application and I needed a special label control with reflection (glass) effect to show some titles in a stylish way. I've always enjoyed working with graphics, but it's never too clever to re-invent …
    1.0 - Introduction Converting Visual Basic 6.0 (VB6) to Visual Basic 2008+ (VB.NET). If ever there was a subject full of murkiness and bad decisions, it is this one!   The first problem seems to be that people considering this task of converting…
    To add imagery to an HTML email signature, you have two options available to you. You can either add a logo/image by embedding it directly into the signature or hosting it externally and linking to it. The vast majority of email clients display l…
    This video discusses moving either the default database or any database to a new volume.

    779 members asked questions and received personalized solutions in the past 7 days.

    Join the community of 500,000 technology professionals and ask your questions.

    Join & Ask a Question

    Need Help in Real-Time?

    Connect with top rated Experts

    11 Experts available now in Live!

    Get 1:1 Help Now