【C语言】:详解随机数的生成和猜数字游戏的实现

简介: 【C语言】:详解随机数的生成和猜数字游戏的实现

1.随机数的生成

想要完成猜数字游戏,首先要产生随机数,下面将介绍如何产生随机数。

1.1 rand

C语言提供了一个函数rand,可以产生随机数,需要包含头文件stdlib.h

函数原型:int rand (void)

rand函数会返回一个伪随机数(因为它是由算法生成的,不能算做纯粹的随机),这个随机数的范围是0~RAND_MAX之间,大部分编译器上的RAND_MAX是32767。

我们可以测试一下rand函数,多测试几组,观察随机数:

#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函数默认的种子是1。

所以说,我们想要用rand函数产生随机数,就必须要让它的种子不断的发生变化,从而每次运行产生的随机数都不相同,那我们该如何做呢?

2. srand

C语言又提供了一个函数srand,用来初始化随机数生成器的,引用的头文件是stdlib.h

函数原型:void srand (unsigned int seed)

程序在调用rand函数前先调用srand函数,通过srand函数的参数seed来设置rand函数生成随机数的种子,只要种子在变化,每次生成的随机数也会发生变化。

那也就是说,只要seed是随机值,那rand每次运行也将产生随机数,在生成随机数的时候又需要一个随机数,那这不是矛盾了吗,要如何解决这个问题呢?

3. time

我们一般是使用程序运行的时间作为种子的,因为时间每时每刻都在变化。

C语言中有一个函数叫time,可以获得这个时间,需要包含头文件time.h

函数原型:time_t time(time_t* timer)

time_t的本质是无符号整型

如果它的参数是NULL,就返回这个时间的差值,C语言中称time函数返回的那个差值叫做时间戳

时间戳是指格林威治时间1970年01月01日00时00分00秒(北京时间1970年01月01日08时00分00秒)起至现在的总秒数。

我们使用这三个函数再次进行随机数的生成:

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main()
{
    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;
}

第一次调试结果:

第二次调试结果:

由上图可知,多次运行产生的数据不同了,这就实现了随机数的生成。

2. 猜数字游戏实现

接下来我们就可以利用上文所说的产生随机数的方法来实现一个简单的猜数字小游戏。

游戏要求如下:

  1. 电脑自动生成1-100的随机数;
  2. 根据玩家猜测数据的大小给出大了或小了的反馈;
  3. 玩家共有5次机会,用完就失败,游戏结束。

代码实现如下:

//菜单
void menu()
{
  printf("#########################\n");
  printf("#####    1.play     #####\n");
  printf("#####    0.exit     #####\n");
  printf("#########################\n");
}
//猜数字的过程
void game()
{
  int ret = rand() % 100 + 1;//生成1~100之间的数字
  int guess = 0;
  int count = 5;
  while (count)
  {
    printf("你现在还有 %d 次机会\n", count);
    printf("请输入要猜的数字:>");
    scanf("%d", &guess);
    if (ret < guess)
    {
      printf("猜大了\n");
    }
    else if (ret > guess)
    {
      printf("猜小了\n");
    }
    else
    {
      printf("恭喜你,猜对了!\n数字是%d\n", guess);
      break;
    }
    count--;
  }
  if (count == 0)
  {
    printf("很遗憾,5次机会用完,挑战失败,随机数是%d.\n", ret);
  }
}
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("选择错误,请重新选择:>");
      break;
    }
  } while (input);
  return 0;
}

这里我们需要注意的是如何设置随机数的范围,我们知道,一个数%(模运算)100的余数一定是0~99,再+1就生成1到100的范围

再比如我们要随机生成100到200之间的数据时,只需要用rand()%101+100即可,因为一个数%101的余数一定是0到100,在+100后范围就是100到200了。

目录
相关文章
|
4天前
|
程序员 C语言
C语言小游戏之猜数字
C语言小游戏之猜数字
14 5
|
4天前
|
算法 编译器 C语言
猜数字游戏C语言代码实现
猜数字游戏C语言代码实现
|
1天前
|
存储 C语言
C语言实战 | “贪吃蛇”游戏重构
在程序设计中,模块化思维至关重要,尤其对于复杂项目,它帮助分解任务,便于团队协作。以“贪吃蛇”游戏为例,游戏涉及两个角色:蛇和食物。使用数组存储蛇的位置,变量存储食物位置。游戏流程分为初始化、显示和更新数据。初始化时,食物位置随机,蛇的位置根据数组设定。显示数据则根据这些信息在屏幕上呈现角色。更新数据时,处理蛇的移动和增长以及食物的生成和消失。类似地,通过模块化方法可开发“打砖块”游戏,涉及球、球拍和砖墙,每个角色都有相应数据结构和更新逻辑。通过这种方式,游戏开发就像搭建积木,遵循框架逐步实现。
11 0
C语言实战 | “贪吃蛇”游戏重构
|
3天前
|
C语言
【海贼王编程冒险 - C语言海上篇】怎样用C语言实现简单的扫雷游戏?
【海贼王编程冒险 - C语言海上篇】怎样用C语言实现简单的扫雷游戏?
5 1
|
3天前
|
C语言
【海贼王编程冒险 - C语言海上篇】C语言如何实现简单的三子棋游戏?
【海贼王编程冒险 - C语言海上篇】C语言如何实现简单的三子棋游戏?
7 1
|
3天前
|
存储 安全 Serverless
扫雷游戏C语言代码实现——万字长文超详细,手把手教你实现,新手也能学会
扫雷游戏C语言代码实现——万字长文超详细,手把手教你实现,新手也能学会
|
4天前
|
存储 定位技术 API
C语言实战 -- 经典贪吃蛇游戏(含完整源码)
C语言实战 -- 经典贪吃蛇游戏(含完整源码)
9 1
|
1天前
|
C语言
C语言实现猜数字游戏:代码详解与函数解析
C语言实现猜数字游戏:代码详解与函数解析
4 0
|
1天前
|
存储 C语言
C语言实战 | “俄罗斯方块”游戏重构
摘要(Markdown格式): 在之前的游戏中,全局变量的过度使用导致存储浪费和低代码通用性。以“贪吃蛇”为例,显示功能依赖全局变量,限制了函数的复用。通过参数传递代替全局变量,如在“俄罗斯方块”等游戏中控制物体运动的函数,可提升代码重用性和模块化。重构过程中,即使小到变量命名和代码精简的改进,也能逐步带来程序质量的显著提升。
5 0
|
4天前
|
存储 C语言
C语言实战——扫雷游戏
C语言实战——扫雷游戏
9 0