0 Favourites

Generate 3 different random numbers without duplic

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

  • 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...
  • Construct 3

    Buy Construct 3

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

    Buy Now Construct 3 users don't see these ads
  • You can do the array method, but here's a lazier way:

    dl.dropbox.com/u/19702035/randomstuff.capx

    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" />

  • SullyTheStrange

    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))&"," , ",")
  • cacotigon

    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.

  • ASBanks

    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!

Jump to:
Active Users
There are 1 visitors browsing this topic (0 users and 1 guests)