Simmon Thind
Simmon Thind

Reputation: 65

Randomizing numbers in C and storing them in an integer array

I am trying to write a code which randomizes numbers between 1 and 14 (symbolizing one suit of a deck of cards). The code should store the values in an array with a limit of 52. Each number can only be stored 4 times (as there are 4 suits in a deck of cards). So, in the end, I should be displaying two randomized decks for person_a and person_b.

My problem is that the randomized decks for person_a and person_b are the same. I have no idea why. I tried seeding using srand(), and using rand() for the random number. Can someone help?

Also, I know my code is really messy and terrible. I'm sorry - this is my first time taking a C course. Below is the code:

#include <stdlib.h>
#include <stdio.h>
#include <math.h>

#define MAX_DECK 52
#define REPETITIONS 4
#define CARDS_HIGH 14
#define CARDS_LOW 1

int
randomize_check(int value_check, int limit, int cards[])
{
    int count = 0;
    int i = 0;
    for(i=0; i<limit; i++)
    {
        if(cards[i]==value_check)
        {
            count++;
        }
    }
    if(count>REPETITIONS)
    {
        return -1;
    }
    else if (count<=REPETITIONS)
    {
        return 1;
    }
}

int
get_random(void)
{
    int random_number = 0;
    random_number = (rand()%(CARDS_HIGH-CARDS_LOW))+CARDS_LOW;

    return(random_number);
}

int * randomize_deck(void)
{

    static int cards[MAX_DECK];
    int i = 0;
    int randomize = 0;
    int check = 0;

    for (i=0; i<MAX_DECK; i++)
    {
        randomize = get_random();
        cards[i] = randomize;
        check = randomize_check(cards[i], MAX_DECK, cards);
        while((check) == -1)
        {
            randomize = get_random();
            cards[i] = randomize;
            check = randomize_check(cards[i], MAX_DECK, cards);
        }

    }
    return(cards);
}

int
main(void)
{
    srand ( time(NULL) );
    int i = 0, j = 0;

    int *person_a = randomize_deck();
    int *person_b = randomize_deck();

    for (i = 0; i < MAX_DECK; i++) //print_a
    {
        printf( "Cards[a%d]: %d\n", i, *(person_a + i));
    }

    printf("\n");

    for (j = 0; j < MAX_DECK; j++) //print_b
    {
        printf( "Cards[b%d]: %d\n", j, *(person_b + j));
    }

    return(0);
}

Upvotes: 1

Views: 95

Answers (2)

Santiago Varela
Santiago Varela

Reputation: 2237

"...randomized decks for person_a and person_b are the same. I have no idea why."

static int cards[MAX_DECK];

This happens because you declared your integer array as static

This means that every time the function randomize_deck is called the same int array will be operated upon and will be the same one returned.**

int * randomize_deck(void) {
    int* cards = malloc(sizeof int) * MAX_DECK); // Instantiate a new and different deck of cards every time the function is called.

    int i = 0;
    int randomize = 0;
    int check = 0;

    /* next steps randomize_deck function */

    return cards; // Now you will return a different deck of cards every time you invoke the function

}

There is one important step to take care of in your main() function. You need no deallocate the memory of the cards you allocated in randomize_deck(). So, you have to free person_a and person_b.

int main(void)
{
    srand ( time(NULL) );
    int i = 0, j = 0;

    int *person_a = randomize_deck();
    int *person_b = randomize_deck();

    /* ... */
    free(person_a); // You need to free these elements you returned,
    free(person_b);
    return 0;
}

Upvotes: 2

ad absurdum
ad absurdum

Reputation: 21315

Your problem stems from the fact that cards is declared as a static array in the randomize_deck() function. So, the first call to randomize_deck() fills this array with random cards, returning a pointer to cards. Then the second call to randomize_deck() fills the same static array with new random cards, and returns a pointer to the same static array. After all of this, both person_a and person_b point to the same static array.

One solution is to change the randomize_deck() function to accept an array argument, with a return type of void. Also, it would be best to pass the size of the array to randomize_deck(), instead of relying on a global constant. And note that in the code below I have changed the array index variables to type size_t, which is an unsigned integer type guaranteed to hold any array index, and the correct type for array indices.

void randomize_deck(int cards[], size_t deck_sz)
{

    size_t i = 0;
    int randomize = 0;
    int check = 0;

    for (i = 0; i < deck_sz; i++)
    {
        randomize = get_random();
        cards[i] = randomize;
        check = randomize_check(cards[i], deck_sz, cards);
        while((check) == -1)
        {
            randomize = get_random();
            cards[i] = randomize;
            check = randomize_check(cards[i], deck_sz, cards);
        }

    }
}

Then in main(), you declare two int arrays, one for each player, and pass these to the randomize_deck() function:

int main(void)
{
    srand ( time(NULL) );
    size_t i = 0, j = 0;

    int person_a[MAX_DECK];
    int person_b[MAX_DECK];

    randomize_deck(person_a, MAX_DECK);
    randomize_deck(person_b, MAX_DECK);

    /* ... */

    return 0;
}

Upvotes: 3

Related Questions