4 Replies - 297 Views - Last Post: 11 May 2012 - 09:14 AM Rate Topic: -----

#1 ybadragon  Icon User is offline

  • New D.I.C Head

Reputation: 1
  • View blog
  • Posts: 32
  • Joined: 11-May 12

Evolutionary Message

Posted 11 May 2012 - 03:18 AM

This is a program that I created after I was looking at Evolutionary Algorithms online at work. It's also my first subscription to this site. This program is going to be used in one of my games as a custom message box, once it is more streamlined. Anyway what it does is the user puts in a string into the textbox, then the program randomizes each character within the string with another character in the string. Then through many iterations it works it's way back to the original message. I know it's a simple idea, but I wanted to have something different than the normal text sliding in from the left on a messagebox in a game. I have also attached a copy of my program to the post for those of you that want to build on it. Any constructive criticism is welcome :)

Here is the code, fairly self explanatory
Public Class Form1
    ' declare variables
    Dim target As String = ""
    Dim source As String = ""
    Dim list As New ArrayList
    Dim loc As Integer = 0

    ' randomize method
    Private Function rnd(ByVal s As String)
        ' declare variables
        Dim rndStr As String = ""
        Dim random As New Random()

        ' for each character in the string
        For Each i As Char In s
            ' add it to arraylist
            list.Add(i)
        Next

        ' for each character in list
        For Each i As Char In list

            ' get random position in the list
            Dim t As Integer = random.Next(list.Count)

            ' concatenate the character to a string
            rndStr += list(t)

            ' set label text to string
            Label1.Text = rndStr
            Me.Refresh()
        Next
        Return rndStr
    End Function
    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        ' declare variables and assign values
        target = TextBox1.Text
        source = rnd(target)
        Dim sLoc As Integer = 0
        Dim tmp As String = ""
        Dim i As Integer

        ' fixing loop
        While Not source = target

            ' if it's the last char in the list
            If loc = list.Count Then

                ' go back to beginning
                loc = 0
            End If

            ' for each char in randomized string
            For Each c As Char In source

                ' if the char is not equal to the char in the list location
                If Not c = list(loc) Then

                    ' get a random char in the list
                    Dim random As New Random()
                    i = random.Next(list.Count)

                    ' assign the char from the list to the current char
                    c = list(i)

                    ' concatenate on the char
                    source += c

                    ' remove the char at the location
                    source = source.Remove(loc, 1)
                Else
                    ' TODO: Remove corresponding list item
                End If

                ' set label text to source
                Label1.Text = source
                Me.Refresh()

                ' increment location in list
                loc += 1
            Next
        End While
    End Sub
End Class



This is the download, I forgot to attach it.

Attached File(s)



Is This A Good Question/Topic? 0
  • +

Replies To: Evolutionary Message

#2 Celerian  Icon User is offline

  • D.I.C Regular


Reputation: 144
  • View blog
  • Posts: 384
  • Joined: 30-March 12

Re: Evolutionary Message

Posted 11 May 2012 - 06:24 AM

Interesting piece of code. There is a bug though.

It works solidly the first time (Longer strings are more enjoyable to watch) but after that, the program will crash because you never reset your list.

The following code fixes your problem:

Public Class Form1
    ' declare variables
    Dim target As String = ""
    Dim source As String = ""
    Dim list As ArrayList
    Dim loc As Integer = 0

    ' randomize method
    Private Function rnd(ByVal s As String)
        ' declare variables
        Dim rndStr As String = ""
        list = New ArrayList
        Dim random As New Random()

        ' for each character in the string
        For Each i As Char In s
            ' add it to arraylist
            list.Add(i)
        Next

        ' for each character in list
        For Each i As Char In list

            ' get random position in the list
            Dim t As Integer = random.Next(list.Count)

            ' concatenate the character to a string
            rndStr += list(t)

            ' set label text to string
            Label1.Text = rndStr
            Me.Refresh()
        Next
        Return rndStr
    End Function
    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        ' declare variables and assign values
        target = TextBox1.Text
        source = rnd(target)
        Dim Loc As Integer = 0
        Dim tmp As String = ""
        Dim i As Integer

        ' fixing loop
        While Not source = target

            ' if it's the last char in the list
            If loc = list.Count Then

                ' go back to beginning
                loc = 0
            End If

            ' for each char in randomized string
            For Each c As Char In source

                ' if the char is not equal to the char in the list location
                If Not c = list(loc) Then

                    ' get a random char in the list
                    Dim random As New Random()
                    i = random.Next(list.Count)

                    ' assign the char from the list to the current char
                    c = list(i)

                    ' concatenate on the char
                    source += c

                    ' remove the char at the location
                    source = source.Remove(loc, 1)
                Else
                    ' TODO: Remove corresponding list item
                End If

                ' set label text to source
                Label1.Text = source
                Me.Refresh()

                ' increment location in list
                loc += 1
            Next
        End While
    End Sub
End Class


Two little changes. I took the initialization of your ListArray out of the main class and moved it into your Rnd function. This creates a new ListArray every time you hit the button, instead of using the same one you created.

The second change is in the button code itself. You were setting sLoc = 0, but sLoc was never used. A variable "Loc" was, so I assumed that you meant to reset Loc everytime the button was hit in order to reset your location in your ListArray.

If you don't reset the list array by clearing it or recreating a new one, you will just append to your ListArray every time the button is clicked.

Failing to reset your Loc variable causes you to extend past the length of the array. For instance, in your code if you used a 10 letter word followed by an 11 letter word, the length of your array list would be 21. Because Loc never got reset, it was still at 10 from the first word you did, and once it gets to your loop, it never checks again that it has reached the end length. Your code assumes that every time it is running from 0 to array length.
Was This Post Helpful? 1
  • +
  • -

#3 ybadragon  Icon User is offline

  • New D.I.C Head

Reputation: 1
  • View blog
  • Posts: 32
  • Joined: 11-May 12

Re: Evolutionary Message

Posted 11 May 2012 - 07:42 AM

Thanks :)
I was actually looking for the reason my program proceeded to crash the second time it was run. I knew about the unused variable sLoc, I just forgot to take it out when I was pasting the code.
Any ideas as to how I can do the "TODO" part of the code, all I want it to do is when it sets one correct letter, remove the first instance of that letter from the list. But every way I've tried it so far gives me an error.
Was This Post Helpful? 0
  • +
  • -

#4 Celerian  Icon User is offline

  • D.I.C Regular


Reputation: 144
  • View blog
  • Posts: 384
  • Joined: 30-March 12

Re: Evolutionary Message

Posted 11 May 2012 - 09:08 AM

There are a couple of problems with the idea of removing a "found letter" from your list.

First off, if you remove a letter from your list array, then you will get the argument out of range exceptions again.

Hint: "For Each c As Char In source" is going to hit every character in string source once. Source will always be the same length, except for the short period of time where you add the new random letter you bring in, right before you remove the letter that didn't match in the position you were testing.

Second, if you remove letters from the list array, you lose the ability to compare the character in source (jumbled string) with the character array.


Ok, played with your code some, and I think I have it working.

Public Class Form1
    ' declare variables
    Dim target As String = ""
    Dim source As String = ""
    Dim list As ArrayList
    Dim loc As Integer = 0

    ' randomize method
    Private Function rnd(ByVal s As String)
        ' declare variables
        Dim rndStr As String = ""
        Dim random As New Random()

        list = New ArrayList

        ' for each character in the string
        For Each i As Char In s
            ' add it to arraylist
            list.Add(i)
        Next

        ' for each character in list
        For Each i As Char In list

            ' get random position in the list
            Dim t As Integer = random.Next(list.Count)

            ' concatenate the character to a string
            rndStr += list(t)

            ' set label text to string
            Label1.Text = rndStr
            Me.Refresh()
        Next
        Return rndStr
    End Function
    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        ' declare variables and assign values
        target = TextBox1.Text
        source = rnd(target)
        Dim loc As Integer = 0
        Dim tmp As String = ""
        Dim i As Integer

        ' fixing loop
        While Not source = target

            'Clear and recreate the ArrayList
            list = New ArrayList

            ' for each letter in the string
            For Each l As Char In target
                ' add it to arraylist
                list.Add(l)
            Next

            ' if it's the last char in the list
            If loc = Len(target) Then

                ' go back to beginning
                loc = 0
            End If

            ' for each char in randomized string
            For Each c As Char In source

                ' if the char is not equal to the char in the list location
                If Not c = Mid(target, loc + 1, 1) Then
                    'If Not c = list(loc) Then

                    ' get a random char in the list
                    Dim random As New Random()
                    i = random.Next(list.Count)

                    ' assign the char from the list to the current char
                    c = list(i)

                    ' concatenate on the char
                    source += c

                    ' remove the char at the location
                    source = source.Remove(loc, 1)
                Else
                    ' TODO: Remove corresponding list item
                    list.Remove(c)
                End If

                ' set label text to source
                Label1.Text = source
                Me.Refresh()

                ' increment location in list
                loc += 1
            Next

        End While
    End Sub
End Class



First, you'll notice that I changed that If statement in the For loop that compared the character 'c' from the source to the letter in the array list. Instead, we compare this with target, so we are able to remove letters from our array list like we want.

Second, we want to remove the letters from the array list as we find them, but eventually we would run out of letters. So inside the loop, we have to create the array list again, and populate it, so every time we run through the loop, we will have a fresh array that we can remove letters from.

Eventually, every letter will match, the ArrayList will be cleared out, source and target will match, and the program will wait for the next input.

Also, I'm sorry that I just kinda solved this. Initially I wanted to drop some hints and let you figure it out, but I had fun with it, and the changes weren't major. I hope you at least understand the changes I made. There is still much you could do to this code to make it more elegant, especially if you plan to work it into a program.

This post has been edited by Celerian: 11 May 2012 - 09:13 AM

Was This Post Helpful? 1
  • +
  • -

#5 ybadragon  Icon User is offline

  • New D.I.C Head

Reputation: 1
  • View blog
  • Posts: 32
  • Joined: 11-May 12

Re: Evolutionary Message

Posted 11 May 2012 - 09:14 AM

Ok, thank you very much for your help, I will test it later when my daughter goes to sleep. Again thank you :)
Was This Post Helpful? 0
  • +
  • -

Page 1 of 1