How do I shuffle an array and then set those values in text boxes?

  • I've been struggling with this for a couple days now. I know there are posts and tutorials on this, but I cant seem to wrap my head around them.

    Like this one https://www.construct.net/en/tutorials/simple-array-shuffle-371

    Anyway, this is what i'm trying to do:

    I have a game set up where it is pulling multiple choice answers from an array. It's pulling the answers from a semi-permanent array (which has 20 options) and pasting the chosen four multiple choice answers into a temporary array. I need to then shuffle these answers and then set those values into text boxes.

    You can see the bulk of this operation in the screen shot below:

    And this is where i'm trying to quickly shuffle the temporary array (based on what I saw in the tutorial posted above), but my brain is dying at this point. I'm plan to finally pull the text in the x column and use that for the 'answer_text'.

  • Shuffle array function below. Uses new 'beta' function feature, but should be easy to translate to older function or just plain events.

  • Shuffle array function below. Uses new 'beta' function feature, but should be easy to translate to older function or just plain events.

    Thank you for your reply. I imitated your event sheet as close as possible, but it gave me some pretty serious errors (0 in some places, and jumbled data in other places).

    If you have the time, could you explain how this works? I cant 't understand what it is supposed to be doing.

    a

    - Why are you subtracting one from the width in the first system event? ("from 0 to Array.Width-1")

    - Why are you subtracting the LoopIndex from the Array.Width in the 'set RandomIndex' action?

    - How does this lead to a shuffled array?

    - Will it work with text values in the array?

  • Try Construct 3

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

    Try Now Construct 3 users don't see these ads
  • Sofa_King

    he is subtracting one in the first event because arrays are zero based... so if the array has a width of 10 (10 values stored in the array), then those entries will be numbered 0 to 9.

    the routine starts with the LAST entry in the array and picks a random entry up to that point in the array and swaps the values. And then does the second last one, etc...

    so at the end of the loop, each value in the array has had a chance to be swapped at least once.

    the tempValue variable is a text variable, so it will work with text values.

    if you don't have the -1 as shown, you could end up swapping with a value outside the array limits - which would probably give you a zero value.

    to walk through the logic: (for an array with 10 items)

    the first time the loop runs, loopindex will be zero, so randomindex will be int(random(10-0))

    note that random will pick a number up to, but NOT including the limit you give it, so in this case it will pick a number between 0 and 9.9999... and then take the integer portion (to give you a number between 0 and 9).

    then it sets tempValue to the last entry in the array (which is 10-0-1), and then swaps that value with the randomly picked entry.

    then the loop repeats, loopindex will be 1, so randomindex will be a number between 0 and 8, and the second last entry (10-1-1) is swapped with that.

    repeat, loopindex will be 2, randomindex will be 0 to 7, swap with (10-2-1) or 7th entry

    The final time the loop runs, loopindex will be 9, so randomindex will be 0, and it will swap with itself (10-9-1).

    This guaranties that every item in the array has had a chance to swap with another position in the array.

    EDIT: just looked at your shuffle code, and the reason it was not working is that "pick" could choose the same value multiple times, and that would result in loopindex getting overwritten in the array, and then you would also have at least other array value never getting set. You would have to use a method that must pick a unique value. (the tutorial you linked to put 4 values in a temp array, and then deleted the picked value each time through the next loop so it could not be picked again).

  • AllanR I really appreciate the time you took to write that! I understood most of what you said, but I am still struggling to implement Mikal 's code or the code in the aforementioned tutorial. I feel like you both gave great information, but no matter what I try to do, I keep getting 0, NaN, or text values from other locations in the first array.

    I decided to try my own code that (in my head) should work. Perhaps you could stake a look and identify why its not working? Keep in mind that I am trying to pull the Y values from (0 to 3) in the 'Working_Answers_Array's Y axis, and randomly place them into 'Working_Answers_Array_Shuffled' at random random Y value locations. I then will pull these text values from 'Working_Array_Shuffled' and use them to set the in-game text.

    Why doesn't this work!??! It works in my head... :(

  • I can see a few things that are likely to be causing problems:

    1. Adding the 0.9999 when picking a random no. for RandYPlacement means you may pick a number outside of the Y index of the array - remember that the Height is one more than the max Y value as the Y index starts at 0.

    2. RandYPlacement can keep picking the same number in each loop so some values won't be selected and others could be duplicated.

    3. When setting the size of Working_Answer_Array your Z axis needs to be at least 1.

    It's always good to try and work things out in a way you can understand but to be honest it would be worth getting your head around Mikal's code - it's quite elegant and really simplifies the process.

    Here's a similar version that's even simpler! ;-P

    It essentially does the same thing, but only needs one variable; in this case "pick" is a variable added to the array, rather than a local variable.

    The "for" loop runs once for each X index in the array.

    Each time the loop runs:

    1. the first action saves to "pick" an index value between 0 and the max X index minus the current loop index, so the first loop it picks between 0 and Width-1 minus 0, the second loop 0 and Width-1 minus 1 and so on until it gets to the final loop where it picks between 0 and width-1 minus width-1, or just 0.
    2. the second action adds the value in the array at the index "pick" to the end of the array (or "pushes back").
    3. the third action deletes the index "pick".

    This final action reduces the number of values to pick from by one, which is why we reduce the scope of pick by the loopindex at the start of the next loop. Effectively what happens is each loop a random value that hasn't already been picked is grabbed and stuck on the end of the array.

    Hope that helps! :-)

  • Sofa_King

    another comment is why do you need to re-shuffle the temp array, when the act of picking 4 answers randomly from the larger array already puts them in a random order?

    if you still have trouble. make sample file with the json data, the 20 item array, the temp array, and the 4 text answer fields. It is much easier to help when we have something to work with - and seeing the actual data can quite often lead to suggestions you might not have considered.

    To me, the top image in your first post looks like it should already be giving you a shuffled result, and it deletes the picked answer so you shouldn't get duplicates.

  • AllanR nice explanation, well done. Sofa_King here's an example project of the method I showed (though that simplification by mekonbekon looks very nice also.)

    https://sendgb.com/DRV8esgk4zA

    Here's a test of 1000000 iterations, looks reasonably well distributed (though I was just summing and averaging, not counting 'combinations'.) Average should trend to 1.5 for this number array.

    Good luck!

  • Mikal That C3P! Thanks. It was helpful to see it in action.

    mekonbekon Thank you, for breaking it down step-by-step.

    I think I understand the logic behind this method. I have tried to implement what you guys have been saying, but I keep ending up with errors. So I think it's probably stemming from somewhere outside the randomization logic.

    I. Give. Up. I cant keep trying to do this because its killing my drive to actually get the work done. At some point down the line, i'm going to revisit this thread and figure it out, but for now, i'm going to stick to the following idea based on what AllanR said.

    AllanR Dude, your right about it already being randomized. I took that a little further and just made a simple 'random 0-3' variable and that seemed to be enough to randomize the text values that I was pulling.

    For some reason the animation frame selection is still not syncing up correctly and I have no idea why not. In the screen capture, you can see the I have disabled the first two lines of code. This code just pulls the info from the 0 Y-axis. The frustrating thing is that this works perfectly every time, but the randomized Y-axis code doesn't work (it works for the text values, but the frame selection is fucked).

    My image sprites are 19 animation frames, named 0, 1, 2, 3 ..., 19, which correspond to the IELTS_Array which is also 0 to 19.

    Anyways my friends, thank you so much for walking me through this step by step! I will 100% revisit this thread in the future. I really appreciate the time you guys took to help me. It's unfortunate that I wasn't able to implement it, but I will at some point.

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