-1

Lets say that I have an array containing 52 elements. How would one go about to extract a random index from this array and assign it to a new variable? I have created a function that is supposed to shuffle some cards but I want to "deal" the cards by selecting a totally random index from this already shuffled array. I just need help with the extraction part.

int random(int cards[52])
{
    for (int i = 0; i < 52; i++)
    {
        cards[i]= i; // Fill the array
    }

    for (int i = 0; i < (52-1); i++) //Shuffle the elements randomly.
    {
        int r = i + (rand() % (52-1));
        int temp = cards[i]; cards[r]; cards[r] = temp;
    }

    return (cards[52]);
}
πάντα ῥεῖ
  • 1
  • 13
  • 116
  • 190
user3435029
  • 21
  • 1
  • 1
  • 2
    If the cards are already randomized, there's no need to select a random card from the list. – Almo Mar 18 '14 at 20:57
  • 1
    I'm aware of that but it's more of a learning type of thing. I would very much like to know how to extract a random index from an already defined array.I should probably have mentioned that in my post, sorry. – user3435029 Mar 18 '14 at 21:00
  • Do you mean that you want to choose a random number from [0,51]? Or that given a number, say 10, you want to assign the value of `cards[10]` to another variable? Or do you also want to modify the array, perhaps by removing `cards[10]` and rearranging the other elements somehow? – Beta Mar 18 '14 at 21:01
  • If you can do it in `C++11`, take a look at this [thread](http://stackoverflow.com/questions/7114043/random-number-generation-in-c11-how-to-generate-how-do-they-work) for random number generation. – Mahesh Mar 18 '14 at 21:03
  • If I am not way out of the ball park here, each "slot" in the array has an index number, am I correct? Well I want to extract a totally random index number which already has a value assigned to it since the array gets assigned the values 1-52. This means that I would run this randomizing process and the code would select a random element out of these 52 that exist and further copy the value to a new variable that I have assigned. – user3435029 Mar 18 '14 at 21:05
  • Did you note arrays are indexed zero (`0`) based in [tag:c++] language?!? – πάντα ῥεῖ Mar 18 '14 at 21:07
  • You mean that the first index has the index number 0, because I know that? – user3435029 Mar 18 '14 at 21:08
  • *Do you want to modify the array in the process?* – Beta Mar 18 '14 at 21:08
  • @user3435029 If you know, then what should this statement do: `return (cards[52]);`?? – πάντα ῥεῖ Mar 18 '14 at 21:12
  • I want to pass the shuffled array to another function that handles the random selection of two cards. This means that I would like to select a random index out of the 52 that exist and assign the value contain in the specific index that has been chosen to a new variable. – user3435029 Mar 18 '14 at 21:15
  • Just to be clear. I want to know how to randomly select an index within a specified space. – user3435029 Mar 18 '14 at 21:17
  • I had this same homework problem in 1991 – Kirby Mar 18 '14 at 21:18
  • It makes me sad that 4chan is a more helpful community than this programming "forefront" for C-language. – user3435029 Mar 18 '14 at 21:19

1 Answers1

1

To deal the cards you should simply take the top card after shuffling.

If you want to select a random item anyway (or without shuffling) you can do that by selecting a random index in the range, and then removing that item from the array. To select a second item you again choose a random index (in the now reduced range) and then remove that item as well.

Also, your shuffle algorithm is not correct. It looks like you attempted to address the usual problem (why does this simple shuffle algorithm produce biased results? what is a simple reason?) but there's a typo. Your code int r = i + (rand() % (52-1)) should be int r = i + (rand() % (52-i)). 52-i, not 52-1. The bug will cause you to potentially access outside the array bounds. I think your card swapping code also has a typo.

And of course rand() is generally a poor source of random data. The <random> library is better and easier to use.

I'll show two versions of an example solution, one using <random> and one using rand(). <random> is what you should do, but I show rand() simply to keep the differences from your code to a minimum.

#include <random>

std::vector<int> cards(52);

// fill the array
std::iota(std::begin(cards), std::end(cards), 0);

// std::shuffle(std::begin(cards), std::end(cards), eng);

std::default_random_engine eng;
std::uniform_int_distribution<int> dist;

// select 10 cards
for (int i=0; i<10; ++i) {
  // select a random index in the range [0, cards.size()-1]
  int card_index = dist(eng, {0, cards.size()-1});

  int card = cards[card_index]; // get the card and do something with it
  cards.erase(std::begin(cards) + card_index); // remove the card from the deck
}

int n = 52;
int cards[52];

// select 10 cards
for (int i=0; i<10; ++i) {
  int card_index = rand() % n;

  int card = cards[card_index]; // get the card

  // remove the card from the deck
  --n;
  card[card_index] = card[n]; 
}
Community
  • 1
  • 1
bames53
  • 86,085
  • 15
  • 179
  • 244
  • It does not have to be totally random from a mathematics perspective, just be random enough to count as a "wild guess". – user3435029 Mar 18 '14 at 21:07
  • @user3435029 On second look, I think you were trying to address the problem with the shuffle algorithm and got it almost right. I updated my answer. – bames53 Mar 18 '14 at 21:34
  • `std::uniform_int_distribution<>` [distributes](http://en.cppreference.com/w/cpp/numeric/random/uniform_int_distribution) on a closed interval so it should be: `std::uniform_int_distribution dist(0,cards.size()-1);` – Chris Drew Mar 14 '15 at 06:42