猜數字遊戲是初學 C 語言最經典的綜合練習,涵蓋選單介面、隨機數種子、迴圈巢狀、條件判斷、使用者輸入驗證。本文提供標準實作、常見錯誤分析、進階功能擴展與程式碼重構建議。
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main() {
int input = 1;
printf("歡迎使用猜數字遊戲\n");
while (input) {
// 顯示選單
printf("**********************\n");
printf("******* 1.start ******\n");
printf("******* 0. exit ******\n");
printf("**********************\n");
printf("請選擇> ");
scanf("%d", &input);
switch (input) {
case 1: {
int answer = 0;
int guess = 0;
// 設定隨機種子(僅需一次,建議移至 main 開頭)
srand((unsigned int)time(NULL));
answer = rand() % 101; // 0-100
// 猜測迴圈
while (1) {
printf("請猜一個 (0-100) 之間的數: ");
if (scanf("%d", &guess) != 1) {
printf("輸入無效,請輸入整數。\n");
while (getchar() != '\n'); // 清空緩衝區
continue;
}
if (guess > answer) {
printf("你猜大了\n");
} else if (guess < answer) {
printf("你猜小了\n");
} else {
printf("恭喜你,猜對了!答案是 %d\n", answer);
break;
}
}
break;
}
case 0:
printf("遊戲結束,再見!\n");
break;
default:
printf("無效選項,請輸入 0 或 1。\n");
}
}
return 0;
}
| 知識點 | 代碼體現 | 說明 |
|---|---|---|
| 隨機數種子 | srand(time(NULL)) | 以當前時間為種子,每次執行產生不同序列。全程只呼叫一次。 |
| 範圍限制 | rand() % 101 | 取模運算將 0-RAND_MAX 壓縮至 0-100。 |
| 雙層迴圈 | 外層選單、內層猜測 | 外層控制遊戲局數,內層控制單局猜測次數。 |
| 輸入驗證 | scanf(...) != 1 | 檢查掃描成功個數,防止非數字輸入導致死循環。 |
| 緩衝區清理 | while(getchar()!='\n') | 掃描失敗時殘留字符需手動清除。 |
srand():若在猜測迴圈內呼叫,若兩次呼叫間時間差 < 1 秒,種子相同導致產生相同隨機數。修正:移至 main() 開頭。scanf 失敗留下字符在緩衝區,導致無限循環。修正:檢查回傳值並清理緩衝區。rand() % 100 產生 0-99。修正:% 101 產生 0-100。int guess; 未賦初值。修正:int guess = 0; 或在迴圈前賦值。// 1. 記錄猜測次數
int attempts = 0;
while (1) {
attempts++;
// ... 猜測邏輯
if (guess == answer) {
printf("共猜了 %d 次\n", attempts);
break;
}
}
// 2. 難度選單
typedef enum { EASY=50, NORMAL=100, HARD=1000 } Difficulty;
Difficulty level = NORMAL;
printf("選擇難度: 1.Easy(0-50) 2.Normal(0-100) 3.Hard(0-1000): ");
scanf("%d", &level);
answer = rand() % (level + 1);
// 3. 最高分記錄(檔案 I/O)
FILE *fp = fopen("highscore.txt", "r+");
int best = 999;
if (fp) { fscanf(fp, "%d", &best); fclose(fp); }
if (attempts < best) {
printf("🎉 打破最高紀錄!原紀錄: %d 次\n", best);
fp = fopen("highscore.txt", "w");
fprintf(fp, "%d", attempts);
fclose(fp);
}
// 4. 二分搜尋提示(教學模式)
printf("提示:使用二分法最多只需 %d 步\n", (int)log2(level) + 1);
// game.h
void showMenu();
int playRound(int maxRange);
int getValidInput(const char *prompt);
// game.c
#include "game.h"
void showMenu() { /* 印選單 */ }
int getValidInput(const char *prompt) {
int val;
while (1) {
printf("%s", prompt);
if (scanf("%d", &val) == 1) return val;
printf("輸入無效,請重試。\n");
while (getchar() != '\n');
}
}
int playRound(int maxRange) {
int answer = rand() % (maxRange + 1);
int guess, attempts = 0;
while (1) {
guess = getValidInput("請猜數字: ");
attempts++;
if (guess > answer) puts("太大了");
else if (guess < answer) puts("太小了");
else { printf("正確!共猜 %d 次\n", attempts); return attempts; }
}
}
// main.c
int main() {
srand(time(NULL));
int choice;
while ((choice = getValidInput("1.開始 0.離開: ")) != 0) {
if (choice == 1) playRound(100);
}
return 0;
}
透過這個小遊戲的完整開發週期,你將掌握 C 語言程式設計的核心技能:模組化思維、錯誤處理、使用者體驗優化、資料持久化。建議嘗試自行實作上述進階功能,並嘗試加入單元測試(如 Unity 測試框架)驗證核心邏輯。