目录
1.前言
码接上回:三子棋逻辑的基本搭建
https://mp.csdn.net/mp_blog/creation/editor/128704393
为了让下篇“三子棋自定义函数的实现”的行文节奏更紧凑,这里先插叙一个小知识点:随机数的创建
假想我们已经实现了玩家下棋的功能,三子棋双人版这时候也就可以发布了,但考虑到一部分群体的需求,我们想再设计一个人机对战版,我们玩家下棋好办,键入两个数字表示坐标就好,但怎么让电脑自己选择两个数字呢?难不成是这样:)
printf("电脑,请选择两个不大于3的非零正整数:");
电脑内心os:哈 哈 !憨 憨 说 的 就 是 你 吧 !哈 哈 哈:)
2.随机数生成函数:int rand(void)
2.1函数简介
其实C语言的库函数里有个叫rand()的函数,它可以实现随机生成数字的功能,函数参数为void,函数返回值是一个根据种子生成的随机数(种子是什么,后面会给解释)头文件是<stdlib.h>
补充说明:rand()函数返回的随机数的范围是 0 到 RAND_MAX 之间,RAND_MAX 是一个常量,它的默认值在不同的环境中会有所不同,但是它的值至少是 32767。
example:
#include <stdlib.h>
#include <stdio.h>
int main()
{
printf("随机数:");
for (int i = 0; i < 10; i++)
{
printf("%d ", rand());
}
return 0;
}
2.2控制随机数的范围
有的老铁可能想问:“这个随机数的范围太广了,能不能给它限制一个范围?比如:1到10?”
这是个好想法,这时候就要用到神奇的取余符号:%,当 左操作数 % 右操作数 时,得到的值的范围就是 小于右操作数的正整数(包括0) 让我们看看效果:
#include <stdlib.h>
#include <stdio.h>
int main()
{
printf("随机数:");
for (int i = 0; i < 10; i++)
{
printf("%d ", rand()%10);
}
return 0;
}
good!生成的都是个位数,后面再 +1 即可将范围控制在 1 到 10 之间了。
2.3种子及其设置方法
2.3.1种子的作用
细心的老铁可能发现了:“怎么两次生成的随机数的个位都一样啊?那如果跟电脑下三子棋,它每次不都是一样的套路吗?”
good!你就是再世美猴王 吧!!!(火眼金睛的你再次发问:“你为什么要把 王 和 吧 两个字分开?!!” 我说:你轻声连贯地读几遍“美猴 王吧”就清楚了:)
咳咳......回到正题,两波生成的随机数其实不只是个位相同,它们是完全相同的!!!不信的话,你再运行几遍就明白了,这是因为rand()函数的种子一直都是默认的初始值,生成的随机数自然也是一样的了,设置不同的种子,计算机就会让rand()就会返回不同系列的数字。
2.3.2种子的设置方法
1.void srand(unsigned int seed)
一个种子设置函数(种子就是一个unsigned int型的数)头文件和rand()一样是<stdlib.h>,无返回值,函数参数是无符号整型,也即种子。
example:
#include <stdlib.h>
#include <stdio.h>
int main()
{
srand(1);
printf("随机数1:");
for (int i = 0; i < 10; i++)
{
printf("%d ", rand());
}
srand(2);
printf("\n随机数2:");
for (int i = 0; i < 10; i++)
{
printf("%d ", rand());
}
return 0;
}
2.我们也可以在rand()函数的括号里设置它的种子:
#include <stdlib.h>
#include <stdio.h>
int main()
{
printf("随机数1:");
for (int i = 0; i < 10; i++)
{
printf("%d ", rand(1));
}
printf("\n随机数2:");
for (int i = 0; i < 10; i++)
{
printf("%d ", rand(2));
}
return 0;
}
通过设置不同的种子,电脑在下三子棋的时候就能使用不同的套路了,可是,每次种子的输入都是要我们人为输入,是不是感觉有点不对味,这随机数,随机地不够纯粹啊!还得人为输入,多麻烦啊!有没有一种一直变化的无符号整型数或者变量啊?
有“聪明”的小伙伴可能想到了:“用rand()做种子不就行了吗:)”呃呃,虽然不管用,但冲你看文章时还有在思考的行为点个赞,那为什么不管用呢?因为你这样做,每次重新运行时,种子是按一套固定的套路变化的,那么生成随机数的规律不也是一摸一样的?
那怎么办呢?其实,是有一直变化的无符号整型数的,它叫时间戳。
2.4 time(NULL)获取时间戳
time(NULL)的返回值就是时间戳,时间戳是一个无符号整型数,其大小是格林威治时间自1970年1月1日(00:00:00 GMT)至当前时间的总秒数,所以每过一秒它的值就会改变,将time(NULL)设置为种子,这样每一次随机数生成的种子都会是不一样的,也就无规律可言了,随机数也就实现了真正意义上的随机了。
time()函数的头文件是<time.h>,函数参数为NULL时返回的是时间戳:
example:
#include <stdlib.h>
#include <stdio.h>
#include <time.h>
int main()
{
srand((unsigned int)time(NULL));//虽然不进行类型转换也不会报错,但这里建议强制类型转化一下,让实参和形参的类型统一,养成良好的代码风格,代码的bug也就会少很多
printf("随机数1:");
for (int i = 0; i < 10; i++)
{
printf("%d ", rand());
}
printf("\n随机数2:");
for (int i = 0; i < 10; i++)
{
printf("%d ", rand());
}
return 0;
}
3.总结
创建随机数用int rand(void)函数,随机数的创建规律与种子有关,种子是一个无符号整型数,种子的设置可使用void srand(unsigned int seed)函数,要想每分每秒都设置不同的种子,用time (NULL)获取时间戳当种子即可。
文章到这里就结束了,如有错误之处,欢迎在评论区中指出,让我们一起学习!共同进步!