Creating random numbers - c

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));

Related

Initialize a minesweeper in c

I'm currently rewriting a minesweeper program in C using the CSFML library.
I'm having some issues at managing the initialization only after the first click, more precisely in the part where I'm supposed to set the tiles around the click empty.
I can't find a way to make these tiles empty without having a risk of removing some bombs.
Here's my init code block for now :
int current = 0;
temp.bombs = BOMB_EASY;
temp.difficulty = EASY;
temp.mapEasy = malloc(sizeof(sTILE *) * (Y_EASY + 1));
for (int i = 0; i < Y_EASY + 1 ; i++)
{
temp.mapEasy[i] = malloc(sizeof(sTILE) * (X_EASY + 1));
}
for (int i = 0; i < X_EASY + 1; i++)
{
temp.mapEasy[Y_EASY][i].type = 0;
}
while (current < BOMB_EASY)
{
for (int i = 0; i < Y_EASY; i++)
{
for (int j = 0; j < X_EASY; j++)
{
int isBomb = rand() % 10;
if (isBomb == 0 && current < BOMB_EASY && temp.mapEasy[i][j].type != 9)
{
temp.mapEasy[i][j].type = 9;
current++;
}
else if (temp.mapEasy[i][j].type != 9)
{
temp.mapEasy[i][j].type = 0;
}
}
}
}
for (int i = 0; i < Y_EASY; i++)
{
for (int j = 0; j < X_EASY; j++)
{
if (temp.mapEasy[i][j].type == 0)
{
temp.mapEasy[i][j].type = HowManyBombs(temp.mapEasy, i, j, Y_EASY, X_EASY);
}
temp.mapEasy[i][j].isRevealed = sfFalse;
temp.mapEasy[i][j].isFlagged = sfFalse;
}
}
}
I know my question might seem stupid and someone probably already answered it but I couldn't find the answer so thanks at the ones who will answer me.
Create an empty matrix
Fill it with n mines at random locations. Upon generating (x, y) coordinates, check if they are already taken.
If the coordinates are already taken, you should place the mine at the next available position.
For example by increasing x by 1, check if free, if not, increase x again. Upon reaching the end of the row, increase y instead and start over with x=0.
If you simply generate a new random number, your algorithm could in theory get forever stuck. In practice it will probably work, but I would expect such an algorithm to generate the grid slower1) than one that just picks the next free spot.
1) rand() call overhead is the most likely bottleneck in this algorithm. But also if you pick the next spot rather than calling rand() again, the CPU might be able to speculatively load (parts of) the array in prefetch data cache. This wouldn't be possible when the memory location is literally random each time you pick it.

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++;

Random Permutation Generation

I am having a hard time understand this code example out of my text book. I hope someone can better explain a part of this code then my book. I am sorry for the lack of comments in this program so I will try my best to be very specific in what I am asking. Ok has the title suggest this program is a "Random Permutation Generation". Where I get confused in the code is in the function called bldPerm()
Function bldPerm():
void bldPerm(int randNos[])
{
int oneRandno;
int haveRand[ARY_SIZE] = { 0 };
for (int i = 0 ; i < ARY_SIZE; i++)
{
do
{
oneRandno = rand() % ARY_SIZE;
} while (haveRand[oneRandno] == 1);
haveRand[oneRandno] = 1;
randNos[i] = oneRandno;
}
return;
}
I don't understand how and why the do while loop while(haveRand[oneRandno]) == 1; checks the array by comparing it to 1. Then what confuses me is that haveRand[oneRandno] = 1; is set to one in that element. Then that element being "1" is set to randNos[i] = oneRandno; and returns other numbers other then 1. The program works out of my book and does print out other numbers then 1 yet I just can't see how it works. I have been trying to warp my head around this what I am sure is a simple thing... yet I don't get it. So my question is can anyone explain what is going on in this function in detail and how it works?
FULL CODE:
#define _CRT_SECURE_NO_WARNINGS
#define ARY_SIZE 20
#include <stdio.h>
#include <stdlib.h>
void bldPerm(int randNos[]);
void printData(int data[], int size, int linesSize);
int main(void)
{
int randNos[ARY_SIZE];
printf("Begin Random Permutation Generation\n");
bldPerm(randNos);
printData(randNos, ARY_SIZE, 10);
return 0;
}
void bldPerm(int randNos[])
{
int oneRandno;
int haveRand[ARY_SIZE] = { 0 };
for (int i = 0 ; i < ARY_SIZE; i++)
{
do
{
oneRandno = rand() % ARY_SIZE;
} while (haveRand[oneRandno] == 1);
haveRand[oneRandno] = 1;
randNos[i] = oneRandno;
}
return;
}
void printData(int data[], int size, int linesSize)
{
int numPrinted = 0;
printf("\n");
for (int i = 0; i < size; i++)
{
numPrinted++;
printf("%2d ", data[i]);
if (numPrinted >= linesSize)
{
printf("\n");
numPrinted = 0;
}
}
printf("\n");
return;
}
We want to fill an array with a random permutation of the numbers 0,...,ARY_SIZE-1. This means these number in a completely random ordering.
void bldPerm(int randNos[]) {
int oneRandno;
We keep an array called haveRand which indicates if the number i has already been chosen for our permutation. If the number is chosen haveRand[i] will be set to 1. At the beginning no number is chosen, so we initialize it with 0.
int haveRand[ARY_SIZE] = { 0 };
For each position in our output array we randomly select one of the numbers which have not been selected yet.
for (int i = 0 ; i < ARY_SIZE; i++)
{
Lets find a number which has not been selected yet.
do
{
To do this we sample any random number and call it oneRandno.
oneRandno = rand() % ARY_SIZE;
We check if it not chosen yet. If this is the case, then haveRand[oneRandno] is 0 and the while look will finish. Otherwise we continue and try a new.
} while (haveRand[oneRandno] == 1);
No we mark the selected number as chosen by setting haveRand[oneRandno] to 1.
haveRand[oneRandno] = 1;
Write the chosen number to the output array.
randNos[i] = oneRandno;
}
}
This algorithm is actually quite bad... For example to fill the last element there is only one candidate left as all other numbers are already selected. But the while loop tries to find this number by random sampling which can take a long time.
I would recommend creating an array with numbers 0 to ARY_SIZE-1 and use the Fisher-Yates algorithm to shuffle them.
I went through the code and wrote some comments with the code, i hope that clears it up.
void bldPerm(int randNos[]) // here you give an array of random numbers that is empty
{
// declare an int to store the randomly generated number
int oneRandno;
// initialize an array to store random numbers of size ARY_SIZE
int haveRand[ARY_SIZE] = { 0 };
// now loop while i is smaller then ARY_SIZE and increment i
for (int i = 0 ; i < ARY_SIZE; i++)
{
// here do generate the random number
do
{
// oneRandno will ALWAYS be between -1 and ARY_SIZE
// or i.o.w. from 0 to ARY_SIZE - 1
oneRandno = rand() % ARY_SIZE;
}
// because the numbers have to be unique, if oneRandno
// was already generated loop again
while (haveRand[oneRandno] == 1);
// Set to 1 because the next iteration oneRandno could have the same value,
// however very unlikely because rand() has a period of at least 2^32 which
// gives you enough room to have it generate a whole lot of numbers before
// it generates the same number again. So basically the while loop will
// never loop and act like a glorified if statement.
// and that the values in randNos should unique, if oneRandno has the
// same value the do while loop will iterate once more
// and generate another oneRandno
haveRand[oneRandno] = 1;
// finally store the uniquely generated number
randNos[i] = oneRandno;
//go to the next iteration
}
return;
}

Create random numbers

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.

Resources