控制台猜单词:程序挑一个词,显示下划线遮罩,你逐字母猜,猜错 6 次小人就吊死。练的是字符数组、状态标记和字符串处理。
1. 选词与遮罩
单词表用字符指针数组;选中的词复制到 word,遮罩数组 mask 初始全为 '_',猜中就把对应位置换成字母:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <time.h>
const char *pool[] = {"python", "keyboard", "monitor", "mouse", "camera",
"guitar", "rocket", "planet", "winter", "garden"};
#define WORDS (int)(sizeof(pool) / sizeof(pool[0]))
char word[32], mask[32];
void pick_word(void) {
strcpy(word, pool[rand() % WORDS]);
int len = (int)strlen(word);
for (int i = 0; i < len; i++) mask[i] = '_';
mask[len] = '\0';
}
void reveal(char ch) {
for (int i = 0; word[i]; i++)
if (word[i] == ch) mask[i] = ch;
}
2. 猜错计数与 ASCII 小人
猜错一次 wrong++,用字符串数组画 6 个阶段的小人。猜中全部字母就赢:
const char *stages[] = {
" +---+\n |\n |\n |\n |\n=========",
" +---+\n O |\n |\n |\n |\n=========",
" +---+\n O |\n | |\n |\n |\n=========",
" +---+\n O |\n /| |\n |\n |\n=========",
" +---+\n O |\n /|\\ |\n |\n |\n=========",
" +---+\n O |\n /|\\ |\n / |\n |\n=========",
" +---+\n O |\n /|\\ |\n / \\ |\n |\n=========",
};
int all_guessed(void) {
for (int i = 0; word[i]; i++)
if (mask[i] == '_') return 0;
return 1;
}
3. 完整代码
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <time.h>
const char *pool[] = {"python", "keyboard", "monitor", "mouse", "camera",
"guitar", "rocket", "planet", "winter", "garden"};
#define WORDS (int)(sizeof(pool) / sizeof(pool[0]))
char word[32], mask[32];
const char *stages[] = {
" +---+\n |\n |\n |\n |\n=========",
" +---+\n O |\n |\n |\n |\n=========",
" +---+\n O |\n | |\n |\n |\n=========",
" +---+\n O |\n /| |\n |\n |\n=========",
" +---+\n O |\n /|\\ |\n |\n |\n=========",
" +---+\n O |\n /|\\ |\n / |\n |\n=========",
" +---+\n O |\n /|\\ |\n / \\ |\n |\n=========",
};
void pick_word(void) {
strcpy(word, pool[rand() % WORDS]);
int len = (int)strlen(word);
for (int i = 0; i < len; i++) mask[i] = '_';
mask[len] = '\0';
}
void reveal(char ch) {
for (int i = 0; word[i]; i++)
if (word[i] == ch) mask[i] = ch;
}
int all_guessed(void) {
for (int i = 0; word[i]; i++)
if (mask[i] == '_') return 0;
return 1;
}
int main(void) {
srand((unsigned)time(NULL));
pick_word();
int wrong = 0;
char guessed[26] = {0};
int gcnt = 0;
printf("===== 猜单词 =====\n");
while (wrong < 6 && !all_guessed()) {
printf("%s\n单词: %s 猜错 %d/6\n", stages[wrong], mask, wrong);
printf("猜一个字母: ");
fflush(stdout);
char ch;
scanf(" %c", &ch);
int dup = 0;
for (int i = 0; i < gcnt; i++)
if (guessed[i] == ch) dup = 1;
if (dup) { printf("这个猜过了!\n"); continue; }
guessed[gcnt++] = ch;
if (strchr(word, ch)) { reveal(ch); printf("对了!\n"); }
else { wrong++; printf("错了!\n"); }
}
if (all_guessed()) printf("\n恭喜!单词是 %s\n", word);
else printf("%s\n吊死了!单词是 %s\n", stages[wrong], word);
return 0;
}
4. 运行与常见问题
保存为 hangman.c,gcc hangman.c -o hangman 后运行。常见问题:①重复字母不计数——用 guessed 数组去重;②输入大写没反应——统一转小写(tolower);③反斜杠乱码——画小人时 \\ 在 C 里要写 \\\\。
💡 改进方向:①难度分级;②分类词库(动物/编程);③提示系统;④计分(猜得越快越高);⑤支持中文词。