Need help randomizing 9 picture locations

Posted on 2004-11-24
Medium Priority
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
  • 3

Accepted Solution

RacinRan earned 1000 total points
ID: 12665155
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.



Expert Comment

ID: 12665231
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.


Expert Comment

ID: 12665541
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 86

Expert Comment

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

Featured Post

Hire Technology Freelancers with Gigs

Work with freelancers specializing in everything from database administration to programming, who have proven themselves as experts in their field. Hire the best, collaborate easily, pay securely, and get projects done right.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Well, all of us have seen the multiple EXCEL.EXE's in task manager that won't die even if you call the .close, .dispose methods. Try this method to kill any excels in memory. You can copy the kill function to create a check function and replace the …
The ECB site provides FX rates for major currencies since its inception in 1999 in the form of an XML feed. The files have the following format (reducted for brevity) (CODE) There are three files available HERE (http://www.ecb.europa.eu/stats/exch…
Integration Management Part 2
Is your data getting by on basic protection measures? In today’s climate of debilitating malware and ransomware—like WannaCry—that may not be enough. You need to establish more than basics, like a recovery plan that protects both data and endpoints.…
Suggested Courses
Course of the Month16 days, 6 hours left to enroll

850 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