# 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

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

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

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

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

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

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

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

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

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

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
Mine is just showing every number in the iOrderedValues[] array in a random order until there is nothing left.

Kind Regards