C语言 猜数字游戏

目录

1. 随机数⽣成

1.1 rand

1.2 srand

1.3 time

1.4 设置随机数的范围

 2. 猜数字游戏实现


 

游戏要求:
1. 电脑⾃动⽣成1~100的随机数
2. 玩家猜数字,猜数字的过程中,根据猜测数据的⼤⼩给出⼤了或⼩了的反馈,直到猜对,游戏结束

1. 随机数⽣成

要想完成猜数字游戏,⾸先得产⽣随机数,可以利用以下函数产生随机数

1.1 rand

C语⾔提供了⼀个函数叫 rand  这个函数是可以⽣成随机数的,函数原型如下所⽰:

 int rand (void);

rand函数会返回一个伪随机数,范围在0到RAND_MAX之间。RAND_MAX的大小取决于具体的编译器实现,但在大多数编译器上,它通常是32767。使用rand函数需要包含stdlib.h头文件。接下来,我们可以多次调用rand函数来生成5个随机数以进行测试。

#include <stdio.h>
#include <stdlib.h>
int main()
{
 printf("%d\n", rand());
 printf("%d\n", rand());
 printf("%d\n", rand());
 printf("%d\n", rand());
 printf("%d\n", rand());
 return 0;
}

 第一次运行                                第二次运行                                第三次运行

             

我们可以观察到,尽管程序每次运行时生成的5个随机数字看起来是不同的,但实际上在每次运行时,它们的序列都是相同的。这表明程序中的随机数生成存在问题。深入了解后会发现,`rand` 函数生成的“随机”数其实是伪随机数。这些伪随机数并不是真正的随机数,而是通过某种算法生成的。真正的随机数是无法预测其下一个值的。

`rand` 函数生成的伪随机数序列是基于一个叫做“种子”的基准值。如果使用相同的种子值,`rand` 函数每次产生的随机数序列都会相同。默认情况下,`rand` 函数的种子值是1,因此每次运行程序时,生成的随机数序列都是相同的。

为了生成每次运行时不同的随机数序列,需要改变种子值。通常可以使用当前时间作为种子值来实现这一点。这样,`rand` 函数在每次运行程序时都会使用不同的种子值,从而生成不同的随机数序列。

1.2 srand

C语⾔中⼜提供了⼀个函数叫 srand ,⽤来初始化随机数的⽣成器的,srand的原型如下
void srand (unsigned int seed);

在程序中,使用 `rand` 函数生成随机数之前,我们可以通过 `srand` 函数来设置种子值(`seed)。` `srand` 函数的参数 `seed` 用于初始化 `rand` 函数的伪随机数生成器。只要种子值每次都不同,`rand` 函数生成的随机数序列也会随之不同。

换句话说,只要 `srand` 设置的种子值是变化的,`rand` 函数生成的随机数序列就会是不同的。因此,我们需要用一个变化的种子值来使 `rand` 生成的随机数具有更多的随机性。通常,程序会使用当前时间作为种子值来保证每次运行时种子值的不同,从而生成不同的随机数序列。

这就解决了看似矛盾的问题:虽然我们希望生成随机数,但需要一个变化的种子值来确保生成的随机数序列是不同的。通过动态变化的种子值,我们可以使 `rand` 函数产生更多样化的随机数

1.3 time

在程序中我们⼀般是使⽤程序运⾏的时间作为种⼦的,因为时间时刻在发⽣变化的。
在C语⾔中有⼀个函数叫 time ,就可以获得这个时间,time函数原型如下:
 time_t time (time_t* timer);

`time` 函数用于获取当前的日历时间。实际上,它返回的是从1970年1月1日0时0分0秒(即UNIX纪元时间)到当前时间的秒数,这个值称为时间戳。`time` 函数的返回值类型是 `time_t`,本质上是一个32位或64位的整数。

如果 `time` 函数的参数 `timer` 是一个非 `NULL` 的指针,函数会将这个时间戳存储到 `timer` 指向的内存中。如果 `timer` 是 `NULL`,函数则只返回时间戳值

要使用 `time` 函数,需要包含头文件 `time.h`

//VS2022 上time_t类型的说明
#ifndef _CRT_NO_TIME_T
 #ifdef _USE_32BIT_TIME_T
 typedef __time32_t time_t;
 #else
 typedef __time64_t time_t;
 #endif
#endif
typedef long __time32_t;
typedef __int64
如果只是让time函数返回时间戳,我们就可以这样写:
time(NULL);//调⽤time函数返回时间戳,这⾥没有接收返回值
我们可以让⽣成随机数的代码改写成如下
#include <stdio.h>
#include <stdlib.h>
#include <time.h>

int main()
{
    // 使用 time 函数的返回值来设置随机数生成器的种子
    // time 函数返回的是从1970年1月1日0时0分0秒到现在的秒数
    // 我们将 time 函数的返回值强制转换为 unsigned int 类型,作为 srand 的种子
    srand((unsigned int)time(NULL));

    // 生成并打印五个随机数
    printf("%d\n", rand());
    printf("%d\n", rand());
    printf("%d\n", rand());
    printf("%d\n", rand());
    printf("%d\n", rand());

    return 0;
}

解释:

  • srand((unsigned int)time(NULL));:这行代码通过调用 time(NULL) 获取当前的时间戳(从1970年1月1日到现在的秒数),并将其作为种子值传递给 srand。这样可以确保每次程序运行时,rand 函数生成的随机数序列都是不同的。
  • rand():生成一个随机数并打印出来。
  •            

多运⾏⼏次看看,每次的运⾏就有差异了。

srand函数是不需要频繁调⽤的,⼀次运⾏的程序中调⽤⼀次就够了。 

1.4 设置随机数的范围

生成0到99之间的随机数:
rand() % 100; // 余数范围是0到99

生成1到100之间的随机数: 

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

如果要⽣成100~200的随机数,⽅法如下:

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

 一般化的公式,用于生成 ab 之间的随机数:

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

 解释:

  • rand() % (最大值 - 最小值 + 1) 生成的余数范围是0到 (最大值 - 最小值)
  • 加上 最小值 后,可以将生成的数值范围调整到 最小值最大值

 2. 猜数字游戏实现

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

// 猜数字游戏函数
void game()
{
    int r = rand() % 100 + 1; // 生成1到100之间的随机数
    int guess = 0;            // 存储用户猜测的数字
    int count = 5;            // 剩余的猜测次数

    while (count > 0)
    {
        printf("\n你还有%d次机会\n", count);
        printf("请猜数字>:");
        scanf("%d", &guess);

        if (guess < r)
        {
            printf("猜小了\n");
        }
        else if (guess > r)
        {
            printf("猜大了\n");
        }
        else
        {
            printf("恭喜你,猜对了\n");
            return; // 猜对了就结束函数
        }

        count--; // 减少剩余次数
    }

    // 当猜测次数用尽后输出正确的值
    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 != 0); // 当选择为0时退出循环

    return 0;
}

 

  • 12
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值