The correct way to do a shuffle is to choose a random other index to fill in the current index, which is uniform:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
function getRandom(floor, ceiling) { return Math.floor(Math.random() * (ceiling - floor + 1)) + floor; } function shuffle(theArray) { // if it's 1 or 0 items, just return if (theArray.length <= 1) return; // walk through from beginning to end for (var indexWeAreChoosingFor = 0; indexWeAreChoosingFor < theArray.length; indexWeAreChoosingFor++) { // choose a random not-yet-placed item to place there // (could also be the item currently in that spot) // must be an item AFTER the current item, because the stuff // before has all already been placed var randomChoiceIndex = getRandom(indexWeAreChoosingFor, theArray.length - 1); // place our random choice in the spot by swapping var valueAtIndexWeChoseFor = theArray[indexWeAreChoosingFor]; theArray[indexWeAreChoosingFor] = theArray[randomChoiceIndex]; theArray[randomChoiceIndex] = valueAtIndexWeChoseFor; } } |
Also, you may need a uniform random generator in C++:
1 2 3 4 5 6 7 |
#include <random> std::random_device rd; std::mt19937 mt(rd()); std::uniform_real_distribution<double> uniform_random(0.0, 1.0); // use as sample = uniform_random(mt); |