1. ## Advice on a college project

Hi, I have to make a random number game for a project.

It's a single player game consisting of up to 3 goes per round and 6 rounds.

1. Generate 5 random numbers from 1 to 6 (inclusive)
2. Enter a row to score in
3. Calculate: bonus of 35 awarded if total score>=63
4. Calculate the total score.

5.End game when all 6 rounds/rows completed.

Wondering if anyone could give some advice on how to get started. I tried using rand but I was just generating the same numbers each time. Any help would be appriciated.

2. > I tried using rand but I was just generating the same numbers each time.
Lemme guess, you were calling srand() at the same time.

Don't do this.
Call srand() either not at all, or exactly ONCE at the start of main.

3. Code:
```#include <stdio.h>
#include <stdlib.h>

int main()
{
int i;
int diceRoll;

for(i=0; i<20; i ++){
diceRoll = (rand()%6) +1;
printf("%d \n", diceRoll);
}
return 0;
}```
That what I was trying to do with the random dice roll. Thanks flp1969 I am reading that now.

4. That what I was trying to do with the random dice roll
You need to specify an initial "random" seed before using rand():

Code:
```#include <stdio.h>
#include <stdlib.h>
#ifndef _WIN32
#include <unistd.h>
#include <fcntl.h>
#else
#include <time.h>
#endif

#ifndef _WIN32
static unsigned int getRandomSeed( void )
{
int fd;
unsigned int r;

if ( ( fd = open( "/dev/urandom", O_RDONLY ) ) < 0 )
{
fputs( "ERROR: Cannot open random device.\n", stderr );
exit( EXIT_FAILURE );
}

if ( read( fd, &r, sizeof r ) < 0 )
{
close( fd );
fputs( "ERROR: Cannot read from random device.\n", stderr );
exit( EXIT_FAILURE );
}

close( fd );

if ( r > RAND_MAX ) r -= RAND_MAX;

return r;
}
#endif

#define TRIES 20

int main( void )
{
int i, dice;
unsigned int t;

// Initialize random seed...
#ifndef _WIN32
// ... just an example using /dev/urandom device...
t = getRandomSeed();
#else
// ... otherwise, using current timestamp.
t = time( NULL );
#endif
srand( t );

for ( i = 0; i < TRIES; i++ )
{
dice = rand() % 6 + 1;

printf( "%d ", dice );
}
putchar( '\n' );

return EXIT_SUCCESS;
}```
Code:
```\$ ./test
1 4 5 6 2 1 3 2 3 1 6 1 5 1 4 4 1 6 3 1
\$ ./test
5 4 6 4 5 3 2 2 3 6 6 6 3 6 6 3 5 2 2 4
\$ ./test
6 3 6 6 2 5 4 3 2 6 6 4 1 6 1 4 3 1 3 6
\$ ./test
3 5 2 6 5 5 5 6 1 2 6 2 5 1 1 2 6 3 4 4```
But notice... LCGs are less random in lower bits...

5. Thanks for the reply. Im fairly new to coding not even sure what a random seed is?

6. Originally Posted by Macman21
Thanks for the reply. Im fairly new to coding not even sure what a random seed is?
The rand() function is often implemented using a "pseudo random number generator" called "linear congruence generator" (LCG). Most (if not all) "pseudo random number generators" depends on an initial value to "make believe" the next call will return a "random" number (it is NOT random, just appears to be!).

LCG uses a formula like:

next_x = ( prev_x * a + b ) % c

the "initial" prev_x is called a "random seed". If you don't give one, using srand() function, rand() will use, always, the same seed and will give you always the same sequence of "pseudo random numbers"... That's why you MUST call srand(), once, with kind of a random value, "seeding" the algorithm used by rand().

7. With a correct call to srand() with a unique value each time, you will get a different set of values from rand() each time. Only call srand() ONCE in the program!

With no call to srand(), the results will be the same each time.

Use time() to get a unique value each time the program is run. time() returns a UNIX Epoch time value.

Run the following code, with and without the call to srand() and see the results:
Code:
```#include <stdio.h>
#include <stdlib.h>
#include <time.h>

#define N 10

int main(void)
{
srand(time(NULL)); // Seeds rand() to the current UNIX Epoch time value

for (int i = 0; i < N; ++i)
{
printf("Random #%d: %d\n", i, rand() % 100);
}

return 0;
}```
Read the manpage for rand() and srand()

8. Originally Posted by rstanley
Use time() to get a unique value each time the program is run. time() returns a UNIX Epoch time value.
I adivce against this affirmative. For example:
Code:
```#include <stdio.h>
#include <stdlib.h>
#include <time.h>

#define N 10

int main ( void )
{
srand ( time ( NULL ) );

for ( int i = 0; i < N; ++i )
printf ( "%d ", rand() % 100 );
putchar( '\n' );

return 0;
}```
Code:
```\$ cc -O2 -o test test.c
\$ for i in {1..10}; do ./test; done
74 18 75 97 21 7 4 49 71 80
74 18 75 97 21 7 4 49 71 80
74 18 75 97 21 7 4 49 71 80
74 18 75 97 21 7 4 49 71 80
74 18 75 97 21 7 4 49 71 80
74 18 75 97 21 7 4 49 71 80
74 18 75 97 21 7 4 49 71 80
74 18 75 97 21 7 4 49 71 80
74 18 75 97 21 7 4 49 71 80
74 18 75 97 21 7 4 49 71 80```
Clearly NOT a unique set of values each time the program runs.

9. flp1969:

Yes, if you run my program 10 times within one second, yes, it will seed with the same value, but this is NOT how 99.999% of programs are run in real life!

Considering the OP is a college student, LEARNING C, my solution should be sufficient.

10. Hi I have made some progress on the code. Thanx for the help. Here is what I have so far. This is what we have to add to the code now if anyone could help out.

1. Allow the player to select which values to keep and which to regenerate each time.
2. Ensure that user selects a valid row each time (a row not previously used).
3. Only display a value in a row if it is used (i.e.: display nothing if the row is unused)

Code:
```#include <stdio.h>
#include <stdlib.h>
#include <time.h>

int dice[5], Row, score[5]={0,0,0,0,0,}, reroll=1, total,bonus=63;
int fRoll();
void fTotal();
void fScore();

int main() {
int i, s;
srand(time(NULL));
do {
for (s = 0; s < 6; s++) {
for (int i = 0; i < 5; i++) {
dice[i] = fRoll();
printf ("\t%d: %d\n",i+1, dice[i]);
}
if (reroll<3){
do {
printf ("\n\tRow to use? 0 to Reroll ");
scanf ("%i",&Row);
} while (Row<0 || Row>6);
if (Row == 0 ) {
printf ("\n\t---Reroll---\n");
reroll ++;
s--;
dice[i] = fRoll();
}else if (Row == 1){
fScore();
}else if (Row == 2){
fScore();
}else if (Row == 3){
fScore();
}else if (Row == 4){
fScore();
}else if (Row == 5){
fScore();
}else if (Row == 6){
fScore();
} else if (Row > 6 || Row < 1){
printf ("Please enter a number between 1 and 6!\n");
s--;
}
}else if (reroll==3){
do {
printf ("\n\tRow to use? Can't Reroll! ");
scanf ("%i",&Row);
} while (Row<1 || Row>6);

if (Row == 1){
fScore();
}else if (Row == 2){
fScore();
}else if (Row == 3){
fScore();
}else if (Row == 4){
fScore();
}else if (Row == 5){
fScore();
}else if (Row == 6){
fScore();
} else if (Row > 6 || Row < 1){
printf ("Please enter a number between 1 and 6!\n");
s--;
}
}
}
}while (s < 6);
fTotal();
}

int fRoll() {
int dice[5];
for (int i = 0; i < 5; i++) {
dice[i] = (rand()%6)+1;
return dice[i];
}
}

void fTotal(){
total=0;
for (int i = 1; i < 7; i++) {
total = total + score[i];
}
if (total >= 63){
total = total + 35;
}
printf ("\n\tTotal is %i", total);
}

void fScore(){
score[Row] = 0;
for (int i = 0; i < 5; i++){
if (dice[i] == Row){
score[Row] += Row;
}
}
reroll =1;
bonus = bonus - score[Row];
printf ("\tScore = %i\n\n", score[Row]);
printf ("\tYou now need %i to get the bonus\n\n",bonus);
}```