More theory then anything? Random non repeating numbers in a loop

Discussion in 'Mac Programming' started by MythicFrost, Sep 29, 2009.

  1. MythicFrost macrumors 68040

    MythicFrost

    Joined:
    Mar 11, 2009
    Location:
    Australia
    #1
    I need to make a Loop from 0 to 8 that generates a random number each time but never repeats.

    I can only use arrays, and I cannot resize them.
    I'll use an example, (this is in no particular language)
    Code:
        Integer Array [4] (index 0 - 4 (5 numbers) are set to 0 - 4)
        For (i = 0; i<4; i++)
        {
            Set Random = Random(0,4) //Random Number Between 0 and 4
            //The first number selected is 3, the next number should only be able to be 0, 1, 2, 4 (not 3)
        }
    I've forgotten how to do this

    Technically it's not Mac related, in fact it's for a game (making/modding a map),
    But I thought this was the best place to post.

    Does anyone know how to do this?

    Kind Regards
     
  2. SilentPanda Moderator emeritus

    SilentPanda

    Joined:
    Oct 8, 2002
    Location:
    The Bamboo Forest
    #2
    I think in this instance it's generally easier to make an array and populate it with your numbers, 0 through 8. Shuffle the array to put the numbers in a random sequence then read the indexes from the first to the last.
     
  3. MythicFrost thread starter macrumors 68040

    MythicFrost

    Joined:
    Mar 11, 2009
    Location:
    Australia
    #3
    It's a good idea, but there is no shuffle function, this is a limited language.
    I've seen it done before, I've just forgotten it, something to do with using an array, a random number and a temp variable. I even tried googling it :O

    Any other idea's?

    Kind Regards
     
  4. Chundles macrumors G4

    Chundles

    Joined:
    Jul 4, 2005
    #4
    If you don't let them repeat is it truly random? I thought the whole idea of random was that all outcomes are equally likely?
     
  5. SilentPanda Moderator emeritus

    SilentPanda

    Joined:
    Oct 8, 2002
    Location:
    The Bamboo Forest
    #5
    Well which language? Otherwise we can keep throwing things at you and you can keep saying that it's not possible in this untold language.

    Unique random is sometimes needed.
     
  6. MythicFrost thread starter macrumors 68040

    MythicFrost

    Joined:
    Mar 11, 2009
    Location:
    Australia
    #6
    Nah it requires uniqueness.

    Well I didn't think anyone would know it, so I figured why bother to tell,
    It's the GUI of the Trigger Editor in the World Editor for Warcraft 3, or the scripting language which the GUI is converted into is called Jass.

    Technically you can use structs and other stuff, but I'm only using the GUI atm, although if I had the code in jass I could put it into GUI.

    It just can't use any fancy structs or other commands, only things limited to the editor.

    Kind Regards
     
  7. Guiyon macrumors 6502a

    Joined:
    Mar 19, 2008
    Location:
    North Shore, MA
    #7
    Most languages don't. You can write one by just looping over the array and randomly swapping elements.
     
  8. MythicFrost thread starter macrumors 68040

    MythicFrost

    Joined:
    Mar 11, 2009
    Location:
    Australia
    #8
    Thank you, it's a good idea making a shuffle function, I'd never thought of that.
    But you managed to spark my mind and remember the old function, it goes like this:

    Code:
    Integer Array iOrderedValues[4]
    Integer iMax = 5
    For (i = 0; i<iMax; i++)
    {
        iRandom = Random(0, iMax)
        iTempInteger = iOrderedValues[iRandom]
        iOrderedValues[iRandom] = iOrderedValues[iMax]
        iMax -= 1
    }
    EDIT: (iOrderedValues[] has to be preset each to it's own index, iOrderedValues[0] = 0 etc, forgot to type that part in)

    Haha that's the most confused language I've ever written, it seems to contain several different syntaxes and language commands in one :D

    Thanks a lot!
     
  9. Guiyon macrumors 6502a

    Joined:
    Mar 19, 2008
    Location:
    North Shore, MA
    #9
    Although I haven't used JASS at all I can see several major issues with that code:
    • Arrays are indexed from 0. With iMax = 5 you are either going to go over your expected length or have a 5 in the array
    • You never use iTempInteger again and lose the original value of iOrderedValues[iRandom]
    • At some point you may have 2 copies of one of the iOrderedValues
    • You never actually complete the whole loop as you are decrementing iMax while incrementing i

    I whipped up a quick bit of code to demonstrate the swap. I don't know if it will actually compile or not (I learned the syntax from a glance at the JASS manual).

    Code:
    local integer array numbers
    local integer arrLen = 4
    local integer temp = 0
    local integer rndIndex = 0
    local integer index = 0
    
    // Construct the sorted numbers array
    loop
        exitwhen( index == arrLen )
        
        set numbers[ index ] = index
        set index = index + 1
    endloop
    
    // Perform 'n' swaps on the array, where 'n'
    //  is the length of the array.
    set index = 0
    loop
        exitwhen( index == arrLen )
        set rndIndex = Random( 0, arrLen - 1 )
        
        set temp = numbers[ index ]
        set numbers[ index ] = numbers[ rndIndex ]
        set numbers[ rndIndex ] = temp
        set index = index + 1
    endloop
     
  10. MythicFrost thread starter macrumors 68040

    MythicFrost

    Joined:
    Mar 11, 2009
    Location:
    Australia
    #10
    Wow thanks a lot :) very nice, the code looks like it would compile.

    My mistake, I typed it out here wrong, my real code is fine.

    iTempInteger is used in the real code, it's the "random value" that is selected,
    Loosing the original value of iOrderedValues[] is a problem, thank you!

    I assume this is because I'm loosing the original iOrderedValues[iRandom]?

    Again, my mistake, the real code is working fine, it's set to a different variable and iMax is decremented without effecting the loop.

    Thank you very much!

    This is the actual code in the GUI form, does it look right do you think?
    iItemCount is 8
    iMax is set to 8
    Code:
    For each (Integer A) from 0 to iItemCount, do (Actions)
        Loop - Actions
            Set iRandomNumber = (Random integer number between 0 and iMax)
            Set iTempInteger = iOrderedValues[iRandomNumber]
            Set iOrderedValues[iRandomNumber] = iOrderedValues[iMax]
            Set iOrderedValues[iMax] = iTempInteger
            Set iMax = (iMax - 1)
    
     
  11. Guiyon macrumors 6502a

    Joined:
    Mar 19, 2008
    Location:
    North Shore, MA
    #11
    Your use of the iMax variable is still wrong here. You always want the random range to be the length of your array but since you are decrementing iMax your shuffle is getting limited. I would suggest getting rid of iMax altogether as it really serves no purpose.

    Code:
    For each (Integer A) from 0 to iItemCount, do (Actions)
        Loop - Actions
            Set iRandomNumber = (Random integer number between 0 and (iItemCount - 1))
            Set iTempInteger = iOrderedValues[iRandomNumber]
            Set iOrderedValues[iRandomNumber] = iOrderedValues[A]
            Set iOrderedValues[A] = iTempInteger
    
     
  12. lloyddean macrumors 6502a

    Joined:
    May 10, 2009
    Location:
    Des Moines, WA
    #12
    See my answer in response to essentially the same question in the iPhone Programming forum.
     
  13. MythicFrost thread starter macrumors 68040

    MythicFrost

    Joined:
    Mar 11, 2009
    Location:
    Australia
    #13
    Thanks, guys
    We're doing two different things, my code is not shuffling, I have realized yours is :D
    Mine is just showing every number in the iOrderedValues[] array in a random order until there is nothing left.



    Kind Regards
     

Share This Page