# Generate 3 different random numbers without duplic

0 Favourites
• 13 posts
• I want to generate three random numbers between 0 and 6, and pass them to global variables. this is what I have:

set one to floor(random(6))

set two to floor(random(6))

set three to floor(random(6))

I can?t figure out how to make sure that none of these three numbers are the same.

• ## Try Construct 3

Develop games in your browser. Powerful, performant & highly capable.

Construct 3 users don't see these ads
• I know a method but not now to apply it to construct 2.

• Put the first value into an array,
• start a while loop that doesn't close until the size of the array matches the number of values you need.
• generate a random number...
• compare it to everything in the array...
• if it doesn't match anything, add it to the array...
• You can do the array method, but here's a lazier way:

It works for a smaller amount of numbers, but if you wanna do more the array method works better. I'll show you how to do that too if you want.

• There's no while loop in c2.

The only sure way I know to do a sampling without replacement is to make a list of your sample, pick one at random, delete the sample from the list.

I showed an implementation not long ago.

It went a bit like that:

``````global sampleCount = 3  // number of... number you want
+System: on start of layout
-> Array: set size to sampleCount,1,1
+On What you want
Local text list = "0,1,2,3,4,5,6"
+repeat sampleCount times
-> Array: set value at loopindex to int((tokenat(list,floor(random(tokencount(list,","))),",")))
-> System: set list to replace(list,str(Array.At(loopindex)),"")
-> System: set list to replace(list,",,",",")
-> System: set list to (left(list,0,1) = ",") ? right(list,len(list)-1) : list
-> System: set list to (right(list,len(list-1),1) = ",") ? left(list,len(list)-1) : list``````

The four last actions are used to delete the token from the list string. This way you don't pick it again.

``    -> System: set list to replace(list,Array.At(loopindex),"")``

Delete the token leaving the comas

1,2,3 -> ",2,3" or "1,,3" or "1,2,"

``    -> System: set list to replace(list,",,",",")``

Check if there's two comas side to side and delete one

1,2,3 -> ",2,3" or "1,3" or "1,2,"

``    -> System: set list to (left(list,0,1) = ",") ? right(list,len(list)-1) : list``

Check if the first character is a coma and delete it

1,2,3 -> "2,3" or "1,3" or "1,2,"

``    -> System: set list to (right(list,len(list-1),1) = ",") ? left(list,len(list)-1) : list``

Check if last character is a coma and delete it

1,2,3 -> "2,3" or "1,3" or "1,2"

• ... Aaaaand that's the not lazy way. <img src="smileys/smiley36.gif" border="0" align="middle" />

• You're way is ugly :D... But indeed pretty neat for the question asked

However I would add another global variable that goes from 0 to 1 once one!=two!=three

To tell the game "ok the variables are now good we can continue"

You made me realize there's indeed a while in c2... The gameloop itself (:

• Yann:

I'm not sure, but looking at your implementation, it looks like it would cause problems with sets that contained values which have substrings which match other values, eg:

1,2,3,4,5,6,7,8,9,10,11

ex: program picks 1

set list to replace(list,str(Array.At(loopindex)),"")

Replace will wipe out the '1' string in '1', '10', and '11'

A while back when I was working on a text-parser with C2, I encountered a similar problem and ended up having to manually traverse and remove without the replace expression.

• A way to handle that that I have used in the past is to use a leading and trailing comma in the list, then not use the first and last tokens, which would be "".

Here is Yann's example tweaked with that in mind.

``````global sampleCount = 3  // number of... number you want
+System: on start of layout
-> Array: set size to sampleCount,1,1
+On What you want
Local text list = ",0,1,2,3,4,5,6,"
+repeat sampleCount times
-> Array: set value at loopindex to int((tokenat(list,int(random(tokencount(list,",")-2)+1),",")))
-> System: set list to replace(list , ","&str(Array.At(loopindex))&"," , ",")``````
• Yep you're super right and I felt into that kind of issue. I solved it by using zerofill numbers.

I think I used r0j0's way too once. Don't remember, I tend to reinvent the wheel sometimes :D

with zerofill you don't fall into the substring issue

"001,002,003,010,110,102,etc"

if you replace(str,"001","") you won't have any issue

and you can still int("003") into 3 with no problem.

But yeah... use r0j0's way... it's the cleanest (:

• This post has been super helpful in assisting me in understanding tokens and how to randomly pull from them. I am having one hang up with Yann's example. In the line

"System: set list to (left(list,0,1) = ",") ? right(list,len(list)-1) : list"

Construct is telling me that left can only have to parameters? What am I missing? been beating my head on this for a full day trying to understand. And Special thanks to Yann! always popping up in the forums I have searched with some intense tech responses.

• yeah probably made a mistake in the two last lines

``````-> System: set list to (left(list,0,1) = ",") ? right(list,len(list)-1) : list
-> System: set list to (right(list,len(list-1),1) = ",") ? left(list,len(list)-1) : list``````

should be

``````-> System: set list to (left(list,1) = ",") ? right(list,len(list)-1) : list
-> System: set list to (right(list,1) = ",") ? left(list,len(list)-1) : list``````
• I think the best and easiest way to do this without a lot extra steps like the token way is to use arrays. Plus its scalable for any amount of numbers/strings/etc.

Make an array and fill it with all your possible choices (in this case numbers) pick a random number from the size of the array and then get that number out of the array and store it however you want to store your 3 picked numbers. Then remove that number from the array.

Once its removed from the array it wont be able to be picked a 2nd time cause it no longer exists unless you added it more than once to the array

• Awesome! thanks Guys!