Become a MacRumors Supporter for $50/year with no ads, ability to filter front page stories, and private forums.

MythicFrost

macrumors 68040
Original poster
Mar 11, 2009
3,940
38
Australia
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
 

SilentPanda

Moderator emeritus
Oct 8, 2002
9,992
31
The Bamboo Forest
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.
 

MythicFrost

macrumors 68040
Original poster
Mar 11, 2009
3,940
38
Australia
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
 

Chundles

macrumors G5
Jul 4, 2005
12,037
493
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?
 

SilentPanda

Moderator emeritus
Oct 8, 2002
9,992
31
The Bamboo Forest
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.

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?

Unique random is sometimes needed.
 

MythicFrost

macrumors 68040
Original poster
Mar 11, 2009
3,940
38
Australia
Nah it requires uniqueness.

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.
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
 

MythicFrost

macrumors 68040
Original poster
Mar 11, 2009
3,940
38
Australia
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!
 

Guiyon

macrumors 6502a
Mar 19, 2008
771
4
Cambridge, MA
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
}

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
 

MythicFrost

macrumors 68040
Original poster
Mar 11, 2009
3,940
38
Australia
Wow thanks a lot :) very nice, the code looks like it would compile.

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
My mistake, I typed it out here wrong, my real code is fine.

You never use iTempInteger again and lose the original value of iOrderedValues[iRandom]
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!

At some point you may have 2 copies of one of the iOrderedValues
I assume this is because I'm loosing the original iOrderedValues[iRandom]?

You never actually complete the whole loop as you are decrementing iMax while incrementing i
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)
 

Guiyon

macrumors 6502a
Mar 19, 2008
771
4
Cambridge, MA
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)

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
 

MythicFrost

macrumors 68040
Original poster
Mar 11, 2009
3,940
38
Australia
Thanks, guys
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.

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
 
Register on MacRumors! This sidebar will go away, and you'll see fewer ads.