Thread: I'm so close to finishing this...please help with logic error

  1. #1
    Registered User
    Join Date
    Sep 2008
    Posts
    43

    I'm so close to finishing this...please help with logic error

    Here is my latest code:

    Code:
    #include <stdio.h>   // for interactive input and output
    #include <stdlib.h>  // for the rand() function
    #include <ctype.h>   // for tolower() macro
    #define SIDES 6
    
    typedef enum {doublesPoints, onesPoints, noPoints, singlesPoints} status;
    
    void prnRules(void)
    // function: prnRules
    // pre: none
    // post: prints the rules
    {
    	printf("%s\n",
    			 "The goal is to be the first player to reach 100 points.\n\n"
    			 "On a turn, a player rolls the two dice repeatedly until either a 1 is rolled \n"
    			 "or the player chooses to hold and stop rolling.\n\n"
    			 "If a 1 is rolled, that player's turn ends and no points are earned for the round.\n"
    			 "If the player chooses to hold, all of the points rolled during that round are added to their score.\n\n"
    			 "If a player rolls double 1s, that counts as 25 points.\n"
    			 "Other doubles are worth 2x double points, so that a 2-2 is worth 8 points; 3-3 is worth 12; \n"
    			 "4-4 is worth 16; 5-5 is worth 20; and 6-6 is worth 24.\n\n"
    			 "When a player reaches a total of 100 or more points, the game ends and that player is the winner.\n");
    }		
    
    int rollDie ()
    // function: rollDie
    // pre: none
    // post: generates a random number for the die 
    {
       int d;
    
       d = rand() % SIDES + 1;
       return d;
    }
    
    
    status turnPoints(int die1, int die2)
    // function: turnStatus
    // pre: dice have been rolled
    // post: returns the status of the roll (doublesPoints, onesPoints, no Points, singlesPoints)
    {
       if (die1 == die2 && !(die1 == 1 && die2 == 1))
    		return doublesPoints;
       
    	else if (die1 == 1 && die2 == 1)
    		return onesPoints;
    		
    	else if ((die1 == 1 || die2 == 1) && !(die1 == 1 && die2 == 1))
    		return noPoints;
    	
    	else
    		return singlesPoints;
    }
    
    int turnAgain(int status)
    // function: turnAgain
    // pre: Player must have rolled a non disqualifying point combination 
    // post: returns a valid (y or n) answer
    {
    	char ans;
    	
    	if (status == 1)
    	{
    		printf("TURNAGAIN Would you like to risk the points for this round and continue? (y or n)? ");
    		ans = getchar();
    		getchar();
    	} 
    	
    	if (status == 0)
    	{
    		ans = 'n';
    	} 
    	return tolower(ans);
    }
    
    //to switch the current player when the turn is over
    int switchPlayer(int currentPlayer)
    {
    	if (currentPlayer == 1)
    		return 2;
    	else
    		return 1;
    }
    
    
    char gameAgain(int choice)
    // function: gameAgain
    // pre: none
    // post: returns a valid (y or n) answer
    {
    	char ans;
    
    	//do
    	{
    		if (choice == 1)
    		   printf("Play another game (y or n)? ");
    		ans = getchar();
    		getchar();
    	} //while (tolower(ans) != 'y' && tolower(ans) != 'n');
    	return tolower(ans);
    }
    
    int gameOver (int p1Total, int p2Total)
    // function: gameOver
    // pre:  none
    // post: returns a '1' if either total exceeds 100
    {
    	if (p1Total || p2Total >= 100)
    	{
    		return 1;
    	}
    	else
    	{
    		return 0;
    	}
    }
    
    //The final print statement with all the totals
    void finalOutput(int p1Total, int p2Total)
    // function: finalOutput
    // pre: gameOver returns a '1'
    // post: returns the final scores of the game
    {
    	printf("\n");
    	printf("WE HAVE A WINNER!!!\n");
    	printf("Player 1 your final score was %d\n", p1Total);
    	printf("Player 2 your final score was %d\n", p2Total);
    }
    
    int updatePlayerTotal(int currentPlayer, int turnTotal, int playerTotal)
    // function: pudatePlayerTotal
    // pre: none
    // post: returns the player total
    {
       printf("Player %d, your total at the start of this turn was %d .\n",
       currentPlayer, playerTotal);
       playerTotal = playerTotal + turnTotal;
       printf("Your total at the end of this turn is %d.\n\n", playerTotal);
       return playerTotal;
    }
    
    int main (void)
    {//begin main
    	// variable declarations
       int sum;                  // for sum of two dice
       char answer;              // for yes/no questions
       int tempTotal = 0;        // temporary player total for the round
       int p1Total = 0;          // running total for player 1
       int p2Total = 0;          // running total for player 2
       int total = 0;		        // player total after each round
       int die1 = 0;             // the roll value of die1
       int die2 = 0;             // the roll value of die2
       int currentPlayer = 1;	  // start with Player 1
    	int status = 0;           // ability to choose to continue
    	
    	
    	srand(time(NULL));        // seed random # generator
    	
    	
    	do // play at least one game
    	{//Begin game loop
    	 //give option to view the rules
    		printf("Welcome to the game of Pig. Would you like to view the rules? (y or n)?\n");
    		answer = getchar();
    		getchar();
    		if (answer == 'y')
    			prnRules();
    		
    		do // until game is won
    		{//Begin roll loop1
    			
    			{   //Begin roll loop2
    				 die1 = rollDie();
    				 die2 = rollDie();
    				 sum  = (die1 + die2);
    				 printf("Player %d:\n", currentPlayer);
    				 printf("Die 1 is a %d.\n", die1);
    				 printf("Die 2 is a %d.\n", die2);
    				
    				 //award points (rolled a double but not double 1's)
    				 if (turnPoints(die1, die2) == doublesPoints)
    				 {
    					 printf(" Player %d, you rolled a double %d!\n ", currentPlayer, die1);
    					 printf(" That's worth %d points.\n", (sum * 2));
    					 tempTotal = (tempTotal + total + (sum * 2));
    					 status = 1;
    				 }
    				
    				 //award points (rolled double 1's)
    				 else if (turnPoints(die1, die2)  == onesPoints)
    				 {
    					 printf(" Player %d, You rolled a double 1!\n ", currentPlayer);
    					 printf(" That's worth 25 points.\n");
    					 tempTotal = (tempTotal + total + 25);
    					 status = 1;
    				 }
    				
    				 //award  no points (one of the two dice = 1)
    				 else if (turnPoints(die1, die2) == noPoints)
    				 {
    					 printf("Sorry Player %d, you rolled a single 1. You do not earn any points this round\n", currentPlayer);
    					 printf("Your current total is %d\n", total);
    					 tempTotal = 0;
    					 total = total + tempTotal;
    					 status = 0;
    				 }
    				
    				 //award points (rolled singles)
    				 else if (turnPoints(die1, die2) == singlesPoints)
    				 {
    					 printf("Player %d, your roll totals %d points.\n", currentPlayer, sum);
    					 tempTotal = tempTotal + (total + sum);
    					 status = 1;
    				 }
    				
    				 
    			}while (status == 1 && (turnAgain(status) == 'y'));//end roll loop2 - while player continues roll
    			
    		   if (turnAgain(status) == 'n')//(answer == 'n')
    			{
    				total = (tempTotal + total);
    				if (currentPlayer == 1)
    				{
    					p1Total = updatePlayerTotal(currentPlayer, tempTotal, p1Total);
    				}
    				else
    				{
    					p2Total = updatePlayerTotal(currentPlayer, tempTotal, p2Total);
    				}
    			   //switch players
    			   currentPlayer = switchPlayer(currentPlayer); 
    			}
    
    		  
    		}while (gameOver (p1Total, p2Total) != 1); //end loop1 - continue while game is not over
    		
    		gameAgain(1);
    		
    	}while (answer != 'n'); //end game loop - loop while wanting to play again
    	return 0;
    }//end main
    Here is the output based on how I responded to the questions:

    Code:
    Welcome to the game of Pig. Would you like to view the rules? (y or n)?
    n
    Player 1:
    Die 1 is a 6.
    Die 2 is a 2.
    Player 1, your roll totals 8 points.
    TURNAGAIN Would you like to risk the points for this round and continue? (y or n)? n
    TURNAGAIN Would you like to risk the points for this round and continue? (y or n)? 
    n
    Player 1:
    Die 1 is a 6.
    Die 2 is a 3.
    Player 1, your roll totals 9 points.
    TURNAGAIN Would you like to risk the points for this round and continue? (y or n)? y
    TURNAGAIN Would you like to risk the points for this round and continue? (y or n)? y
    Player 1:
    Die 1 is a 1.
    Die 2 is a 2.
    Sorry Player 1, you rolled a single 1. You do not earn any points this round
    Your current total is 0
    Player 1, your total at the start of this turn was 0 .
    Your total at the end of this turn is 0.
    
    Player 2:
    Die 1 is a 1.
    Die 2 is a 5.
    Sorry Player 2, you rolled a single 1. You do not earn any points this round
    Your current total is 0
    Player 2, your total at the start of this turn was 0 .
    Your total at the end of this turn is 0.
    
    Player 1:
    Die 1 is a 3.
    Die 2 is a 4.
    Player 1, your roll totals 7 points.
    TURNAGAIN Would you like to risk the points for this round and continue? (y or n)? n
    TURNAGAIN Would you like to risk the points for this round and continue? (y or n)? n
    Player 1:
    Die 1 is a 3.
    Die 2 is a 2.
    Player 1, your roll totals 5 points.
    TURNAGAIN Would you like to risk the points for this round and continue? (y or n)? n
    TURNAGAIN Would you like to risk the points for this round and continue? (y or n)? n
    Player 1:
    Die 1 is a 1.
    Die 2 is a 3.
    Sorry Player 1, you rolled a single 1. You do not earn any points this round
    Your current total is 0
    Player 1, your total at the start of this turn was 0 .
    Your total at the end of this turn is 0.
    Thats only part of the output, but the patterns continue the same way. There are several issues here but :
    1). I shouldnt have to answer y (or n) twice to make it continue (or not continue).
    2). When I tell it to continue it should continue with the same player
    3). When I answer no to continue it should switch to the other player.
    4). Whenever the player switches it should give a cumulative total for the rounds played.

    For now I just want to figure out how to answer the question once and make it switch players.
    This may be a potential problem line of code:
    Code:
    }while (status == 1 && (turnAgain(status) == 'y'));//end roll loop2 - while player continues roll
    I just added the "status ==1 &&" to it. before I added that to it I could answer yes to the continue question all day and it would just keep asking it over. If I answered no, it would end the game after asking it a second time.

    Can anyone give me any hints as to how I should fix this?

    Thanks a bunch
    crazychile

  2. #2
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    [quote]
    Code:
    			 
    			}while (status == 1 && (turnAgain(status) == 'y'));//end roll loop2 - while player continues roll  asks player
    			
    		   if (turnAgain(status) == 'n')//(answer == 'n')  asks player yet again
    //quote]

  3. #3
    Registered User
    Join Date
    Sep 2008
    Posts
    43
    ok thats a good hint tabstop. I hadn't thought of that. I can see why it would do that if you answered n/n but why does it do that for y/y? Can you give me any hints how to fix this to make it do the roll loop again/or for next player?

    Thank you so much,
    crazychile

  4. #4
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    You'd have to post the actual code you're using to get better answers. For one, you're missing <time.h>. For two, if you actually run it, this is what happens:
    Code:
    Welcome to the game of Pig. Would you like to view the rules? (y or n)?
    n
    Player 1:
    Die 1 is a 4.
    Die 2 is a 2.
    Player 1, your roll totals 6 points.
    TURNAGAIN Would you like to risk the points for this round and continue? (y or n)? n
    TURNAGAIN Would you like to risk the points for this round and continue? (y or n)? n
    Player 1, your total at the start of this turn was 0 .
    Your total at the end of this turn is 6.
    
    Play another game (y or n)? n

  5. #5
    Registered User
    Join Date
    Sep 2008
    Posts
    43
    I'm not sure I understand. All of the code was included with the post.

    Why do I need time.h? Is that for the randomness of the dice?

    Thank you,
    crazychile

  6. #6
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    You can't do time(NULL) without time.h.

    And the code you posted does not display the behavior you claim it does. Two n's immediately end the game, and y's do nothing but ask again. Edit: Oh, and any positive score for player 1 ends the game. And I bet your inner do-while loop doesn't end where you think it does, either.
    Last edited by tabstop; 11-03-2008 at 09:24 PM.

  7. #7
    Registered User
    Join Date
    Sep 2008
    Posts
    43
    Ok this is weird...youre right. I get the following output:

    Code:
    Welcome to the game of Pig. Would you like to view the rules? (y or n)?
    n
    Player 1:
    Die 1 is a 5.
    Die 2 is a 5.
     Player 1, you rolled a double 5!
      That's worth 20 points.
    TURNAGAIN Would you like to risk the points for this round and continue? (y or n)? y
    TURNAGAIN Would you like to risk the points for this round and continue? (y or n)? y
    TURNAGAIN Would you like to risk the points for this round and continue? (y or n)? y
    TURNAGAIN Would you like to risk the points for this round and continue? (y or n)? y
    TURNAGAIN Would you like to risk the points for this round and continue? (y or n)? n
    TURNAGAIN Would you like to risk the points for this round and continue? (y or n)? n
    Player 1, your total at the start of this turn was 0 .
    Your total at the end of this turn is 20.
    
    Play another game (y or n)? n
    home-computers-computer:~/Desktop homecomputer$
    I didn't think I had changed the code since the original post. I have also noticed that sometimes when I tell it I dont want to play again, it does anyway. Is it possible that the status that triggers the while is alternating based on the number of times I answer the question?

    here is the code again:
    Code:
    #include <stdio.h>   // for interactive input and output
    #include <stdlib.h>  // for the rand() function
    #include <ctype.h>   // for tolower() macro
    
    #define SIDES 6
    
    typedef enum {doublesPoints, onesPoints, noPoints, singlesPoints} status;
    
    
    void prnRules(void)
    // function: prnRules
    // pre: none
    // post: prints the rules
    {
    	printf("%s\n",
    			 "The goal is to be the first player to reach 100 points.\n\n"
    			 "On a turn, a player rolls the two dice repeatedly until either a 1 is rolled \n"
    			 "or the player chooses to hold and stop rolling.\n\n"
    			 "If a 1 is rolled, that player's turn ends and no points are earned for the round.\n"
    			 "If the player chooses to hold, all of the points rolled during that round are added to their score.\n\n"
    			 "If a player rolls double 1s, that counts as 25 points.\n"
    			 "Other doubles are worth 2x double points, so that a 2-2 is worth 8 points; 3-3 is worth 12; \n"
    			 "4-4 is worth 16; 5-5 is worth 20; and 6-6 is worth 24.\n\n"
    			 "When a player reaches a total of 100 or more points, the game ends and that player is the winner.\n");
    }		
    
    int rollDie ()
    // function: rollDie
    // pre: none
    // post: generates a random number for the die 
    {
       int d;
    
       d = rand() % SIDES + 1;
       return d;
    }
    
    
    status turnPoints(int die1, int die2)
    // function: turnStatus
    // pre: dice have been rolled
    // post: returns the status of the roll (doublesPoints, onesPoints, no Points, singlesPoints)
    {
       if (die1 == die2 && !(die1 == 1 && die2 == 1))
    		return doublesPoints;
       
    	else if (die1 == 1 && die2 == 1)
    		return onesPoints;
    		
    	else if ((die1 == 1 || die2 == 1) && !(die1 == 1 && die2 == 1))
    		return noPoints;
    	
    	else
    		return singlesPoints;
    }
    
    int turnAgain(int status)
    // function: turnAgain
    // pre: Player must have rolled a non disqualifying point combination 
    // post: returns a valid (y or n) answer
    {
    	char ans;
    	
    	if (status == 1)
    	{
    		printf("TURNAGAIN Would you like to risk the points for this round and continue? (y or n)? ");
    		ans = getchar();
    		getchar();
    	} 
    	
    	if (status == 0)
    	{
    		ans = 'n';
    	} 
    	return tolower(ans);
    }
    
    //to switch the current player when the turn is over
    int switchPlayer(int currentPlayer)
    {
    	if (currentPlayer == 1)
    		return 2;
    	else
    		return 1;
    }
    
    
    char gameAgain(int choice)
    // function: gameAgain
    // pre: none
    // post: returns a valid (y or n) answer
    {
    	char ans;
    
    	//do
    	{
    		if (choice == 1)
    		   printf("Play another game (y or n)? ");
    		ans = getchar();
    		getchar();
    	} //while (tolower(ans) != 'y' && tolower(ans) != 'n');
    	return tolower(ans);
    }
    
    int gameOver (int p1Total, int p2Total)
    // function: gameOver
    // pre:  none
    // post: returns a '1' if either total exceeds 100
    {
    	if (p1Total || p2Total >= 100)
    	{
    		return 1;
    	}
    	else
    	{
    		return 0;
    	}
    }
    
    //The final print statement with all the totals
    void finalOutput(int p1Total, int p2Total)
    // function: finalOutput
    // pre: gameOver returns a '1'
    // post: returns the final scores of the game
    {
    	printf("\n");
    	printf("WE HAVE A WINNER!!!\n");
    	printf("Player 1 your final score was %d\n", p1Total);
    	printf("Player 2 your final score was %d\n", p2Total);
    }
    
    int updatePlayerTotal(int currentPlayer, int turnTotal, int playerTotal)
    // function: pudatePlayerTotal
    // pre: none
    // post: returns the player total
    {
       printf("Player %d, your total at the start of this turn was %d .\n",
       currentPlayer, playerTotal);
       playerTotal = playerTotal + turnTotal;
       printf("Your total at the end of this turn is %d.\n\n", playerTotal);
       return playerTotal;
    }
    
    int main (void)
    {//begin main
    	// variable declarations
       int sum;                  // for sum of two dice
       char answer;              // for yes/no questions
       int tempTotal = 0;        // temporary player total for the round
       int p1Total = 0;          // running total for player 1
       int p2Total = 0;          // running total for player 2
       int total = 0;		        // player total after each round
       int die1 = 0;             // the roll value of die1
       int die2 = 0;             // the roll value of die2
       int currentPlayer = 1;	  // start with Player 1
    	int status = 0;           // status for choice to continue
    	
    	
    	srand(time(NULL));        // seed random # generator
    	
    	
    	do // play at least one game
    	{//Begin game loop
    	 //give option to view the rules
    		printf("Welcome to the game of Pig. Would you like to view the rules? (y or n)?\n");
    		answer = getchar();
    		getchar();
    		if (answer == 'y')
    			prnRules();
    		
    		do // until game is won
    		{//Begin roll loop1
    			
    			{   //Begin roll loop2
    				 die1 = rollDie();
    				 die2 = rollDie();
    				 sum  = (die1 + die2);
    				 printf("Player %d:\n", currentPlayer);
    				 printf("Die 1 is a %d.\n", die1);
    				 printf("Die 2 is a %d.\n", die2);
    				
    				 //award points (rolled a double but not double 1's)
    				 if (turnPoints(die1, die2) == doublesPoints)
    				 {
    					 printf(" Player %d, you rolled a double %d!\n ", currentPlayer, die1);
    					 printf(" That's worth %d points.\n", (sum * 2));
    					 tempTotal = (tempTotal + total + (sum * 2));
    					 status = 1;
    				 }
    				
    				 //award points (rolled double 1's)
    				 else if (turnPoints(die1, die2)  == onesPoints)
    				 {
    					 printf(" Player %d, You rolled a double 1!\n ", currentPlayer);
    					 printf(" That's worth 25 points.\n");
    					 tempTotal = (tempTotal + total + 25);
    					 status = 1;
    				 }
    				
    				 //award  no points (one of the two dice = 1)
    				 else if (turnPoints(die1, die2) == noPoints)
    				 {
    					 printf("Sorry Player %d, you rolled a single 1. You do not earn any points this round\n", currentPlayer);
    					 printf("Your current total is %d\n", total);
    					 tempTotal = 0;
    					 total = total + tempTotal;
    					 status = 0;
    				 }
    				
    				 //award points (rolled singles)
    				 else if (turnPoints(die1, die2) == singlesPoints)
    				 {
    					 printf("Player %d, your roll totals %d points.\n", currentPlayer, sum);
    					 tempTotal = tempTotal + (total + sum);
    					 status = 1;
    				 }
    				
    				 
    			}while (status == 1 && (turnAgain(status) == 'y'));//end roll loop2 - while player continues roll
    			
    		   if (turnAgain(status) == 'n')//(answer == 'n')
    			{
    				total = (tempTotal + total);
    				if (currentPlayer == 1)
    				{
    					p1Total = updatePlayerTotal(currentPlayer, tempTotal, p1Total);
    				}
    				else
    				{
    					p2Total = updatePlayerTotal(currentPlayer, tempTotal, p2Total);
    				}
    			   //switch players
    			   currentPlayer = switchPlayer(currentPlayer); 
    			}
    
    		  
    		}while (gameOver (p1Total, p2Total) != 1); //end loop1 - continue while game is not over
    		
    		gameAgain(1);
    		
    	}while (answer != 'n'); //end game loop - loop while wanting to play again
    	return 0;
    }//end main
    I'll include time.h on it this next time also.

    thanks a bunch
    crazychile

  8. #8
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    gameAgain(1) doesn't change the status of answer, so who knows what that's going to be.
    Code:
    {//Begin roll loop1
    			
    			do {   //Begin roll loop2
    That's missing.
    Your gameOver is still broken.

  9. #9
    Registered User
    Join Date
    Sep 2008
    Posts
    43
    Thank you so much!

    It wont switch players now, but at least I'm getting somewhere. I commented out the gameAgain(1) for now.

    Code:
    Welcome to the game of Pig. Would you like to view the rules? (y or n)?
    n
    Player 1:
    Die 1 is a 4.
    Die 2 is a 5.
    Player 1, your roll totals 9 points.
    TURNAGAIN Would you like to risk the points for this round and continue? (y or n)? y
    Player 1:
    Die 1 is a 5.
    Die 2 is a 3.
    Player 1, your roll totals 8 points.
    TURNAGAIN Would you like to risk the points for this round and continue? (y or n)? n
    TURNAGAIN Would you like to risk the points for this round and continue? (y or n)? n
    Player 1, your total at the start of this turn was 0 .
    Your total at the end of this turn is 17.
    
    home-computers-computer:~/Desktop homecomputer$
    Thanks again for your help
    crazychile

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Compiling sample DarkGDK Program
    By Phyxashun in forum Game Programming
    Replies: 6
    Last Post: 01-27-2009, 03:07 AM
  2. how do you resolve this error?
    By -EquinoX- in forum C Programming
    Replies: 32
    Last Post: 11-05-2008, 04:35 PM
  3. Another syntax error
    By caldeira in forum C Programming
    Replies: 31
    Last Post: 09-05-2008, 01:01 AM
  4. Errors including <windows.h>
    By jw232 in forum Windows Programming
    Replies: 4
    Last Post: 07-29-2008, 01:29 PM
  5. error: template with C linkage
    By michaels-r in forum C++ Programming
    Replies: 3
    Last Post: 05-17-2006, 08:11 AM