C语言——猜数字游戏

想在C语言里做一个能和朋友互动的小游戏?猜数字绝对是最经典的入门选择——不用复杂的图形界面,几行代码就能实现‘电脑出题、玩家猜数’的完整逻辑。今天我们就从随机数生成这个核心问题入手,一步步拆解一个能运行、有反馈的猜数字游戏,从基础版到带次数限制的进阶版,让你看懂每一行代码的作用。


一、游戏核心需求

1. 电脑生成1~100的随机数;

2. 玩家猜数,程序反馈“大了/小了”,直至猜对结束。

二、随机数生成的三层核心函数

1. 伪随机数生成:rand()

• 原型:

int rand(void);

• 功能:rand()返回的整数范围是 0 \sim \text{RAND_MAX},其中RAND_MAX是<stdlib.h>头文件中定义的宏,多数编译器(如VC++、GCC)将其定义为32767(即 2^{15} - 1),这是16位有符号整数的最大值。

• 头文件:<stdlib.h>;

• 缺陷:默认种子为1,每次运行程序生成的随机数序列完全相同(伪随机)。

2. 随机数种子初始化:srand()

• 原型:

void srand(unsigned int seed);

• 功能:为rand()设置随机数种子,种子不同则rand()生成的序列不同;

• 头文件:<stdlib.h>;

• 关键:需传入动态变化的种子才能实现真正的“随机”。

3. 动态种子获取:time()

• 原型:

time_t time(time_t* timer);

• 功能:返回从1970年1月1日00:00:00 UTC到程序运行时刻的秒数差值(时间戳);

• 参数说明:

◦ 若timer为NULL:直接返回时间戳;

time(NULL);//调用time函数返回时间戳,这里没有接收返回值

◦ 若timer为非空指针:将时间戳存入timer指向的内存空间;

• 返回值类型:time_t,本质是32位/64位整型(随编译器和系统而定);

• 头文件:<time.h>;

• 作用:利用时间的实时变化特性,作为srand()的种子,保证每次运行的种子唯一。

三、time_t类型的底层定义(以VS2022为例)

#ifndef _CRT_NO_TIME_T
    #ifdef _USE_32BIT_TIME_T
        typedef _time32_t time_t; // 32位整型
    #else
        typedef _time64_t time_t; // 64位整型
    #endif
#endif
typedef long _time32_t;
typedef __int64 _time64_t;

四、随机数范围的通用设置方法

rand()生成的随机数默认范围是0 \sim \text{RAND_MAX},通过取模和偏移可自定义范围,具体实现和原理如下:

1. 生成0~99的随机数

rand()%100; //余数的范围是0-99

原理是对100取模,余数的自然范围就是0到99。

2. 生成1~100的随机数

rand()% 100 + 1;//%100的余数是0~99,0~99的数字+1,范围是1~100

原理是先通过取模得到0~99的数,再加1后,范围就映射为1到100。

3. 生成100~200的随机数

100 + rand()%(200 - 100+1)
//余数的范围是0~100,加100后就是100~200

原理是先取0~100的随机数,再加上100做偏移,最终得到100到200的数。

4. 生成a~b的随机数(通用公式)

a + rand()%(b - a + 1)

原理是先取0~(b-a)的随机数,再加上a做偏移,就能覆盖a到b的所有整数。

关键注意点:srand()函数只需在程序运行时调用一次即可,频繁调用会导致生成的随机数序列重复,失去随机性。

正确生成1~100随机数的代码:

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

int main() {
    // 用时间戳初始化随机数种子
    srand((unsigned int)time(NULL));
    // 生成1~100的随机数(rand()%100得到0~99,加1后范围为1~100)
    int random_num = rand() % 100 + 1;
    return 0;
}

五、伪随机数的本质

伪随机”指rand()并非生成真正的随机数,而是通过固定算法基于“种子”计算得到的数序列。若种子不变(如默认的1),每次运行程序生成的数序列完全相同;只有通过srand()设置动态种子(如time(NULL)),才能让序列表现出“随机”效果。

rand()通过固定算法基于“种子”生成数序列:

1. 种子固定 → 序列固定(如默认种子1,每次运行随机数相同);

2. 种子动态(如time(NULL))→ 序列每次不同(实现“随机”效果)。

六、基础版猜数字游戏代码

实现菜单选择、随机数生成、玩家猜数反馈的核心逻辑,代码如下:

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

// 游戏逻辑函数:实现猜数和反馈
void game() {
    // 生成1~100的随机数
    int r = rand() % 100 + 1;
    int guess = 0;
    while (1) {
        printf("请猜数字:>");
        scanf("%d", &guess);
        if (guess < r) {
            printf("猜小了\n");
        } else if (guess > r) {
            printf("猜大了\n");
        } else {
            printf("恭喜你,猜对了\n");
            break;
        }
    }
}

// 菜单函数:展示游戏选项
void menu() {
    printf("*************************\n");
    printf("******* 1. play *********\n");
    printf("******* 0. exit *********\n");
    printf("*************************\n");
}

int main() {
    int input = 0;
    // 初始化随机数种子,保证每次运行随机数不同
    srand((unsigned int)time(NULL));
    do {
        menu();
        printf("请选择:>");
        scanf("%d", &input);
        switch (input) {
            case 1:
                game(); // 选择1,开始游戏
                break;
            case 0:
                printf("游戏结束\n"); // 选择0,退出游戏
                break;
            default:
                printf("选择错误,重新选择\n"); // 输入其他值,提示错误
                break;
        }
    } while (input); // 当input为0时,退出循环
    return 0;
}

七、进阶版(带5次猜数次数限制)

在基础版的基础上增加猜数次数统计,5次未猜对则判定失败,代码如下:

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

// 带次数限制的游戏逻辑函数
void game() {
    int r = rand() % 100 + 1;
    int guess = 0;
    int count = 5; // 设置5次猜数机会
    while (count) {
        printf("\n你还有%d次机会\n", count);
        printf("请猜数字:>");
        scanf("%d", &guess);
        if (guess < r) {
            printf("猜小了\n");
        } else if (guess > r) {
            printf("猜大了\n");
        } else {
            printf("恭喜你,猜对了\n");
            break; // 猜对则跳出循环,结束本轮游戏
        }
        count--; // 每次猜错,机会数减1
    }
    // 机会用完仍未猜对,提示失败并显示正确答案
    if (count == 0) {
        printf("你失败了,正确值是:%d\n", r);
    }
}

// 菜单函数(与基础版一致)
void menu() {
    printf("*************************\n");
    printf("******* 1. play *********\n");
    printf("******* 0. exit *********\n");
    printf("*************************\n");
}

int main() {
    int input = 0;
    srand((unsigned int)time(NULL));
    do {
        menu();
        printf("请选择:>");
        scanf("%d", &input);
        switch (input) {
            case 1:
                game();
                break;
            case 0:
                printf("游戏结束\n");
                break;
            default:
                printf("选择错误,重新选择\n");
                break;
        }
    } while (input);
    return 0;
}

这个小小的猜数字游戏,其实是C语言入门的“缩影”——从随机数的种子到玩家的交互,每一行都是基础逻辑的落地。

现在你已经能跑通完整代码,不妨试着改改次数、调调范围,甚至加个“难度选择”的小功能。编程的好玩之处,就在于把这些简单逻辑,变成属于你的、能互动的小玩意儿。
 

 

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值