# input question

• 04-11-2007
piyush_v
input question
im a 1st year uni student and im kinda stuck with this c assignment. Its supposed to be a yahtzee scoring program. read 5 values from the user and display the scoring options.
We're supposed to error check the input in 3 different ways
1)
correct format, ie the values should be separated by spaces and the number of spaces between each value doesnt matter
so 12345 is not the correct format but 1 2 3 4 5 is.
2)
range.needs to be between 1 and 6
3) frequency
there needs to be 5 dice values entered

THE PROBLEM

1)with my present code, if the user enters 12345 it is read as the correct input because im using the isdigit() function to sort out the numbers. hence 12345 is read the same way as 1 2 3 4 5. how can i get around this?
2) ive got 2 arrays, one which has the dice values and one which hs the frequency of each number on the dice. I need to find all the combinations of the dice entered and display the scoring options. ie, a straigt(1 2 3 4 5) is worth certian points, a full house( a pair and a 3 of a kind) is worth certain points. I dont no where to start with both these aspects

here is my code.
Code:

```#define FREQ 7 #include <stdio.h> #include <ctype.h> #include <stdlib.h> int main (int argc, char **argv) { int VALUES=0; int dice[VALUES]; int freq[FREQ]; int x = 0; int p = 0; int c; int sum = 0; int choice=0;         printf ("Please enter dice values: \n");         c = getchar();         while(c !=10)         {                 if (isdigit(c))                 {                         dice[x] = c-48;                         x = x + 1;                                 }                 c = getchar();         }                 VALUES = x;         for(x=0;x<VALUES;x++)         {                         if (dice[x]<1 || dice[x]>6)                 {                                printf("Value Out of Range.\n");                         exit(1);                 }         }               for(x=0;x<FREQ;x++)         {                 freq[x]=0;         }                for(x=0; x<VALUES;x++)         {                 p=0;                 p=dice[x];                 freq[p]+=1;         }         for(x=1; x < FREQ; x++)         {                 sum+=freq[x];         }         if ( sum<1 || sum>6)         {                 printf("Incorrect number of values.\n");                 exit(1);         }                 printf("\nYour dice values are: ");                         for(x=0;x<5;x++)         {                 printf(" &#37;d",dice[x]);         }         printf("\n\nPlease choose:\n1 -> Reroll some dice\n2 -> Reroll all dice\n3 -> Keep dice\n");                 choice = getchar();         if (choice-48 <1 || choice-48>3)         {                 printf("\nInvalid Choice.\n");                 exit(1);         }         return (0); }```
i no the indentation is all over the place. sorry!!

any help is appreciated.
• 04-11-2007
zacs7
Ah, Dunno about C99 VLAs but an array size of 0 sounds illegal,

Code:

```int VALUES=0; int dice[VALUES];```
So you go along with int dice[0]; the whole way, When you change the value of VALUE the size of dice isn't going to change... Unless C99 VLAs allow you to invent to array elements along the way... :|
• 04-11-2007
piyush_v
when i compile that code it seems to work! lol
that isint a major problem. what im really stuck at is how do i differenciate an input string of 12345 from 1 2 3 4 5
• 04-11-2007
zacs7
You can use sscanf or scanf PROVIDED you know how to use them and the risks behind them, I suggest you use fgets(..., ..., stdin); and sscanf(...);
• 04-11-2007
Noir
Quote:

You can use sscanf or scanf PROVIDED you know how to use them and the risks behind them
But how do you learn how to use them and the risks behind them if you don't ever use them? Anyone can read a reference on scanf() and be an expert on the details but still have no clue how to put them into practice. ;)
Quote:

what im really stuck at is how do i differenciate an input string of 12345 from 1 2 3 4 5
The formatting is really strict, so you can use scanf():
Code:

```if ( scanf( "%d%d%d%d%d", &dice[0], &dice[1], &dice[2], &dice[3], &dice[4] ) == 5 ) {   for ( i = 0; i < 5; i++ ) {     if ( dice[i] > 0 && dice[i] <= 6 ) {       // everything's okay     } else {       // error: out of range     }   } } else {   // error: too few numbers or a stream error }```
• 04-11-2007
piyush_v
thanks for that. it works!
last question: i need to figure out if the input numbers are in order, ie a straight.
there are 2 scoring options, a small straight and a straight, small straight being 4 dice in ascending order and straight being 5 dice in ascending order.

how do i figure this out
i was thinking of finding all the permutations out and storing them in an array(??) and then using a for loop to scan through them and if it came across one which suffised the conditions, it would assign a value of 1 to "true" a variable and break out of the loop. once this is done id use a if statement to see if there was a straight in there.
problem: how in the living world do i find out all the permutations ?
• 04-11-2007
Noir
Quote:

i was thinking of finding all the permutations out and storing them in an array(??) and then using a for loop to scan through them and if it came across one which suffised the conditions, it would assign a value of 1 to "true" a variable and break out of the loop. once this is done id use a if statement to see if there was a straight in there.
Either I don't really understand the problem, or you're totally over engineering the solution. :D All you have to do is find the longest sorted run. It's even easier because the smallest run that you're scoring is 4 out of 5, so you only have three possibilities:
Code:

```?1234 1234? 12345```
The logic for that is pretty simple and can probably be made simpler by someone smarter than I am. ;)
Code:

```int right_side = 0; for ( i = 1; i < 5; i++ ) {   if ( dice[i - 1] > dice[i] ) {     if ( i > 1 ) {       break;     } else {       right_side = 1;     }   } } if ( i == 5 ) {   if ( right_side ) {     // small straight   } else {     // straight   } }```
• 04-11-2007
piyush_v
tried it . now whever the options are displayed the "straight" always appears as one even if the input wasnt a straight
what am i doing wrong?
also right at the end there is a getchar to read the final input but it never allows me to do so and just ends the program?:S:S
Code:

```#define FREQ 7 #include <stdio.h> #include <ctype.h> #include <stdlib.h> int main(int argc, char **argv) {     int VALUES = 0;     int dice[VALUES];     int freq[FREQ];     int x = 0;     int p = 0;     int c;     int sum = 0;     int choice = 0;     int d = 0;     int triple = 0;     int four = 0;     int yahtzee = 0;     int sort[5];     int right_side = 0;     int s_straight = 0;     int straight = 0;     int count = 0;     int d_total = 0;     int score[count];     int temp;     int a, b;     int c_last;     printf("Please enter dice values: \n> ");     c = getchar();     while (c != 10) {         if (isdigit(c)) {             dice[x] = c - 48;             x = x + 1;         }         c = getchar();     }     VALUES = x;     for (x = 0; x < VALUES; x++) {         if (dice[x] < 1 || dice[x] > 6) {             printf("\nValue Out of Range.\n");             exit(1);         }     }     for (x = 0; x < FREQ; x++) {         freq[x] = 0;     }     for (x = 0; x < VALUES; x++) {         p = 0;         p = dice[x];         freq[p] += 1;     }     for (x = 1; x < FREQ; x++) {         sum += freq[x];     }     if (sum < 1 || sum > 6) {         printf("\nIncorrect number of values.\n");         exit(1);     }     printf("\nYour dice values are: ");     for (x = 0; x < 5; x++) {         printf(" &#37;d", dice[x]);     }     printf         ("\n\nPlease choose:\n1 -> Reroll some dice\n2 -> Reroll all dice\n3 -> Keep dice\n");     choice = getchar();     while (c != 10) {         if (choice - 48 < 1 || choice - 48 > 3) {             printf("\nInvalid Choice.\n");             exit(1);         } else {             printf("\n");         }     }     for (x = 0; x < 5; x++) {         d_total = d_total + dice[x];     }     for (x = 1; x < FREQ; x++) {         if (freq[x] == 2) {             d = 1;             break;         }     }     for (x = 1; x < FREQ; x++) {         if (freq[x] == 3) {             triple = 1;             break;         }     }     for (x = 1; x < FREQ; x++) {         if (freq[x] == 4) {             four = 1;             break;         }     }     for (x = 1; x < FREQ; x++) {         if (freq[x] == 5) {             yahtzee = 1;             break;         }     }     for (x = 0; x < 5; x++) {         sort[x] = dice[x];     }     for (a = 0; a < 4; a++)         for (b = a + 1; b < 5; b++)             if (sort[a] > sort[b]) {                 temp = sort[b];                 sort[b] = sort[a];                 sort[a] = temp;             }     for (x = 1; x < 5; x++) {         if (dice[x - 1] > dice[x]) {             if (x > 1) {                 break;             } else {                 right_side = 1;             }         }     }     if (x == 5) {         if (right_side == 1) {             s_straight = 1;         } else {             straight = 1;         }     }     if (choice == 51) {         printf("\nYour score options are:");     }     if (triple == 1) {         count = count + 1;         score[count] = d_total;         printf("\n%d -> Three of a Kind ( %d points)", count,               score[count]);     }     if (four == 1) {         count = count + 1;         score[count] = d_total;         printf("\n %d -> Four of a Kind ( %d points)", count,               score[count]);     }     if ((d == 1) && (triple == 1)) {         count = count + 1;         score[count] = 25;         printf("\n %d -> Full House ( %d points)", count, score[count]);     }     if (s_straight == 1) {         count = count + 1;         score[count] = 30;         printf("\n %d -> Small Straight ( %d points)", count,               score[count]);     }     if (straight == 1) {         count = count + 1;         score[count] = 40;         printf("\n %d -> Straight ( %d points)", count, score[count]);     }     if (yahtzee == 1) {         count = count + 1;         score[count] = 50;         printf("\n %d -> Yahtzee ( %d points)", count, score[count]);     }     {         count = count + 1;         score[count] = d_total;         printf("\n %d -> Chance ( %d points)", count, score[count]);     }     c_last = getchar();     while (c_last != 10) {         if (choice - 48 > 0 || choice - 48 < count) {             printf("\n>Your score is: %d points\n", score[choice - 48]);         }     }     return (0); }```
• 04-11-2007
whiteflags
> now whever the options are displayed the "straight" always appears as one even if the input wasnt a straight

That means Noir's code was wrong. I had a feeling it was but I make a habit of not talking too much. Mainly cause in this thread I wouldn't know much; I don't play dice games.

Mainly the steps for varifying a straight are
1. sort the dice.
2. check the tops of all the dice in a loop. The previous die should be one less than the next.
if ( dice[next] != dice[prev] + 1 ) break;
3. If the loop repeated four times, you hit a short straight. If it was five, that's a straight.

Please refactor some of your code later. Long C functions are a pain to debug and organize.
• 04-12-2007
Noir
Yeah, my code doesn't work now that I try it. This does though:
Code:

```int run = find_run( dice, 0, 5 ); if ( run == 5 ) {   puts( "straight" ); } else if ( run == 4 ) {   puts( "small straight" ); } else if ( find_run( dice, 1, 5 ) == 4 ) {   puts( "small straight" ); }```
and find_run() looks like this:
Code:

```int find_run( int dice[], int start, int end ) {   int length = 1;   for ( ; start < end - 1; start++ ) {     if ( dice[start] != dice[start + 1] - 1 ) {       break;     }     length++;   }   return length; }```
I really didn't want to run the loop again for the first small straight case, but I guess I'm not good enough to figure that one out yet. ;)