This forum is in archive mode. You will not be able to post new content.

Author Topic: [C] Srand function  (Read 2828 times)

0 Members and 1 Guest are viewing this topic.

Offline Code.Illusionist

  • Royal Highness
  • ****
  • Posts: 687
  • Cookies: 39
  • Compile or die trying
    • View Profile
[C] Srand function
« on: April 15, 2013, 01:10:08 PM »
Here is the problem. When i call srand and rand function inside main function everything works totaly fine. BUT, when I put srand and rand inside some of my functions it doesen't work. Even when I use rand as parameter and call srand from main still no good. by the way, my application should give random solution for chess problem. And problem is to set 8 rocks on board so they don't att each other. I have solution for it. only random number don't work as it should.  Numbers go like: 8 1 2 3 4 5 6 7 (mostly that combination) and letter function on simular principe. Here is code:
Code: [Select]
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <time.h>
void create_array(int niz[]);
void random_numbers(int niz[], int k);
void random_characters(char niz[], int k);
void show_result(int niz[], char niz1[]);
int main(int argc, char *argv[])
{
    srand(time(NULL));
  int A[8];
  char B[8] = {65,66,67,68,69,70,71,72};
 create_array (A);
random_ numbers (A, rand()%7+1);
random_ characters (B, rand()%7+1);
puts("Rock will not attack each other if you put them like this:");
show_result(A,B);
  system("PAUSE");
  return 0;
}
void create_array (int niz[]) {
     int i;
    for (i = 0; i < 8 ; i++)
 niz[i] = i+1;     
     }
void random_ numbers (int niz[], int k) {
     int i,j,temp;
     for (i = 0; i < 8 ; i++) {
  j = k;
  temp = niz[i];
  niz[i] = niz[j];
  niz[j] = temp;
     }
}
void random_ characters (char niz[], int k) {
         int i,j,temp;
     for (i = 0; i < 8 ; i++) {
  j = k;
  temp = niz[i];
  niz[i] = niz[j];
  niz[j] = temp;
     }
     }
void show_result(int niz[], char niz1[]) {
     int i;
     for(i=0;i < 8 ; i++)
     printf("%c%d  ",niz1[i],niz[i]);
     printf("\n");
     }
Vae Victis - suffering to the conquered

Offline 0poitr

  • Peasant
  • *
  • Posts: 149
  • Cookies: 64
    • View Profile
Re: [C] Srand function
« Reply #1 on: April 15, 2013, 03:23:33 PM »
What do you mean by 'it doesen't work.' ? What values does it return?
Imagination is the first step towards Creation.

Offline Code.Illusionist

  • Royal Highness
  • ****
  • Posts: 687
  • Cookies: 39
  • Compile or die trying
    • View Profile
Re: [C] Srand function
« Reply #2 on: April 15, 2013, 05:51:18 PM »
Insted of generating random numbers like 3 4 5 2 1 7 6 8 it always return 8 1 2 3 4 5 6 7 (most of time return that order of numbers. And If I transfer function inside main (only code, not really function), it works perfectly. It generate random numbers from 1-8. But in function it's buged. Same with characters.
Vae Victis - suffering to the conquered

Offline Neea

  • Peasant
  • *
  • Posts: 83
  • Cookies: 19
  • Laboris Gloria Ludi
    • View Profile
Re: [C] Srand function
« Reply #3 on: April 15, 2013, 06:33:28 PM »
From my experience rand doesn't really generate random numbers, it all depends on the seed you pick ... so if you pick only one seed, and use rand more times the numbers won't exactly be random. I'm not sure if this answers your problem, but i hope it can give you some ideas where to look for the issue. Also normally if you have your srand/rand code in main or in a function it shouldn't be a difference.


http://linux.die.net/man/3/srand Maybe this can also be of any help.
<!--Here be Cthulhu -->

Offline Xires

  • Noob Eater
  • Administrator
  • Knight
  • *
  • Posts: 379
  • Cookies: 149
    • View Profile
    • Feed The Trolls - Xires
Re: [C] Srand function
« Reply #4 on: April 15, 2013, 06:50:53 PM »
First, ORGANIZE YOUR DAMNED CODE!  You cannot expect to spot errors if your code is a horrifying mess.  Keep it organized and correctly tabulated.

Second, CHECK THE CODE!  The code posted includes spaces after "random_".  The compiler should throw a bitch-fit.  If it doesn't, get a new one.

Third, CHECK YOUR RESULTS!  This code works perfectly fine(once the syntax elements are fixed).  It gives different values each time it's run.

Code: (bash) [Select]
$ ./code.illusionist-srand
Rock will not attack each other if you put them like this:
B4 H1 A2 C8 D3 E5 F6 G7
$ ./code.illusionist-srand
Rock will not attack each other if you put them like this:
G5 A1 B2 C3 D8 E4 H6 F7
$ ./code.illusionist-srand
Rock will not attack each other if you put them like this:
B7 H1 A2 C3 D4 E5 F8 G6
$ ./code.illusionist-srand
Rock will not attack each other if you put them like this:
B5 H1 A2 C3 D8 E4 F6 G7
$

Here's the organized & corrected code:
Code: (c) [Select]
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <time.h>

void create_array(int niz[]);
void random_numbers(int niz[], int k);
void random_characters(char niz[], int k);
void show_result(int niz[], char niz1[]);

int main(int argc, char *argv[]) {
int A[8];
char B[8] = {65,66,67,68,69,70,71,72};

srand(time(NULL));

create_array (A);

random_numbers(A, rand()%7+1);
random_characters(B, rand()%7+1);

puts("Rock will not attack each other if you put them like this:");

show_result(A,B);

return 0;
}

void create_array(int niz[]) {
int i;

for (i = 0; i < 8 ; i++)
niz[i] = i+1;
}

void random_numbers(int niz[], int k) {
int i,j,temp;

for (i = 0; i < 8 ; i++) {
j = k;

temp = niz[i];
niz[i] = niz[j];
niz[j] = temp;
}
}

void random_characters(char niz[], int k) {
int i,j,temp;

for (i = 0; i < 8 ; i++) {
j = k;

temp = niz[i];
niz[i] = niz[j];
niz[j] = temp;
}
}

void show_result(int niz[], char niz1[]) {
int i;

for(i=0;i < 8 ; i++)
printf("%c%d  ",niz1[i],niz[i]);

printf("\n");
}
-Xires

Offline WirelessDesert

  • Knight
  • **
  • Posts: 356
  • Cookies: 10
  • I think...
    • View Profile
Re: [C] Srand function
« Reply #5 on: April 15, 2013, 06:55:09 PM »
It works fine for me after fixing some function names, what compiler are you using?
Xires was faster and activated rage mode. Nice.
Check out my arduino project: Moving car - School project!
"I'm like current, I always take the easiest route."

Offline Code.Illusionist

  • Royal Highness
  • ****
  • Posts: 687
  • Cookies: 39
  • Compile or die trying
    • View Profile
Re: [C] Srand function
« Reply #6 on: April 15, 2013, 07:10:53 PM »
@Xires , I still recive wrong output. You see, whenever I call this rand function I get A1 and it's always A1. Why? It can be either A2, A3, A4, A5, A6, A7, A8 , and also A is always on second place. It should be randomly other not like this. If i use excatly the same peace of code but without functions, and I set them in main function like this:
Code: [Select]
#include <stdio.h>
#include <stdlib.h>
#define nl printf("\n")

int main(int argc, char *argv[])
{
int A[8];
        char B[8] = {65,66,67,68,69,70,71,72};
        srand(time(NULL));
        int i,j,temp;
        for (i = 0; i < 8 ; i++)
                A[i] = i+1;
        for (i = 0; i < 8 ; i++) {
                j = rand()%7+1;
                temp = A[i];
                A[i] = A[j];
                A[j] = temp;
        }
        for (i = 0; i < 8 ; i++) {
                j = rand()%7+1;
                temp = B[i];
                B[i] = B[j];
                B[j] = temp;
        }
        puts("Rock will not attack each other if you put them like this:");
        for(i=0;i < 8 ; i++)
        printf("%c%d  ",B[i],A[i]);
        printf("\n");
  system("PAUSE");   
  return 0;
}

Everything works perfectly! Just why?
« Last Edit: April 15, 2013, 07:11:59 PM by Code.Illusionist »
Vae Victis - suffering to the conquered

Offline Neea

  • Peasant
  • *
  • Posts: 83
  • Cookies: 19
  • Laboris Gloria Ludi
    • View Profile
Re: [C] Srand function
« Reply #7 on: April 15, 2013, 07:41:08 PM »
Answer is easy ....
In the original code with the functions, you get similar output like this one :

F2  A8  B1  C3  D4  H5  E6  G7 
B7  H1  A2  C3  D4  E5  F8  G6 
E5  A1  B2  C3  H8  D4  F6  G7 
H3  A1  B8  C2  D4  E5  F6  G7 
C7  A1  H2  B3  D4  E5  F8  G6 
H8  A1  B2  C3  D4  E5  F6  G7 
While in the main full block version you get:



F3  C1  B7  E2  G5  D6  H4  A8 
C7  H1  F2  B6  G3  D8  E5  A4 
G2  D5  B4  F7  C8  A3  H1  E6 
E6  G4  C1  A8  B3  F7  H2  D5 
C3  D4  H5  A8  E7  G1  F6  B2


BECAUSE ... when you generate the random number in the main block (not the function calls) you do it after the for starts, so for every for loop you do you generate a new random number..
While when you generate the number in the random_num(param, rand()%8) you use is the for the same number you generate in the call function. So if random_num(param,8) you're gonna use 8 the same value, in every for iteration.


Hope that clears some things up.
<!--Here be Cthulhu -->

Offline Code.Illusionist

  • Royal Highness
  • ****
  • Posts: 687
  • Cookies: 39
  • Compile or die trying
    • View Profile
Re: [C] Srand function
« Reply #8 on: April 15, 2013, 09:40:06 PM »
Ohhh, it finaly does. But still don't know is it possible to use it in function somehow?
EDIT: I solved it on some wierd way. I combined two functions in one so I call srand only ONCE, but I can call rand 2 times. Here is code:
Code: [Select]
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <time.h>

void create_array(int niz[]);
void generate_random(int niz[], char niz1[]);
void show_result(int niz[], char niz1[]);

int main(int argc, char *argv[]) {

        int A[8];
        char B[8] = {65,66,67,68,69,70,71,72};
       
        create_array(A);
        generate_random(A,B);
        puts("Rock will not attack each other if you put them like this:");
        show_result(A,B);
        system("PAUSE");
        return 0;
}
void create_array(int niz[]) {
        int i;
        for (i = 0; i < 8 ; i++)
                niz[i] = i+1;
}
void generate_random(int niz[], char niz1[]) {
        int i,j,e,temp,temp1;
        srand(time(NULL));
        for (i = 0; i < 8 ; i++) {
                j = rand()%7+1;
                e = rand()%7+1;
                temp = niz[i];
                temp1 = niz1[i];
                niz[i] = niz[j];
                niz1[i] = niz1[e];
                niz[j] = temp;
                niz1[e] = temp1;
        }
}
void show_result(int niz[], char niz1[]) {
        int i;
        for(i=0;i < 8 ; i++)
        printf("%c%d  ",niz1[i],niz[i]);
        printf("\n");
}
If you ask me I don't know why it works but it does. XD
« Last Edit: April 15, 2013, 11:43:41 PM by Code.Illusionist »
Vae Victis - suffering to the conquered

Offline Xires

  • Noob Eater
  • Administrator
  • Knight
  • *
  • Posts: 379
  • Cookies: 149
    • View Profile
    • Feed The Trolls - Xires
Re: [C] Srand function
« Reply #9 on: April 16, 2013, 06:52:57 AM »
Answer is easy ....
In the original code with the functions, you get similar output like this one :

F2  A8  B1  C3  D4  H5  E6  G7 
B7  H1  A2  C3  D4  E5  F8  G6 
E5  A1  B2  C3  H8  D4  F6  G7 
H3  A1  B8  C2  D4  E5  F6  G7 
C7  A1  H2  B3  D4  E5  F8  G6 
H8  A1  B2  C3  D4  E5  F6  G7 
While in the main full block version you get:



F3  C1  B7  E2  G5  D6  H4  A8 
C7  H1  F2  B6  G3  D8  E5  A4 
G2  D5  B4  F7  C8  A3  H1  E6 
E6  G4  C1  A8  B3  F7  H2  D5 
C3  D4  H5  A8  E7  G1  F6  B2


BECAUSE ... when you generate the random number in the main block (not the function calls) you do it after the for starts, so for every for loop you do you generate a new random number..
While when you generate the number in the random_num(param, rand()%8) you use is the for the same number you generate in the call function. So if random_num(param,8) you're gonna use 8 the same value, in every for iteration.


Hope that clears some things up.

Decent observation.  I thought that this was expected behavior but I guess I just didn't understand the OP correctly.
-Xires

Offline Xires

  • Noob Eater
  • Administrator
  • Knight
  • *
  • Posts: 379
  • Cookies: 149
    • View Profile
    • Feed The Trolls - Xires
Re: [C] Srand function
« Reply #10 on: April 16, 2013, 06:56:47 AM »
Ohhh, it finaly does. But still don't know is it possible to use it in function somehow?
EDIT: I solved it on some wierd way. I combined two functions in one so I call srand only ONCE, but I can call rand 2 times. Here is code:
Code: [Select]
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <time.h>

void create_array(int niz[]);
void generate_random(int niz[], char niz1[]);
void show_result(int niz[], char niz1[]);

int main(int argc, char *argv[]) {

        int A[8];
        char B[8] = {65,66,67,68,69,70,71,72};
       
        create_array(A);
        generate_random(A,B);
        puts("Rock will not attack each other if you put them like this:");
        show_result(A,B);
        system("PAUSE");
        return 0;
}
void create_array(int niz[]) {
        int i;
        for (i = 0; i < 8 ; i++)
                niz[i] = i+1;
}
void generate_random(int niz[], char niz1[]) {
        int i,j,e,temp,temp1;
        srand(time(NULL));
        for (i = 0; i < 8 ; i++) {
                j = rand()%7+1;
                e = rand()%7+1;
                temp = niz[i];
                temp1 = niz1[i];
                niz[i] = niz[j];
                niz1[i] = niz1[e];
                niz[j] = temp;
                niz1[e] = temp1;
        }
}
void show_result(int niz[], char niz1[]) {
        int i;
        for(i=0;i < 8 ; i++)
        printf("%c%d  ",niz1[i],niz[i]);
        printf("\n");
}
If you ask me I don't know why it works but it does. XD

Use srand() in main() only.  And only call srand() once.  The 'rand()' function performs a relatively simple mathematical algorithm that generates numbers in sequence.  The 'srand()' function simply populates some starting information for subsequent calls to 'rand()'.  Seeding more than once can lower the level of randomness.  Seeding too close to the call to rand() can do much the same thing.  Therefore, it's best practice to seed at the function start and call rand() whenever you need it afterward, preferably as far from the srand() call as possible.
-Xires

 



Want to be here? Contact Ande, Factionwars or Kulverstukas on the forum or at IRC.