1

I'm trying to build a memory game and I want to ask how I can generate a randomic number with just one repetition. Like 1-1, 2-2, 3-3. I will paste here my function that I created and tell me if I have to create another function just to create a condition to create just a pair from numbers.

// function to fulfill the table
void preencher_mesa(int matriz[4][4], int dificuldade)
{
    int i, j;
    int lim_col, lim_linha; // limits of the matriz

    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) // difficulty == 1
            {
                matriz[i][j] = (rand()%3)+1;
            }
            else if(dificuldade == 2) // difficulty == 2
            {
                matriz[i][j] = (rand()%6)+1;
            }
            else if (dificuldade == 3) // difficulty == 3
            {
                matriz[i][j] = (rand()%8)+1;
            }
        }
    }

    mostrar_mesa(matriz); //showtable
}
Jay Kominek
  • 8,674
  • 1
  • 34
  • 51
  • this line: 'if(dificuldade == 1)/dificulty ==1' does not compile – user3629249 Jun 21 '15 at 23:52
  • this code does not handle the cases when dificuldate is <= 0 and/or >3 – user3629249 Jun 21 '15 at 23:54
  • 2
    suggest: always use spaces for indenting. Never tabs. This is because, depending on which wordprocessor/editor is being used (including the stackoverflow pages) The resulting display of the code will be different. While spaces (except for variable width font, which should not be used for code) is always the same – user3629249 Jun 21 '15 at 23:57
  • 3
    suggest: call the srand() function very early in the main() function, and then never call it again. – user3629249 Jun 21 '15 at 23:58
  • Do you mean you want a random number function that returns the same number consecutively twice, then another number twice, etc? For example, 3, 3, 75, 75, 10043, 10043, 91, 91? – user12205 Jun 22 '15 at 01:32
  • @user3629249: No rather *never* use space for indentation, only tabs, so I can choose myself how many spaces I want. It works perfectly fine then if you want a tab to be 2 spaces and I want it to be 8 spaces, as long as you use *spaces* for **alignment** everything will be in order and look just fine. – Jite Jun 24 '15 at 22:25
  • @Jite: that only works for leading tabs; once you've got past leading tabs, you need to use spaces to get sane looking layout. And you soon end up using spaces only -- well, it make take 10-15 years, but the chances are you will, Linux kernel conventions notwithstanding. (Take home: this is a contentious issue and agreement won't be reached and there are merits and demerits to both points of view.) – Jonathan Leffler Jun 26 '15 at 01:06
  • @JonathanLeffler: That's what I'm saying: Tabs for indentation and spaces for alignment. It will work fine as long as you don't start trying to align things on rows with different indentation (please don't do that) :-) – Jite Jun 26 '15 at 13:10

1 Answers1

1

If you have a 3x2 matrix that should be filled with the digits/numbers 1, 1, 2, 2, 3, 3 in some random permutation, then you could do something like:

  1. Allocate an array (vector) of the right size — 6 for the current example.
  2. Populate the array with the correct values — 1, 1, 2, 2, 3, 3 for the current example.
  3. Use an appropriate technique to shuffle the array, and then copy the shuffled data into the target 2D array.
  4. Or select a digit at random from the initial 6 options, then (if necessary) move the last digit into the hole and select the next digit from the remaining 5 options, etc.

You can use the Fisher-Yates shuffling algorithm. You might check in your copy of Knuth The Art of Computer Programming, Volume 2: Seminumerical Algorithms. Or you can look for expositions on Stack Overflow (such as Algorithm to select a single random combination of values, chosen because one of my Google searches also came across it).


Judging from the comments, you want duplicates from your rand() surrogate, so this should work:

int duprand(void)
{
    static int mode = 0;
    static int value = 0;
    if (mode == 0)
    {
        mode = 1;
        value = rand();
    }
    else
    {
        mode = 0;
    }
    return value;
 }

Or, more succinctly:

int duprand(void)
{
    static int mode = 0;
    static int value = 0;
    if (mode == 0)
        value = rand();
    mode = !mode;
    return value;
 }

Simply call duprand() each time you want a random number. You will get the same value twice in a row. This code doesn't provide a resynchronization method; if you want one, you can write one easily enough:

void sync_duprand(void)
{
    int i = duprand();
    int j = duprand();
    if (i != j)
       i = duprand();
}

What I really wanted was ...

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

extern void shuffle(int *array, int n);
/*
** rand_int() and shuffle() copied verbatim (but reformatted) from
** https://stackoverflow.com/a/3348142 - an answer by Roland Illig
** (https://stackoverflow.com/users/225757/roland-illig).
*/

static int rand_int(int n)
{
    int limit = RAND_MAX - RAND_MAX % n;
    int rnd;

    do
    {
        rnd = rand();
    } while (rnd >= limit);
    return rnd % n;
}

void shuffle(int *array, int n)
{
    int i, j, tmp;

    for (i = n - 1; i > 0; i--)
    {
        j = rand_int(i + 1);
        tmp = array[j];
        array[j] = array[i];
        array[i] = tmp;
    }
}

/* New code - but hardly novel code */
static void dump_matriz(int matriz[4][4])
{
    for (int i = 0; i < 4; i++)
    {
        for (int j = 0; j < 4; j++)
            printf("  %d", matriz[i][j]);
        putchar('\n');
    }
}

int main(void)
{
    int matriz[4][4];

    int *base = &matriz[0][0];
    for (int i = 0; i < 8; i++)
    {
        *base++ = i + 1;
        *base++ = i + 1;
    }

    printf("Before:\n");
    dump_matriz(matriz);

    shuffle(&matriz[0][0], 16);

    printf("After:\n");
    dump_matriz(matriz);

    return 0;
}

Sample output:

Before:
  1  1  2  2
  3  3  4  4
  5  5  6  6
  7  7  8  8
After:
  1  7  8  6
  6  2  5  8
  2  4  7  3
  3  5  1  4

Note that because there's no call to srand(), the permutation is fixed. (You might get a different result from what I show, but running this test multiple times will produce the same result each time on your machine.) Add a call to srand() with an appropriate initialization, and you get different sequences. Hack and chop to suit your requirements for smaller matrices.

Community
  • 1
  • 1
Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
  • After reading the question I thought the OP was asking how to make a random function that returns each number twice consecutively, as in, say, 3, 3, 75, 75, 10043, 10043, 91, 91 etc. I've written an answer for that but after reading yours I'm not sure whether I interpreted the question correctly (and thus whether I should post my answer)... What do you think? – user12205 Jun 22 '15 at 01:51
  • Returning the same number twice in a row isn't a big achievement, is it? You simply use the number twice. I presume that the requirement is more complex, therefore. – Jonathan Leffler Jun 22 '15 at 01:52
  • Yes @ace you should do that! Because I'm still thinking in a way to this works! – Lucca Mello Jun 24 '15 at 21:37
  • @LuccaMello: Assuming you want duplicates from your `rand()`, then: `int duprand(void) { static int mode = 0; static int value = 0; if (mode == 0) { mode = 1; value = rand(); } else { mode = 0; } return value; }` should do the job. Simply call `duprand()` each time you want a random number. You will get the same value twice in a row. This code doesn't provide a resynchronization method; if you want one, you can write one easily enough: `void sync_duprand(void) { int i = duprand(); int j = duprand(); if (i != j) i = duprand(); }`. – Jonathan Leffler Jun 24 '15 at 21:43
  • What I am needing at the moment is assuming that I have 8 pairs of numbers for example: (1,1)(2,2)(3,3),(4,4),(5,5),(6,6),(7,7),(8,8) and I need that I will get this number shuffle in a table, I want that this number get different positions in this table (matriz[4][4]). Level 1 - Easy- Just 3 pairs of number randomic in this table, level 2 - Medium 4 pairs, and Level 3 - Hard - 8 pairs @Jonathan Leffler – Lucca Mello Jun 24 '15 at 22:03
  • OK, so my original suggestion is what you're after. Go for it. SO searching on '`[c] fisher yates shuffle`' turns up usable code rather easily. – Jonathan Leffler Jun 24 '15 at 22:04