Create random numbers - c

this is my first question here, i'm making a little game, and for assigning the roles, i need random numbers. I have this code, but is possible that the numbers don't be repeated? Thanks.
void giveroles() {
srand(time(NULL));
int r = rand() % i + 1;
switch ( r ) { /* ... */ }
}

If you want to randomly assign a small set of numbers, rather than generate them at random, create a list of the numbers you want, and then randomise the order of the list (iterate over the list, randomly swapping entries).
For example:
int cards[52];
for(int i = 0 ; i < 52 ; i++)
{
cards[i] = i;
}
for(int i = 0 ; i < 1000 ; i++)
{
int r1 = rand()%52;
int r2 = rand()%52;
int t = cards[r1];
cards[r1] = cards[r2];
cards[r2] = t;
}
for(int i = 0 ; i < 52 ; i++)
{
printf("%d\n", cards[i]);
}
For completeness, it has been pointed out that shuffling in this fashion is biased. Here's a variation which should be unbiased:
cards[0] = 0;
for(int i = 1 ; i < 52 ; i++)
{
int r = rand() % (i+1);
cards[i] = cards[r];
cards[r] = i;
}
(it should be further noted that taking the module of rand() is also likely to be biased, as the range of rand() will not be an even multiple)

Take out the line srand(time(NULL));. You should in general only ever do this once in your program, e.g. at the start of main(), in order to randomize the seed used by subsequent calls to rand().

If you don't want to repeat random numbers, the solution is to keep track of which random numbers you have previously used, and if you get a "hit" in your list of existing numbers, try again.
Also, using srand(time(NULL)); should only be done once. I suspect this is more the question you were actually asking.

Related

How can I use the rand() function to generate a different number that hasn't been generated before?

// What I mean by this is shown by my example:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int i;
int a;
for (a = 0;a <10;a ++) {
i = (rand()%10)+1; // generates a number from 1-10
printf("%d\n", i);
}
// I would like for the loop to generate a number that gives a number that was not generated before. For example, an output such as:
1,3,6,2,8,9,4,10,5,7
instead of:
3,9,10,3,7,9,2,7,10,1
In other words, I would like no copies.
You obviously don't just want no copies, but you want every number in a given set exactly once. This is, as commented by Robert, similar to shuffling a deck of cards. You don't have "decks" in C, but you can model one as an array:
int deck[] = {1,1,1,1,1,1,1,1,1,1};
This should represent 10 different "cards" (identified by their index in the array), each available one time. Now, just write code that "draws" cards:
int i = 0; // starting point for searching for the next card to draw
for (int n = 10; n > 0; --n) // how many cards are left
{
int skip = rand() % n; // randomly skip 0 .. n cards
while (1)
{
if (deck[i]) // card still available?
{
if (!skip) break; // none more to skip -> done
--skip; // else one less to skip
}
if (++i > 9) i = 0; // advance index, wrapping around to 0
}
deck[i] = 0; // draw the card
printf("%d\n", i+1); // and print it out
}
of course, seed the PRNG (e.g. srand(time(0))) first, so you don't get the same sequence every time.
The idea shown in the question is to print numbers within a range, without repetition. Here is one way to do that, by putting each value into an array and swapping its elements around.
A variation could be that you don't want to use all the possible numbers, in that case just change PICKED.
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define ARRLEN 10
#define PICKED 10
int main(void) {
int array[ARRLEN];
srand((unsigned)time(NULL)); // seed the PRNG
for(int i = 0; i < ARRLEN; i++) { // generate the numbers
array[i] = i + 1;
}
for(int i = 0; i < ARRLEN; i++) { // shuffle the array
int index = rand() % ARRLEN;
int temp = array[i];
array[i] = array[index]; // by randomly swapping
array[index] = temp;
}
for(int i = 0; i < PICKED; i++) { // output the numbers
printf("%d ", array[i]);
}
printf("\n");
}
Program output:
9 8 4 5 1 10 7 3 6 2
The library's PRNG is not very random, but for many cases that is not important. If it is, better algorithms are available.

Iterate through an array with nonconsecutive integers

I'm writing a code that will call a function repeatedly for each value in the Fibonacci sequence. For instance, let's say I want to print the sequence number each iteration, but I also want to print it in iteration-number times in that particular iteration. I'll want my output to be
1 1 22 333 55555 88888888 ... and so on.
Currently, I have a for-loop set up that creates an array with the Fibonacci sequence:
for(index = 0; index < 10; index++)
{
fibonacci[index] = fibonacci[index] + fibonacci[index-1]+fibonacci[index-2];
}
I'm not sure where to proceed from here. I've experimented with adding additional for-loops both inside and outside this one, but I'm coming up short. Primarily the problem lies within the fact that the loop can't take on the sequene's nonconsecutive values.
You need to have a nested for loop, this means a for loop within your for loop for the repetitive display of characters.
int a = 0;
int b = 1;
int c = 0;
for (int i = 0; i < 10; i++){
c = a + b;
a = b;
b = c;
for(int x = 0; x < c; x++) {
System.out.print(c);
}
System.out.print(" ");
}

Assigning a random value to an array

I'm trying to
Get rid of the info in an array with 10 "spots".
Fill the array with (10) random numbers
My code till time
int main()
{
int numbers[10] = { 0 };
int randNumber = 0;
int i = 0;
for (int i = 0; i <= 10; i++)
{
srand(time(NULL));
randNumber = rand() % 10 + 1;
printf("Random number saved in the array: %d\n", randNumber);
i++;
}
getchar();
getchar();
return 0;
}
First of all, you need to move the srand(time(NULL)); out of the loop.
Otherwise, because, time() has a time granularity of 1 second, in a second, if called multiple times in the loop (within a second, probably), it will re-initialize the PNRG with the same seed and all the next call to rand() will give you the same random number.
Now, once you have the random numbers, you need to assign it to the each array member like numbers[i] = randNumber; inside the loop, but there's more to it. Your loop, at present is off by one. You need to change
for (int i = 0; i <= 10; i++)
to
for (int i = 0; i < 10; i++)
to stay within bounds.
Your array's size is 10, and this loop runs 11 times, causing an overflow. This will solve it:
for (int i = 0; i < 10; i++)
Also remove the increasing of the loop's iterator, i, from inside the loop body. Remove the line:
i++;

How to give struct objects random not matching x and y coordinates in C?

I am trying to do my homework, which is some sort of game.
This is a part of it and I'm trying to create a function which puts 18 (9 in one team and the other 9 in another) different players on the field. player is a struct which has a name and coordinates. So I tried to write this function and had several problems. I think I have mostly fixed them, but I don't understand what's wrong with it now. Basically this function gives all the players random x and y coordinates, but as I have to make sure that they don't match, I created 2 lists x's and y's. The program takes all the players and add's their x coordinates to x's list if the current player x coordinate matches any x coordinates in x's list, then the program checks the same player's y coordinate and checks if it matches the coordinate of y of the same object in y's list. So if both x and y math, then the program runs again by recursion. The problem I get is that the coordinates I get every time I run the program are same. they don't match but they are not really random cause they don't change when I run them again.
I think I have tried all my knowledge and skills but still can't understand the problem of my code.
Can you please tell me what's wrong with this code?
void random_positions()
{
int i,j;
int xs[17],ys[17];
for(i= 0; i<9 ; i++)
{
players[i][0].x = rand() % 25;
players[i][0].y = rand() % 25;
players[i][1].x = rand() % 25;
players[i][1].y = rand() % 25;
printf("A%d x = %d y = %d \n",i+1,players[i][0].x,players[i][0].y);
printf("B%d x = %d y = %d \n",i+1,players[i][1].x,players[i][1].y);
}
for(i = 0; i < 9 ; i++)
{
xs[i] = players[i][0].x;
xs[i+8] = players[i][1].x;
ys[i] = players[i][0].y;
ys[i+8] = players[i][1].y;
for(j = 0; j <= i ; j++)
{
//printf("j%d start\n",j);
if(i != j && xs[i] == xs[j])
{
//printf("i%d start\n",j);
if(ys[i] == ys[j])
{
return random_positions();
}
//("j%d done\n",j);
}
//printf("j%d done\n",j);
}
}
}
A computer is (usually) a deterministic machine; if you run the same program twice, you will get the same answer.
A random number generator generally takes a seed, an initial value that it uses to initialize itself before it starts producing random numbers; give it a different seed, and you will get a different sequence. One way to do this is to give it the current time as a seed:
#include <stdio.h>
#include <stdlib.h> /* srand, rand */
#include <time.h> /* time */
int main ()
{
/* initialize random seed: */
srand (time(NULL));
/* generate random number between 1 and 10: */
int num = rand() % 10 + 1;
printf("%d\n", num);
return 0;
}

Creating random numbers

I have a 2-dimensional array(3x7) with numbers between 0 to 20. I would like to randomly change the locations, hence it is randomly rearranged. But it seems that every time it is run it has the same locations.
int arr[numRows][numCols] = {{0,1,2,3,4,5,6},{7,8,9,10,11,12,13},{14,15,16,17,18,19,20}};
random_rearrange_num(arr);
void random_rearrange_num(int p[][numCols])
{
int temp = 0,k= 0,l = 0;
for(int i = numRows -1 ; i > 0 ; i--)
{
for (int j = numCols-1;j>0; j--)
{
k = 0 + rand()/(RAND_MAX/(2-0+1)+1);
l= 0 + rand()/(RAND_MAX/(6-0+1)+1);
temp = p[i][j];
p[i][j] = p[k][l];
p[k][l] = temp;
}
}
}
I have shown the neccessary part in the question. The full code is here: https://codereview.stackexchange.com/questions/9419/programming-of-3-x-7-trick
For example: it always loads up with this first
Second is this :
everytime i restart, the numbers are at the same location. How do i change it?
You should first initialize a seed with srand()
A common way to seed is:
srand (time(NULL));

Resources