Project 2: Number Guessing Game
Project 2: Number Guessing Game¶
Learning Objectives¶
What you will learn through this project:
- Random number generation (rand, srand, time)
- Loops (while, do-while)
- Conditional statement usage
- Game logic implementation
Game Rules¶
1. Computer selects a number between 1-100
2. Player guesses the number
3. "UP!" or "DOWN!" hints provided
4. Repeat until correct answer
5. Display number of attempts
Step 1: Understanding Random Number Generation¶
Core Syntax: rand() and srand()¶
#include <stdio.h>
#include <stdlib.h> // rand, srand
#include <time.h> // time
int main(void) {
// Set seed (call only once)
// time(NULL): use current time (seconds) as seed
srand(time(NULL));
// Generate random number
printf("%d\n", rand()); // Random number between 0 ~ RAND_MAX
// Specify range: 1 ~ 100
int num = rand() % 100 + 1;
printf("Random number between 1~100: %d\n", num);
// Range formula: rand() % (max - min + 1) + min
// Example: 50~100 -> rand() % 51 + 50
return 0;
}
Why Seed Is Needed¶
// Running without srand generates the same sequence of random numbers every time!
// srand(time(NULL)) uses current time as seed -> different random numbers each run
Step 2: Basic Game Implementation¶
// guess_v1.c
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main(void) {
// Initialize random
srand(time(NULL));
// Generate answer between 1~100
int answer = rand() % 100 + 1;
int guess;
int attempts = 0;
printf("=== Number Guessing Game ===\n");
printf("Guess a number between 1 and 100!\n\n");
// Game loop
while (1) {
printf("Guess: ");
scanf("%d", &guess);
attempts++;
if (guess < answer) {
printf("UP! (The number is higher)\n\n");
} else if (guess > answer) {
printf("DOWN! (The number is lower)\n\n");
} else {
printf("\nCorrect!\n");
printf("You got it in %d attempts!\n", attempts);
break;
}
}
return 0;
}
Example Output¶
=== Number Guessing Game ===
Guess a number between 1 and 100!
Guess: 50
UP! (The number is higher)
Guess: 75
DOWN! (The number is lower)
Guess: 62
UP! (The number is higher)
Guess: 68
Correct!
You got it in 4 attempts!
Step 3: Adding Features¶
Additional Features¶
- Attempt limit
- Input validation
- Restart functionality
- Difficulty selection
// guess_v2.c
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
// Function declarations
void print_title(void);
int get_difficulty(void);
int play_game(int max_num, int max_attempts);
void clear_input_buffer(void);
int main(void) {
char play_again;
srand(time(NULL));
print_title();
do {
int difficulty = get_difficulty();
int max_num, max_attempts;
// Difficulty settings
switch (difficulty) {
case 1: // Easy
max_num = 50;
max_attempts = 10;
break;
case 2: // Normal
max_num = 100;
max_attempts = 7;
break;
case 3: // Hard
max_num = 200;
max_attempts = 8;
break;
default:
max_num = 100;
max_attempts = 7;
}
// Run game
int result = play_game(max_num, max_attempts);
if (result) {
printf("\nCongratulations! You win!\n");
} else {
printf("\nToo bad. Try again next time!\n");
}
// Restart confirmation
printf("\nPlay again? (y/n): ");
scanf(" %c", &play_again);
clear_input_buffer();
printf("\n");
} while (play_again == 'y' || play_again == 'Y');
printf("Exiting game. Goodbye!\n");
return 0;
}
void print_title(void) {
printf("\n");
printf("================================\n");
printf(" Number Guessing Game v2 \n");
printf("================================\n");
printf("\n");
}
int get_difficulty(void) {
int choice;
printf("Select difficulty:\n");
printf(" 1. Easy (1~50, 10 chances)\n");
printf(" 2. Normal (1~100, 7 chances)\n");
printf(" 3. Hard (1~200, 8 chances)\n");
printf("\nChoice: ");
scanf("%d", &choice);
clear_input_buffer();
if (choice < 1 || choice > 3) {
printf("Invalid choice. Starting with Normal difficulty.\n");
choice = 2;
}
return choice;
}
int play_game(int max_num, int max_attempts) {
int answer = rand() % max_num + 1;
int guess;
int attempts = 0;
printf("\nGuess a number between 1 and %d!\n", max_num);
printf("Chances: %d\n\n", max_attempts);
while (attempts < max_attempts) {
printf("[%d/%d] Guess: ", attempts + 1, max_attempts);
if (scanf("%d", &guess) != 1) {
printf("Please enter a number.\n\n");
clear_input_buffer();
continue;
}
// Range validation
if (guess < 1 || guess > max_num) {
printf("Please enter a number between 1~%d.\n\n", max_num);
continue;
}
attempts++;
if (guess < answer) {
printf("UP!\n");
// Additional hint
if (answer - guess > max_num / 4) {
printf("(Big difference)\n");
}
printf("\n");
} else if (guess > answer) {
printf("DOWN!\n");
if (guess - answer > max_num / 4) {
printf("(Big difference)\n");
}
printf("\n");
} else {
printf("\nCorrect!\n");
printf("You got it in %d attempts!\n", attempts);
// Calculate score
int score = (max_attempts - attempts + 1) * 100;
printf("Score: %d points\n", score);
return 1; // Win
}
}
printf("\nOut of chances.\n");
printf("The answer was %d.\n", answer);
return 0; // Lose
}
void clear_input_buffer(void) {
int c;
while ((c = getchar()) != '\n' && c != EOF);
}
Step 4: Final Version (Advanced Features)¶
Additional Features¶
- High score saving (within session)
- Statistics display
- Better UI
// guess_game.c (Final)
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <string.h>
// Constant definitions
#define MAX_NAME_LEN 50
// Global variables (game statistics)
typedef struct {
int games_played;
int games_won;
int best_score;
int total_attempts;
char best_player[MAX_NAME_LEN];
} GameStats;
// Function declarations
void print_title(void);
void print_menu(void);
int get_difficulty(int *max_num, int *max_attempts);
int play_game(int max_num, int max_attempts, GameStats *stats);
void show_stats(GameStats *stats);
void clear_input_buffer(void);
int main(void) {
int choice;
GameStats stats = {0, 0, 0, 0, ""};
srand(time(NULL));
while (1) {
print_title();
print_menu();
printf("Choice: ");
if (scanf("%d", &choice) != 1) {
clear_input_buffer();
continue;
}
clear_input_buffer();
switch (choice) {
case 1: {
int max_num, max_attempts;
get_difficulty(&max_num, &max_attempts);
play_game(max_num, max_attempts, &stats);
printf("\nPress Enter to continue...");
getchar();
break;
}
case 2:
show_stats(&stats);
printf("\nPress Enter to continue...");
getchar();
break;
case 3:
printf("\nExiting game. Goodbye!\n\n");
return 0;
default:
printf("\nInvalid choice.\n");
}
}
return 0;
}
void print_title(void) {
printf("\n");
printf(" =====================================\n");
printf(" | |\n");
printf(" | Number Guessing Game |\n");
printf(" | |\n");
printf(" =====================================\n");
printf("\n");
}
void print_menu(void) {
printf(" ---------------------------------\n");
printf(" | 1. Start Game |\n");
printf(" | 2. View Statistics |\n");
printf(" | 3. Exit |\n");
printf(" ---------------------------------\n");
printf("\n");
}
int get_difficulty(int *max_num, int *max_attempts) {
int choice;
printf("\n Select difficulty:\n\n");
printf(" 1. Easy | 1~50 | 10 chances\n");
printf(" 2. Normal | 1~100 | 7 chances\n");
printf(" 3. Hard | 1~200 | 8 chances\n");
printf(" 4. Extreme | 1~1000 | 10 chances\n");
printf("\n Choice: ");
scanf("%d", &choice);
clear_input_buffer();
switch (choice) {
case 1:
*max_num = 50;
*max_attempts = 10;
break;
case 2:
*max_num = 100;
*max_attempts = 7;
break;
case 3:
*max_num = 200;
*max_attempts = 8;
break;
case 4:
*max_num = 1000;
*max_attempts = 10;
break;
default:
*max_num = 100;
*max_attempts = 7;
}
return choice;
}
int play_game(int max_num, int max_attempts, GameStats *stats) {
int answer = rand() % max_num + 1;
int guess;
int attempts = 0;
int low = 1, high = max_num; // Range for hints
printf("\n ----------------------------------\n");
printf(" Guess a number between 1 and %d!\n", max_num);
printf(" Chances: %d\n", max_attempts);
printf(" ----------------------------------\n\n");
while (attempts < max_attempts) {
int remaining = max_attempts - attempts;
printf(" [Remaining: %d] Current range: %d~%d\n", remaining, low, high);
printf(" Guess: ");
if (scanf("%d", &guess) != 1) {
printf(" -> Please enter a number.\n\n");
clear_input_buffer();
continue;
}
if (guess < 1 || guess > max_num) {
printf(" -> Please enter a number between 1~%d.\n\n", max_num);
continue;
}
attempts++;
stats->total_attempts++;
if (guess < answer) {
printf(" -> UP! (The number is higher)\n\n");
if (guess > low) low = guess + 1;
} else if (guess > answer) {
printf(" -> DOWN! (The number is lower)\n\n");
if (guess < high) high = guess - 1;
} else {
// Correct!
int score = (max_attempts - attempts + 1) * 100 + (max_num / 10);
printf("\n *** Correct! ***\n\n");
printf(" Attempts: %d\n", attempts);
printf(" Score: %d points\n", score);
stats->games_played++;
stats->games_won++;
if (score > stats->best_score) {
stats->best_score = score;
printf("\n New high score!\n");
printf(" Enter your name: ");
scanf("%49s", stats->best_player);
clear_input_buffer();
}
return 1;
}
}
// Lose
printf("\n X Out of chances.\n");
printf(" The answer was %d.\n", answer);
stats->games_played++;
return 0;
}
void show_stats(GameStats *stats) {
printf("\n ========== Game Statistics ==========\n\n");
if (stats->games_played == 0) {
printf(" No games played yet.\n");
return;
}
printf(" Total games: %d\n", stats->games_played);
printf(" Wins: %d\n", stats->games_won);
printf(" Losses: %d\n", stats->games_played - stats->games_won);
float win_rate = (float)stats->games_won / stats->games_played * 100;
printf(" Win rate: %.1f%%\n", win_rate);
float avg_attempts = (float)stats->total_attempts / stats->games_played;
printf(" Average attempts: %.1f\n", avg_attempts);
if (stats->best_score > 0) {
printf("\n High Score\n");
printf(" Score: %d points\n", stats->best_score);
printf(" Player: %s\n", stats->best_player);
}
printf("\n =====================================\n");
}
void clear_input_buffer(void) {
int c;
while ((c = getchar()) != '\n' && c != EOF);
}
Compile and Run¶
gcc -Wall -Wextra -std=c11 guess_game.c -o guess_game
./guess_game
Summary¶
| Concept | Description |
|---|---|
rand() |
Pseudo-random number generation |
srand(time(NULL)) |
Seed initialization |
while (1) |
Infinite loop |
break |
Exit loop |
continue |
Skip to next iteration |
| Struct | Grouping related data |
Exercises¶
- Binary Search AI: Add a mode where the computer guesses the player's number
-
Hint: Always choose the middle value of the range
-
Multiplayer: Mode where two players take turns guessing
-
File Saving: Save and load high scores to/from a file
Next Step¶
05_Project_Address_Book.md -> Let's learn about structs and file I/O!