NO

Author Topic: YAHTZEE problem  (Read 6878 times)

jin_yeugh

  • Guest
YAHTZEE problem
« on: May 17, 2013, 11:12:36 PM »
I'm working on a very simple YAHTZEE type program which rolls 5 dice and stores the result of each die roll in an array element. The point of the program is to calculate the number of attempts until a YAHTZEE is achieved (5-of-a-kind). I'm having trouble getting the do-while loop to repeat. 

The code is a rough draft but I still don't see a problem. I'm guessing it's the problem with my while condition as it ends the loop prematurely.

thanks for the help!

Here's my code

Code: [Select]
//Yahtzee! VERY basic concept of game with one roll
#include<stdio.h>
#include<stdlib.h>
#include<time.h>

int throw1(void)
{
int i_die;
 
i_die = rand() % 6 + 1;
return ( i_die );
} //Declaring thow1() function before main()


int main(void)
{
int i_x = 1;
int i_total_rolls = 0;
int i_roll[5];
int i_total;
int i_a, i_b, i_c, i_d, i_e; //Naming integer variables with i_ prefix to lable them as integers
i_total = 0;

srand((unsigned)time(NULL)); //Generate seed from clock


//Initial roll
do
{
/*printf("Here's your roll...!\n\n");
puts("Dice:");*/
for( i_a = 0; i_a < 5; i_a ++ ) //for each number of dice, the loop iterates, labeling which die is displayed
{
i_b = i_a + 1; //Add 1 to i_a so that it counts from 1 up and not 0 (like the for loop dictates)
printf("  %d ", i_b);
}

putchar('\n');

for( i_d = 0; i_d < 5; i_d ++ )
printf("+---"); //Create a border for results. It is assembled piecewise, according to number of dice rolled

printf("+\n"); //finish border with '+'

for( i_c = 0; i_c < 5; i_c ++ )
{
i_roll[i_c] = throw1(); //Call throw1() function and store result in i_roll variable
printf("| %d ",i_roll[i_c]); //Display result
i_total += i_roll[i_c]; //Keep a running total
}

printf("|\n");

for( i_e = 0; i_e < 5; i_e ++ )
printf("+---"); //Bottom border created piecewise

printf("+\n");
i_total_rolls += i_x ++; //Tally number of attempts

   
}while( i_roll[0] != i_roll[1] && i_roll[0] != i_roll[2] && i_roll[0] != i_roll[3] && i_roll[0] != i_roll[4] ); //Check if all elements in array "i_roll" are equal
printf("total rolls until YAHTZEE: %d\n", i_total_rolls);
 

return(0);
}

« Last Edit: May 18, 2013, 12:44:51 AM by Bitbeisser »

Offline Bitbeisser

  • Global Moderator
  • Member
  • *****
  • Posts: 772
Re: YAHTZEE problem
« Reply #1 on: May 18, 2013, 01:11:07 AM »
Well, haven't been able to compile and run the code, but at a first glance it seems indeed that the while condition isn't quite right.
The condition is not testing what you mentioned the "point of the program" is. Write the condition in it's separate steps and maybe, for better understanding, write out the boolean operation instead of the actual C symbol. That should it make easier to understand...

Ralf

PS: I also added code tags around  your code so it's easier to read... ;)

Offline jj2007

  • Member
  • *
  • Posts: 536
Re: YAHTZEE problem
« Reply #2 on: May 18, 2013, 03:28:53 AM »
Hi Jin,
Your code compiles fine on my Pelles C installation.
If you replace all && in your While loop with ||, it will work as you expect it to do.

Offline Bitbeisser

  • Global Moderator
  • Member
  • *****
  • Posts: 772
Re: YAHTZEE problem
« Reply #3 on: May 18, 2013, 05:34:44 AM »
Hi Jin,
Your code compiles fine on my Pelles C installation.
The question was not to get the code compiling...
Quote
If you replace all && in your While loop with ||, it will work as you expect it to do.
Well, beside that we have a general rule not to do the (home)work for others, it doesn't really help if he doesn't understand why his original code doesn't work as he expected...

Ralf

Offline jj2007

  • Member
  • *
  • Posts: 536
Re: YAHTZEE problem
« Reply #4 on: May 18, 2013, 09:36:24 AM »
Hi Jin,
Your code compiles fine on my Pelles C installation.
The question was not to get the code compiling...

It wasn't until you declared that you couldn't compile it ("haven't been able to compile and run the code"). I just clarified that it does compile on an unmodified Pelles C installation. Or did you mean "had no time to paste it into a template and try"?

Quote
Quote
If you replace all && in your While loop with ||, it will work as you expect it to do.
Well, beside that we have a general rule not to do the (home)work for others, it doesn't really help if he doesn't understand why his original code doesn't work as he expected...

I guess Jin is intelligent enough to ask himself why it suddenly works, and find the answer himself. It is pretty obvious.

Offline Bitbeisser

  • Global Moderator
  • Member
  • *****
  • Posts: 772
Re: YAHTZEE problem
« Reply #5 on: May 20, 2013, 04:12:03 AM »
It wasn't until you declared that you couldn't compile it ("haven't been able to compile and run the code"). I just clarified that it does compile on an unmodified Pelles C installation. Or did you mean "had no time to paste it into a template and try"?
as in "Not having access to a system with Pelle's C installed". I was typing that response from a Linux system...
Quote
Quote
Quote
If you replace all && in your While loop with ||, it will work as you expect it to do.
Well, beside that we have a general rule not to do the (home)work for others, it doesn't really help if he doesn't understand why his original code doesn't work as he expected...
I guess Jin is intelligent enough to ask himself why it suddenly works, and find the answer himself. It is pretty obvious.
It might be obvious to you, but the basic problem of him (her?) is a very common one to programming newbies, understanding the basic logic of boolean comparison. Just telling him/her to replace the symbol isn't really helping, (s)he might have a chance to understand what was wrong when trying to rethink the logic. A wrong operator alone, now that would have been obvious...

Ralf

jin_yeugh

  • Guest
Re: YAHTZEE problem
« Reply #6 on: June 17, 2013, 11:41:44 PM »
Sorry for abandoning this post guys, I am truly a newbie and find myself going at things alone, forgetting entirely about the wealth of help I have in this forum so I rarely log in. I've also abandoned this program for lack of motivation, or out of frustration to be precise- tenacity being a skill I aim to hone as well.  Thank you, Ralf, for making my code more readable in my post. Also thank you to everyone for your input. As I've only begun to troubleshoot, I can merely report I found jj2007's advice to replace && with || worked in extending the loop beyond one cycle but I found the loop still broken and it either never ends or it ends in a non-yahtzee roll. I'll keep looking for the problem(s) with this new direction for troubleshooting. Thank you everyone!
-Evan

Offline Bitbeisser

  • Global Moderator
  • Member
  • *****
  • Posts: 772
Re: YAHTZEE problem
« Reply #7 on: June 18, 2013, 02:49:20 AM »
Sorry for abandoning this post guys, I am truly a newbie and find myself going at things alone, forgetting entirely about the wealth of help I have in this forum so I rarely log in. I've also abandoned this program for lack of motivation, or out of frustration to be precise- tenacity being a skill I aim to hone as well.  Thank you, Ralf, for making my code more readable in my post. Also thank you to everyone for your input. As I've only begun to troubleshoot, I can merely report I found jj2007's advice to replace && with || worked in extending the loop beyond one cycle but I found the loop still broken and it either never ends or it ends in a non-yahtzee roll. I'll keep looking for the problem(s) with this new direction for troubleshooting. Thank you everyone!
-Evan
As I already tried to mention, you have a general logic issue with your while loop, probably coming from a lack of properly understanding compounded boolean statements...  ;)

Ralf

jin_yeugh

  • Guest
Re: YAHTZEE problem
« Reply #8 on: June 18, 2013, 06:30:58 PM »
I have done quite a few changes to make the code more efficient and found the do-while loop to still be an issue. I must not fully understand the loop but it all makes sense to me the way I've written it. I also separated the part that checks for a yahtzee and it works fine until I put it inside the do-while loop; then, it becomes an endless loop. Here is the updated program:

Code: [Select]
//Yahtzee! VERY basic concept of game with one roll
#include<stdio.h>
#include<stdlib.h>
#include<time.h>

int throw1(void)
{
int i_die;
 
i_die = rand() % 6 + 1;
return ( i_die );
} //Declaring thow1() function before main()


int main(void)
{
int i_total_rolls = 0;
int i_roll[5];
int i_yahtzee[] = { 0, 0, 0, 0, 0 }; //Initialize i_yahtzee to zeros so loop doesn't terminate prematurely
int i_a, i_b, i_c, i_d; //Naming integer variables with i_ prefix to lable them as integers
//variables for for() loops


srand((unsigned)time(NULL)); //Generate seed from clock



do
{

//Generate dice rolls through throw1() function
for( i_c = 0; i_c < 5; i_c ++ )
{
i_roll[i_c] = throw1(); //Call throw1() function and store result in i_roll variable

}
///////////////


i_total_rolls ++; //Tally number of attempts

   //Check to see if all dice are equal
i_a = 0; //Start comparison at element 0 and compare to all other elements
for( i_b = 1; i_b < 5; i_b ++ ) //compare first die to four subsequent dice
{
if( i_roll[i_a] == i_roll[i_b] )
i_yahtzee[i_b] = 1;  //If all dice are equal
else
break; //If dice are not equal, exit comparison loop
}
////////////////////////


}while( !i_yahtzee[4] ); //Repeat loop until a yahtzee is rolled, indicated by the fifth element of "yahtzee" array being a '1'

putchar(7);
putchar(7);
putchar(7);

printf("total rolls until YAHTZEE: %d\n", i_total_rolls);


//Create border for dice roll display
for( i_d = 0; i_d < 5; i_d ++ )
printf("+---"); //Create a border for results. It is assembled piecewise, according to number of dice rolled
printf("+\n"); //finish border with '+'

//display dice rolls within border
for( i_d = 0; i_d < 5; i_d ++ )
printf("| %d ",i_roll[i_d]); //Display result

for( i_d = 0; i_d < 5; i_d ++ )
printf("+---"); //Bottom border created piecewise
printf("+\n");
////////////////////////////


return(0);
}

And here's the separated loop that checks for a yahtzee:

Quote
//Check for yahtzee by using status byte in an array

#include<stdio.h>

int main(void)
{
   int i_a, i_b;
   int i_roll[] = {3, 3, 3, 7, 3};
   int i_yahtzee[] = {0, 0, 0, 0, 0}; //Initialize i_yahtzee array to all 0s so loop doesn't terminate early
   
   //Check to see if all dice are equal
   do
   {
      i_a = 0; //Start comparison at element 0 and compare to all other elements
      for( i_b = 1; i_b < 5; i_b ++ ) //compare first die to four subsequent dice
      {
         printf( "%d %d\n", i_roll[i_a], i_roll[i_b] );
         if( i_roll[i_a] == i_roll[i_b] )
            i_yahtzee[i_b] = 1;  //If all dice are equal
         else
            break; //If dice are not equal, exit compariso loop
      }
      for( i_a = 0; i_a < 5; i_a ++ )
         printf( "%d ", i_yahtzee[i_a] );
      ////////////////////////
   } while( !i_yahtzee[4] );
   putchar(7);
   return(0);
}

jin_yeugh

  • Guest
Re: YAHTZEE problem
« Reply #9 on: June 19, 2013, 12:54:49 AM »
Thanks, but the problem actually lies in the do-while loop. In the code below I have an excerpt which checks the status of an element of an array and that part works fine until I contain it in a do-while loop.  I can't figure out what the problem is with my loop and am also not sure how else to implement the process of checking the element array.

Quote
//Check for yahtzee by using status byte in an array

#include<stdio.h>

int main(void)
{
   int i_a, i_b;
   int i_roll[] = {3, 3, 3, 3, 3
   };
   int i_yahtzee[] = {0, 0, 0, 0, 0}; //Initialize i_yahtzee array to all 0s so loop doesn't terminate early
   
   //Check to see if all dice are equal
   do {
      i_a = 0; //Start comparison at element 0 and compare to all other elements
      for( i_b = 1; i_b < 5; i_b ++ ) //compare first die to four subsequent dice
      {
         printf( "%d %d\n", i_roll[i_a], i_roll[i_b] );
         if( i_roll[i_a] == i_roll[i_b] )
            i_yahtzee[i_b] = 1;  //If all dice are equal
         else
            break; //If dice are not equal, exit compariso loop
      }
      for( i_a = 0; i_a < 5; i_a ++ )
         printf( "%d ", i_yahtzee[i_a] );
      ////////////////////////
   } while( !i_yahtzee[4] );
   putchar(7);
   return(0);
}

jin_yeugh

  • Guest
Re: YAHTZEE problem
« Reply #10 on: June 20, 2013, 11:28:15 PM »
So here's another update: I've greatly improved the efficiency of the program and have got it working 80% of the time. The other 20% an endless loop occurs. Since this is based on probability, it is likely that my end condition simply isn't met for a very long time, making it appear like an endless loop but not this often. Whatever advice you guys have would be great!

Code: [Select]
//Yahtzee! VERY basic concept of game with one roll
#include<stdio.h>
#include<stdlib.h>
#include<time.h>

int throw1(void)
{
int i_die;
 
i_die = ( rand() % 6 ) + 1;
return ( i_die );
} //Declaring thow1() function before main()


int main(void)
{
int i_total_rolls = 0;
int i_roll[5]; //Array to store the five dice rolls
int i_yahtzee[5]; //Array used to check status of roll- are all five dice the same?
int i_a, i_b, i_c, i_d, i_e, i_f; //Naming integer variables with i_ prefix to lable them as integers
//variables for for() loops


srand((unsigned)time(NULL)); //Generate seed from clock



do
{
for( i_f = 0; i_f < 5; i_f ++ )
{
i_yahtzee[ i_f ] = 0; //Initialize i_yahtzee array to all zeros so loop doesn't terminate prematurely
}

//Generate dice rolls through throw1() function
for( i_c = 0; i_c < 5; i_c ++ )
{
i_roll[ i_c ] = throw1(); //Call throw1() function and store result in i_roll variable
printf("%d", i_roll[ i_c ]); //TROUBLEHSOOT / Display roll results
}
////////////


putchar('\n');

i_total_rolls ++; //Tally number of attempts

//Check to see if all dice are equal
i_a = 0; //Start comparison at element 0 and compare to all other elements
for( i_b = 1; i_b < 5; i_b ++ ) //compare first die to four subsequent dice
{


if( i_roll[ i_a ] == i_roll[ i_b ] )
{
i_yahtzee[ i_b ] = 1;  //If all dice are equal
}
else
{
break; //If dice are not equal, exit comparison loop
}
} //End for() loop
///////////


//TROUBLESHOOT YAHTZEE CHECK RESULTS
for( i_e = 1; i_e < 5; i_e ++ )
{
printf("i_yahtzee[%d] = %d\n", i_e, i_yahtzee[i_e] );
}
//////////////////////



}while( i_yahtzee[4]  != 1 ); //Repeat loop until a yahtzee is rolled, indicated by the fifth element of "yahtzee" array being a '1'



printf("total rolls until YAHTZEE: %d\n", i_total_rolls);


//Create border for dice roll display
for( i_d = 0; i_d < 5; i_d ++ )
printf("+---"); //Create a border for results. It is assembled piecewise, according to number of dice rolled
printf("+\n"); //finish border with '+'

//display dice rolls within border
for( i_d = 0; i_d < 5; i_d ++ )
printf("| %d ",i_roll[i_d]); //Display result
printf("|\n");
for( i_d = 0; i_d < 5; i_d ++ )
printf("+---"); //Bottom border created piecewise
printf("+\n");
////////////////////////////


return(0);
}
« Last Edit: June 21, 2013, 01:49:02 AM by Bitbeisser »

Offline TimoVJL

  • Global Moderator
  • Member
  • *****
  • Posts: 2115
Re: YAHTZEE problem
« Reply #11 on: June 21, 2013, 02:14:10 PM »
Code: [Select]
#include<stdio.h>
#include<stdlib.h>
#include<time.h>

int main(void)
{
int i_total_rolls = 0;
int i_roll[5];

srand((unsigned)time(NULL));
printf("  1   2   3   4   5\n-----------------\n");
int itest = 0;
do
{
i_total_rolls = 0;
do
{
for (int i = 0; i < 5; i++)
i_roll[i] = rand() % 6 + 1;
i_total_rolls++;
printf("\r| %d | %d | %d | %d | %d |", i_roll[0], i_roll[1], i_roll[2], i_roll[3], i_roll[4]);
if ((i_total_rolls && i_total_rolls % 10000) == 0)
srand((unsigned)time(NULL)); // new seed
} while (i_roll[0] != i_roll[1] || i_roll[0] != i_roll[2] || i_roll[0] != i_roll[3] || i_roll[0] != i_roll[4]);
printf("\ntotal rolls until YAHTZEE: %d\n", i_total_rolls);
} while (itest++ < 20);
return (0);
}
May the source be with you

jin_yeugh

  • Guest
Re: YAHTZEE problem
« Reply #12 on: June 21, 2013, 05:33:41 PM »
Thank you Timovjl!  That's such an improvement on the efficiency of my program. I really like the way you have twenty iterations, giving a large sample size so you can easily average out how many rolls it took.  I'm going to edit my code to emulate yours, making some similar strip-down changes. I can see where some weight can be shed now.