Generate random number without repetition in C

Asked

Viewed 7,781 times

2

Hello, I am making a memory game in c, and would like to know how to generate a random number without repetition. I will post what in the function so far. I will need to do another function only to check for repeated number?

void preencher_mesa(int matriz[4][4], int dificuldade)
{

    int i,j;
    int lim_col, lim_linha;



    for(i=0; i<4; i++)
        for(j=0;j<4;j++)
            matriz[i][j] = 0;


    if(dificuldade == 1)
    {
        lim_col = 3;
        lim_linha = 2;

    }
    else if(dificuldade == 2)
    {
        lim_col = 4;
        lim_linha = 2;
    }
    else if(dificuldade == 3)
    {
        lim_col = 4;
        lim_linha = 4;
    }

    srand(time(NULL) );
    for(i=0;i<lim_linha;i++)
    {
        for(j=0; j<lim_col;j++)
        {
                if(dificuldade == 1)
                {
                    matriz[i][j] = (rand()%3)+1;

                }
                else if(dificuldade == 2)
                {
                    matriz[i][j] = (rand()%6)+1;


                }
                else if (dificuldade == 3)
                {
                    matriz[i][j] = (rand()%8)+1;

                }



        }

    }

     mostrar_mesa(matriz);
}
  • You can’t enter the values 1, 2, and 3 in an array of 6 positions without repeating! (difficulty == 1); You cannot enter values 1, 2, 3, 4, 5, and, 6 in an array of 8 positions without repeating! (difficulty == 2); you cannot put 8 values in an array of 16 positions without repeating (3)

  • I really want them to repeat, but only once, because it’s a memory game

  • Ok, the idea is the same as my answer. You fill the array with repeated values, shuffle the array, use the random values.

  • I ended up creating this variable: int letters[16] = {1,1,2,2,3,3,4,5,5,6,6,7,7,8,8}; na main. But I wish that according to the level of difficulty there were only a couple of letters. Example => Difficulty 1 -> 3 pairs of cards then appear only (randomly) I don’t know, 1 and 1 , 4 and 4 , 7 and 7 @pmg

  • The easiest way is to pick up 3 isolated numbers for the beginning of an array ({1, 2, 3, 4, 5, 6, 7, 8} ==> {1, 4, 7}); then extend this array principle ({1, 4, 7} ==> {1, 4, 7, 1, 4, 7}); and finally shuffle the array. Note that the array can always be (or almost always) the same, only changes the initial number you consider. See the theme of my answer.

2 answers

1

Use the function srand((unsigned) time(NULL)), as exemplified below:

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

int main()
{
    const int MAX = 10;
    int i;
    srand((unsigned)time(NULL));
    for(i = 0; i < MAX; i++)
        printf("Elemento %d = %d\n", i, rand()%MAX);
    return 0;
}

With this code, 10 numbers will be printed on the screen and all are between 0 and 9, inclusive.

  • 2

    For the curious: srand comes from Seed Random /random number. The random number algorithm of the rand works on generating a new number on top of the previous seed, then it updates the seed to use again

1

Put all possible numbers into an array; shuffle that array; then use the required values.

int valores[] = {4, 5, 6, 7, 8, 9,
                 14, 15, 16, 17, 18, 19,
                 24, 25, 26, 27, 28, 29}; // 18 valores, para 16 posicoes
shuffle(valores); // ver, por exemplo, https://en.wikipedia.org/wiki/Fisher-Yates_shuffle

for (i = 0; i < 4; i++) {
    for (j = 0; j < 4; j++) {
        matrix[i][j] = valores[4*i + j];
    }
}

Edit

To fill the array depending on the degree of difficulty you can do

for (i = 0; i < lim_col * lim_linha; i++) valores[i] = i / 2 + 1;

2nd Act

I made a program that does what you want.

#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>

int randto(int n) {
    int r, rmax = (RAND_MAX / n) * n;
    do r = rand(); while (r >= rmax);
    return r % n;
}

void shuffle(int *data, int n) {
    while (n > 1) {
        int p = randto(n--);
        int tmp = data[n];
        data[n] = data[p];
        data[p] = tmp;
    }
}

int main(int argc, char **argv) {
    if (argc != 2) exit(EXIT_FAILURE);
    int carta[16];
    int base[] = {1, 2, 3, 4, 5, 6, 7, 8};
    int n;
    int dificuldade;
    srand(time(0));
    dificuldade = atoi(argv[1]);
    switch (dificuldade) {
        default: return 1; break;
        case 1: n = 3; break;
        case 2: n = 5; break;
        case 3: n = 8; break;
    }

    shuffle(base, sizeof base / sizeof *base);
    for (int i = 0; i < n; i++) carta[i + n] = carta[i] = base[i];
    shuffle(carta, 2 * n);

    printf("Seq:");
    for (int i = 0; i < 2 * n; i++) printf(" %d", carta[i]);
    printf("\n");

    return 0;
}

Output with different parameters was

% ./a.out 3
Seq: 2 7 8 3 6 1 4 1 5 5 7 6 8 3 4 2
% ./a.out 2
Seq: 1 5 7 1 5 8 4 4 7 8
% ./a.out 1
Seq: 5 2 6 6 2 5

Browser other questions tagged

You are not signed in. Login or sign up in order to post.