5
\$\begingroup\$

I am trying to relearn the C language and thought making small projects would be a good way to do it. The code I wrote works perfectly as intended.

I am just here to see if there are any better practices to be implemented or any code optimization tips would be highly appreciated.

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int random(int N){
 srand(time(NULL));
 int value = rand() % N;
 return value;
}
int play(int turns, int range){
 int num = random(range);
 while (turns > 0){
 printf("You have %d turns left\n", turns);
 printf("Guess the number (0-%d): ", range);
 int guess;
 scanf("%d", &guess);
 if (guess == num){
 printf("Congratulations! You guessed the correct number!\n");
 return 1;
 }
 else if (guess < num){
 printf("Too low. Try again.\n");
 turns--;
 }
 else {
 printf("Too high. Try again.\n");
 turns--;
 }
 }
 return 0;
}
int main(int argc, char const *argv[])
{
 printf("Welcome to the Guessing Game\n");
 while (1){
 printf("Choose your difficulty:\n For easy enter (1)\n For medium enter (2)\n For difficult enter (3)\n");
 int diff;
 scanf("%d", &diff);
 switch (diff) {
 case 1: 
 if (play(5, 30) != 1) {
 printf("Sorry you ran out of Turns\n");
 }
 break;
 case 2: 
 if (play(3, 50) != 1) {
 printf("Sorry you ran out of Turns\n");
 }
 break;
 case 3: 
 if (play(1, 100) != 1) {
 printf("Sorry you ran out of Turns\n");
 }
 break;
 default:
 printf("INVALID Difficulty Please try again!\n");
 break;
 }
 printf("Do you want to play again? (y/n): ");
 char choice;
 scanf(" %c", &choice);
 if (choice != 'y'){
 printf("Thanks for playing!\n");
 break;
 }
 }
 return 0;
}
Toby Speight
87.5k14 gold badges104 silver badges322 bronze badges
asked Aug 19, 2024 at 6:22
\$\endgroup\$
0

3 Answers 3

4
\$\begingroup\$

Good re-learning effort.


Bug (kinda)

printf("Guess the number (0-%d): ", range); implies that 0 to range is a possible correct answer (or 1 to range - 1 if one views (...) as not including the endpoints.), yet rand() % range only makes for that values 0 to range - 1.

// Suggest
printf("Guess the number [0-%d]: ", range-1);
// or
// int value = rand() % N;
int value = rand() % (N + 1);

Test success of input functions

scanf("%d", &guess); returns 1 if a number was entered. But what if a non-number was entered? It returns zero. EOF is also possible.

Check the return value. Does it differ from expectations?

if (scanf("%d", &guess) != 1) {
 printf("Input is not numeric. Quitting.\n");
 return EXIT_FAILUE;
}

Formatting

Format is OK, yet looks like it was manually done. Use an auto-formatter for efficiency and consistency.

Simplify

else if (guess < num){ is replaceable with if (guess < num){ as the previous if() block did a return.

srand() call only needed once

srand() is only needed to call once in the life of the program. Commonly this is done early via main().

Avoid naked magic numbers

// if (play(1, 100) != 1) {
#define TURNS_DIFFICULT 1
#define RANGE_DIFFICULT 100
...
if (play(TURNS_DIFFICULT, RANGE_DIFFICULT) != 1) {

Avoid very long lines

Use string literal concatenation.

// printf("Choose your difficulty:\n For easy enter (1)\n For medium enter (2)\n For difficult enter (3)\n");
printf("Choose your difficulty:\n"
 " For easy enter (1)\n"
 " For medium enter (2)\n"
 " For difficult enter (3)\n");

Avoid repeated code

Instead of if (play(x, x) != 1) { printf("Sorry you ran out of Turns\n"); 3 times, maybe something like

 switch (diff) {
 case 1: play(5, 30);
 break;
 case 2: play(3, 50);
 break;
 case 3: play(1, 100);
 break;
 default:
 printf("INVALID Difficulty Please try again!\n");
 break;
 }

.. and put the printf("Sorry you ran out of Turns\n"); in play()?


Minor: punctuation

// printf("INVALID Difficulty Please try again!\n");
printf("INVALID difficulty. Please try again!\n");

Minor: Tolerate either case

// if (choice != 'y'){
if (choice != 'y' && choice != 'Y'){

Also research tolower().

answered Aug 19, 2024 at 18:06
\$\endgroup\$
1
  • \$\begingroup\$ Those are some really great suggestions. Thanks for your advice!! \$\endgroup\$ Commented Aug 20, 2024 at 13:24
2
\$\begingroup\$

In addition to the good points in the other answer, here are some other things to consider.

Displayed messages

The messages you display to the user make it clear how to play the game and make it easy to follow the progress. The following are some minor improvements.

You should show the correct number (num) when the user runs out of turns.

You should not display Try again. when the user runs out of turns.

This message is grammatically incorrect:

You have 1 turns left

You should display turn:

You have 1 turn left

Portability

There are 101 ways to compile C code. When I use gcc in my Linux operating system, I get an error message like the following:

error: conflicting types for 'random'
 int random(int N){
 ^~~~~~
In file included from ,,,
/usr/include/stdlib.h:321:17: note: previous declaration of 'random' was here
 extern long int random (void) __THROW;
 ^~~~~~

The code compiled and ran without errors when I changed the name of the function from random to random_int.

answered Aug 20, 2024 at 0:25
\$\endgroup\$
1
  • 2
    \$\begingroup\$ random() does not collide with the standard C library. It is colliding with (common) extensions employed by gcc. If OP compiled without these extensions, no conflict. Still a user random() is asking for trouble. \$\endgroup\$ Commented Aug 20, 2024 at 2:31
2
\$\begingroup\$

Do not use scanf() for user input:

Checking the return value alone does not suffice. If the converted input is larger than the maximum value of an int, the behavior would be undefined.

I would suggest reading the input as a string and then converting it with sscanf()/strtol() et cetera.

answered Aug 22, 2024 at 10:44
\$\endgroup\$

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.