954,505 Members — Technology Publication meets Social Media
Username:
Password:
Lost login information?
Have something to say? Contribute New Article Reply to this Article

Convert to Absolute Values

I have this program to write thats a guessing game. the user specifies the amount of rounds and only 5 attempts per round is allowed a round is over when the user guesses correctly or the number of attempts are up. A Message is displayed to inform the user whether he/she is cold, hot or warm based on a certain criteria:

#include <stdio.h> 
#include <stdlib.h>

/*Funtion Prototypes*/

int genRandom(void);


int main(void)

{
/*Declare variables*/

int rounds;
int ranNum;
int guess;
int attempts=5;
int score;


printf("\nEnter the desired number of rounds\n");
scanf("%d",&rounds);

  
do{ 
  ranNum=genRandom();/*Call random function*/

  printf("Your rannum is %d\n", ranNum);

  do{
  printf("Guess the value of the random number\n");
  scanf("%d",&guess);

 if(guess>100)
  {
   printf("Invalid!!!Your source base must be less than 100\n\n");

  }
   
  attempts=attempts-1;


 if (ranNum==guess)
{
   printf("Congratulations,You are correct!\n"); 

}


if ((ranNum-guess) >40)
{
   printf("You are Cold\a\n");
}
else if (10<=(ranNum-guess)<=40)
{	
   printf("You are Warm\a\n"); 

}
else if ((ranNum-guess) < 10)
{
   printf("You are Hot!\a\n");

}
  }while(attempts!=0);

}while(rounds!=0);


score=5*(5-attempts);

printf("Your score is %d\n", score);

}/* end of main*/

int genRandom(void)
{
  return rand()%100;
}

1. How do I work with only absolute or positive values for my criteria (say number is less than guess)
2. I want to break out of the loop when the guess is correct or when the attempts are up.

boujibabe
Junior Poster
123 posts since Nov 2004
Reputation Points: 10
Solved Threads: 0
 

Some points:To guarantee that a particular integer will always be postive (absolute), declare it as an unsigned int .
You check to see if the value the user entered was larger than 100, but you never checked if it was smaller than 0.
You can use break to jump out of a loop if you need to, although a better way would be simply to keep checking the value of a boolean variable which represents if it's time to exit the loop.
This statement makes no sense:

if (10<=(ranNum-guess)<=40)


Since you already checked that the difference is smaller than 40, just check that the difference isn't smaller than 10.
Proper code indentation is a code habit to practice. Many editors have a built-in feature, so you don't even have to think about it. And it makes code much easier to read and understand.

John A
Vampirical Lurker
Team Colleague
7,630 posts since Apr 2006
Reputation Points: 2,240
Solved Threads: 339
 
Some points:
  • To guarantee that a particular integer will always be postive (absolute), declare it as an unsigned int .

[LIST]

what if I typecast it

((unsigned int)(ranNum-guess) >40)
  • You can use break to jump out of a loop if you need to, although a better way would be simply to keep checking the value of a boolean variable which represents if it's time to exit the loop.
  • Do you mean like if (attempts>0=1&&rounds>0=1) ?
  • Proper code indentation is a code habit to practice. Many editors have a built-in feature, so you don't even have to think about it. And it makes code much easier to read and understand.

I been trying to work on my indentation and I thought I was getting better can you suggest a good code editor that would help?

Thanks.

boujibabe
Junior Poster
123 posts since Nov 2004
Reputation Points: 10
Solved Threads: 0
 

here is the revised code

#include <stdio.h> 
#include <stdlib.h>

/*Funtion Prototypes*/
int genRandom(void);

int main(void)

{
/*Declare variables*/

int rounds;
int ranNum;
int guess;
int attempts=5;
int score;


printf("\nEnter the desired number of rounds\n");
scanf("%d",&rounds);
do{
ranNum=genRandom();/*Call random function*/
--rounds;
  do{
printf("Guess the value of the random number\n");
scanf("%d",&guess);
--attempts;

		if((guess>100)||(guess<0))
		{
		  printf("Invalid!!!your number must less than 100 or more than 0\n\n");
		continue;
		}
   
		if (ranNum==guess)
		{
	      printf("Congratulations,You are correct!\n"); 
		break;
		}
		
		if ((unsigned int)(ranNum-guess) >40)
		{
	      printf("You are Cold\n");
		}
		else if (10<=(unsigned int)(ranNum-guess))
		{	
	      printf("You are Warm\n"); 
		}
		else if ((unsigned int)(ranNum-guess) < 10)
		{
		  printf("You are Hot!\n");
		}
	}while(attempts!=0);
 }while(rounds!=0);

score=5*(5-attempts);

printf("Your score is %d\n", score);

}/* end of main*/

int genRandom(void)
{
  return rand()%100;
}


The score is noncumulative and is suppsed to show at the end of each round

boujibabe
Junior Poster
123 posts since Nov 2004
Reputation Points: 10
Solved Threads: 0
 

You are getting incorrect output since you fail to reset the attempts value to 5 again i.e. at the end of the nested do while loop, set the value of attempts again to 5.

Also it is better to decrement the value of attempts at the end of the second do while loop, only after the successful completion of the loop since you seem to be using continue.

And btw, read this thread for getting a good IDE.

~s.o.s~
Failure as a human
Administrator
11,938 posts since Jun 2006
Reputation Points: 3,281
Solved Threads: 734
 

Thanks a bundle. It works now except when I'm correct I can't break out of the loop and print the score, also It isn't starting another round after the failed attempts.

boujibabe
Junior Poster
123 posts since Nov 2004
Reputation Points: 10
Solved Threads: 0
 
Thanks a bundle. It works now except when I'm correct I can't break out of the loop and print the score, also It isn't starting another round after the failed attempts.


Hmm... the "break" statement works fine for me, except that you aren't calculating the score correctly. You should calculate the score right after the round finishes, and before you reset the attempts.

Like this:

}while(attempts!=0);
        score+=5*(5-attempts);


Notice that I put += instead of just =, since the score is supposed to be accumlative. Which means you're going to have to initalize score at the beginning of your program.

You may want to print a "you failed" message before the round ends so that the user knows that he/she ran out of attempts, and additionally, print out the number of attempts remaining after each guess.

John A
Vampirical Lurker
Team Colleague
7,630 posts since Apr 2006
Reputation Points: 2,240
Solved Threads: 339
 
I been trying to work on my indentation and I thought I was getting better

Here's a tutorial about code formatting. Concentrate on whitespace as well as indentation. A differnt IDE won't do it all for you, and knowing how to format is extremely important.

WaltP
Posting Sage w/ dash of thyme
Moderator
10,506 posts since May 2006
Reputation Points: 3,348
Solved Threads: 944
 
Thanks a bundle. It works now except when I'm correct I can't break out of the loop and print the score, also It isn't starting another round after the failed attempts.

Post the updated code so I can see what you have come up with...

~s.o.s~
Failure as a human
Administrator
11,938 posts since Jun 2006
Reputation Points: 3,281
Solved Threads: 734
 
#include <stdio.h> 
#include <stdlib.h>

/*Funtion Prototypes*/
int genRandom(void);

int main(void)

{
/*Declare variables*/

int rounds;
int ranNum;
int guess;
int attempts=5;
int score;


printf("\nEnter the desired number of rounds\n");
scanf("%d",&rounds);
do{
ranNum=genRandom();/*Call random function*/
--rounds;
  do{
printf("Guess the value of the random number\n");
scanf("%d",&guess);


		if((guess>100)||(guess<0))
		{
		  printf("Invalid!!!your number must less than 100 or more than 0\n\n");
		continue;
		}
   
		if (ranNum==guess)
		{
	      printf("Congratulations,You are correct!\n"); 
		break;
		}
		
		if ((unsigned int)(ranNum-guess) >40)
		{
	      printf("You are Cold\n");
		}
		else if (10<=(unsigned int)(ranNum-guess))
		{	
	      printf("You are Warm\n"); 
		}
		else if ((unsigned int)(ranNum-guess) < 10)
		{
		  printf("You are Hot!\n");
		}
		--attempts;
	}while(attempts!=0);

	score+=5*(5-attempts);
  attempts=5;

 }while(rounds!=0);

printf("Your score is %d\n", score);

}/* end of main*/

int genRandom(void)
{
  return rand()%100;
}


Now I'm going on infinitely instead of breaking after five attempts. A noncumulative score has to be displayed at the end of each round but once the rounds are up a cumulative score is then displayed.

boujibabe
Junior Poster
123 posts since Nov 2004
Reputation Points: 10
Solved Threads: 0
 

You need to initialize the score variable to zero. If you want to print out the score after each round, print the score at the end of the inner while loop.

I don't see as such something wrong with your code other that those mentioned by me...

~s.o.s~
Failure as a human
Administrator
11,938 posts since Jun 2006
Reputation Points: 3,281
Solved Threads: 734
 

I decided to be a beta tester of you code :)

This is the output of the test.

Enter the desired number of rounds 3 The random number is 41 Guess the value of the random number 2 You are Warm Guess the value of the random number 3 You are Warm Guess the value of the random number 4 You are Warm Guess the value of the random number 5 You are Warm Guess the value of the random number 6 You are Warm The random number is 67 Guess the value of the random number 7 You are Cold Guess the value of the random number 8 You are Cold Guess the value of the random number 9 You are Cold Guess the value of the random number 10 You are Cold Guess the value of the random number

Right after the generation of the random number in the first do{}while loop I included a printf for debugging to see what the number generated was. That's the 41 you see. And look at the warn/ cold algorithm. It doesn't make sense.
Most like you would have to double check the logic behind it, again.

Also, you don't need to add (unsigned int) to every statement after the if,
you could just added to the function like this:

int genRandom(void)
{
  return (unsigned) rand()%100;
}



By the way, I think your code is a perfect candidate for aswitch instead of
all those if and if else.

Aia
Nearly a Posting Maven
2,392 posts since Dec 2006
Reputation Points: 2,224
Solved Threads: 218
 
if ((unsigned int)(ranNum-guess) > 40)

The unsigned int is necessary. Let me show you an example. Let's say that the random number was 50, and the guess was 100.
ranNum-guess would then equal -50, which is NOT what we want. We want how far away the guess is from the random number, not the exact difference (plus or minus).

John A
Vampirical Lurker
Team Colleague
7,630 posts since Apr 2006
Reputation Points: 2,240
Solved Threads: 339
 
By the way, I think your code is a perfect candidate for a switch instead of all those if and if else.

I want to correct myself. A switch would not work here since the evaluation in a switch has to be iquals to a integer expression and not conditional.

However I want to point some things in your code. I commented.

#include <stdio.h> 
#include <stdlib.h>

/*Funtion Prototypes*/
int genRandom(void);

int main(void)
{
/*Declare variables*/

    int rounds;
    int ranNum;
    int guess;
    int attempts=5;
    int score;


    printf("\nEnter the desired number of rounds\n");
    scanf("%d",&rounds);
    do{
        ranNum=genRandom();/*Call random function*/
        --rounds;
          do{
            printf("Guess the value of the random number\n");
            scanf("%d",&guess);


            if((guess>100)||(guess<0))
            {
                printf("Invalid!!!your number must less than 100 or more than 0\n\n"); /* zero is not excluded, zero is a posibility */
                  continue;
            }
   
            if (ranNum==guess)
            {
                printf("Congratulations,You are correct!\n"); 
                  break;
            }
        
            if ((unsigned int)(ranNum-guess) >40) /* lest's say ranNum-guess is 45. 45 is greater than 40. This statement applys */
            {
                  printf("You are Cold\n");
            }
            else if (10<=(unsigned int)(ranNum-guess)) /* if ranNum-guess is 45, 10 is less or iquals to 45. This statement applays too */
            {    
                  printf("You are Warm\n"); 
            }
            else if ((unsigned int)(ranNum-guess) < 10) /* ranNum-guess is 45, 45 is less than 10?. No. */
            {
                printf("You are Hot!\n");
            }
            --attempts;
        }while(attempts!=0);

        score+=5*(5-attempts);
          attempts=5;

    }while(rounds!=0);

    printf("Your score is %d\n", score);

}/* end of main*/

int genRandom(void)
{
  return rand()%100;
}

I don't know if you have noticed but every time you execute this
code the same random numbers ocurre. This happens because there
is nothing random for a computer. To work around this problem you could generate a seudo-random number using the time in your computer as a seed.

here's my take of your genRandom function:

int genRand()
{
     int number;
     
     srand ((unsigned) time(NULL)); /* seed using computer time */
     number = (rand() % 100) + 1; /* this will create a number from 1 to 100, and not from 0 to 99 like before */
     return number;
}
Aia
Nearly a Posting Maven
2,392 posts since Dec 2006
Reputation Points: 2,224
Solved Threads: 218
 
if ((unsigned int)(ranNum-guess) >40) /* lest's say ranNum-guess is 45. 45 is greater than 40. This statement applys */


Why is that incorrect? If the guess was 45 off the random number, of course it should print cold! If the difference isless than 40 the statement is not printed, which is correct.

else if (10<=(unsigned int)(ranNum-guess)) /* if ranNum-guess is 45, 10 is less or iquals to 45. This statement applays too */

True, but you forgot that this is an else if() statement. If the difference was larger than 40, it would have been caught in the first expression. Since we know that the difference is less than 40, we don't have to test for it multiple times.
else if ((unsigned int)(ranNum-guess) < 10) /* ranNum-guess is 45, 45 is less than 10?. No. */ No, but that is also correct. A difference of less than 10 would mean that the user is very close. It's appropriate to print out such a statement.I don't know if you have noticed but every time you execute this
code the same random numbers ocurre. This happens because there
is nothing random for a computer. To work around this problem you could generate a seudo-random number using the time in your computer as a seed.

here's my take of your genRandom function:

int genRand()
{
     int number;
     
     srand ((unsigned) time(NULL)); /* seed using computer time */
     number = (rand() % 100) + 1; /* this will create a number from 1 to 100, and not from 0 to 99 like before */
     return number;
}

Don't do it like that. You only need to seed the random number generator at the top of the program, seeding it multiple times is unnecessary and usually leads to nonrandom numbers.

John A
Vampirical Lurker
Team Colleague
7,630 posts since Apr 2006
Reputation Points: 2,240
Solved Threads: 339
 

Why is that incorrect? If the guess was 45 off the random number, of course it should print cold! If the difference is less than 40 the statement is not printed, which is correct.

True, but you forgot that this is an else if() statement. If the difference was larger than 40, it would have been caught in the first expression. Since we know that the difference is less than 40, we don't have to test for it multiple times.

No, but that is also correct. A difference of less than 10 would mean that the user is very close. It's appropriate to print out such a statement.

I was not say it was wrong. I was pointing out the logic and perhaps the fact that the first two over-lapped.

However I think I would do it like:

if ((ranNum-guess) >= 40)
           {
               printf("You are Cold\n");
           }
           else if ((ranNum-guess) > 10 && (ranNum-guess) < 40)
           {    
               printf("You are Warm\n"); 
           }
           else if ((ranNum-guess) <= 10)
           {
               printf("You are Hot!\n");
           }
Don't do it like that. You only need to seed the random number generator at the top of the program, seeding it multiple times is unnecessary and usually leads to nonrandom numbers


Good to know about that little quirck ;)

Aia
Nearly a Posting Maven
2,392 posts since Dec 2006
Reputation Points: 2,224
Solved Threads: 218
 

> However I think I would do it like:

That's redundant. It won't affect performance in a little program like this, but there are certain assumptions you should get into the habit of making, and this is one of them. The only way the else if() statement executes is if the if() statement evaluated as false.

Also, you forgot to use (unsigned int) casts in your expressions, so it would evaluate incorrectly.

John A
Vampirical Lurker
Team Colleague
7,630 posts since Apr 2006
Reputation Points: 2,240
Solved Threads: 339
 
Also, you forgot to use (unsigned int) casts in your expressions, so it would evaluate incorrectly.

I don't need (unsigned int) if I'm using it at the function level. Don't I?

srand ((unsigned) time(NULL));

Aia
Nearly a Posting Maven
2,392 posts since Dec 2006
Reputation Points: 2,224
Solved Threads: 218
 
I don't need (unsigned int) if I'm using it at the function level. Don't I?


Did you read my previous post?

The issue here is not that the generated number is positive (although it should be positive), the thing is that thedifference between the random number and the guess has to be positive in order for the expressions to work properly.

The OP realized this, and that is why this thread was created.

John A
Vampirical Lurker
Team Colleague
7,630 posts since Apr 2006
Reputation Points: 2,240
Solved Threads: 339
 
The issue here is not that the generated number is positive (although it should be positive), the thing is that the difference between the random number and the guess has to be positive in order for the expressions to work properly.

I stand corrected. Thank you. :cheesy:

Aia
Nearly a Posting Maven
2,392 posts since Dec 2006
Reputation Points: 2,224
Solved Threads: 218
 

This article has been dead for over three months

Post: Markdown Syntax: Formatting Help
You