资讯专栏INFORMATION COLUMN

C语言每日一练——第61天:掷骰子游戏

whlong / 3706人阅读

摘要:原型和配合使用产生伪随机数序列。问题分析思路可以参照前面掷骰子小游戏的实现原理。

C语言每日一练
2021年11月21日

实现掷骰子小游戏

在开始今天的练习前,我先写一个有趣的C语言小游戏——掷骰子(zhì tóu zi)

实现原理

大家对骰子应该不陌生,让我们先看看百度词条的介绍:

掷骰子
拼音:zhì tóu zi
骰子: 既色子,用象牙、骨头或塑料等较坚硬物体做的小四方块;每面刻有点数,一到六,常用一对做各种游戏或赌博。
掷骰子:先摇动骰子,然后抛掷使两个骰子都随意停止在一平面上。
——百度百科

掷骰子时,每次能掷出的点数为1~6,且是随机的,那么如何用C语言来产生这一随机数呢?

这时就要用到rand()srand()函数了:

srand函数是随机数发生器的初始化函数。原型:void srand(unsigned int seed);
srandrand()配合使用产生伪随机数序列。

  1. rand()
    原型:int rand(void)
    功能:产生随机值,从srand (seed)中指定的seed开始,返回一个[seed, RAND_MAX(0x7fff))间的随机整数。
  2. srand()
    原型:void srand(unsigned seed)
    参数:seedrand()的种子,用来初始化rand()的起始值。
    功能:可以认为rand()在每次被调用时,它都会查看srand(seed)中指定的seed值,如果存在srand(seed),那么它会自动调用srand(seed)一次来初始化它的起始值。如果用户在此之前没有调用过srand(seed),它会自动调用srand(1)一次。

——百度百科

上面提到了rand()函数只能生成伪随机数,意思是如果起始值seed固定,那么每次程序运行,它产生的随机数序列都是相同的,而不是真正意义上的随机数。形象地说,如果seed值固定,那每次程序运行,第一次掷到的点数都是固定的,这显然不合理,那怎么生成更加合理的随机数呢?

补充:
种子在每次启动计算机时是随机的,但是一旦计算机启动以后它就不再变化了;也就是说,每次启动计算机以后,种子就是定值了,所以根据公式推算出来的结果(也就是生成的随机数)就是固定的。——http://c.biancheng.net/view/2043.html

我们都知道系统的时间值(总秒数)是时刻都在变化着的,如果把时间秒数当做随机数的种子seed,那岂不是能实现真正的随机数?答案是方法可行,但并不能产生真正的随机数,因为时间是递增的,是有规律的数字序列,所以产生的随机数也会呈现一定的规律,但是,此时的随机数已经足够我们用来完成掷骰子游戏了,所以我们也没必要去纠结是否是真正的随机数(可能计算机本来就无法产生真正随机数)。

要想获取系统时间秒数,需要用到time()函数:

time() 是指返回自 Unix 纪元(January 1 1970 00:00:00 GMT)起的当前时间的秒数的函数,主要用来获取当前的系统时间,返回的结果是一个time_t类型。
time_t time(time_t *t);
如果t是空指针,直接返回当前时间。如果t不是空指针,返回当前时间的同时,将返回值赋予t指向的内存空间。
——百度百科

time_t的原型就是long int,这个函数的实现原理我们也没必要去深究,我们只要清楚它能返回秒数就足够了。
程序中,我们可以通过下面的语句初始化随机数种子产生随机数

srand((unsigned)time(NULL)); //用系统秒数初始化随机数种子ret = rand();                //产生随机数,赋值给ret变量

现在生成了随机数,那如何将随机数转换成骰子的点数呢?
骰子一般都是正方体,有6个面,正面朝上的即为点数,那么它就有6种点数,分别是1~6,我们将刚才生成的随机数对6取余,即可将随机数限定在0~5之间,再加上1,就是我们要的随机点数了:

ret = rand() % 6 + 1;       //ret即为随机点数

源码介绍

原理介绍完了,接下来直接上代码

代码由两个部分构成:

  1. 菜单打印:打印功能选择,显示上次投骰子的结果
  2. 操作选择:选择掷骰子或退出退出程序
#include  #include      //srand()/rand()#include        //time()int main(){    char choice = "/0"; //菜单选择    int ret = 0;    //用系统秒数初始化随机数种子    srand((unsigned)time(NULL));    while(1)    {              /* 1.菜单打印 */        system("cls");  //清屏--Windows系统        printf("======================/n");        printf("|     掷骰子游戏     |/n");        printf("|  1:掷骰子  0:退出  |/n");        if(ret)            printf("|     上轮点数:%d     |/n", ret);        printf("======================/n");        /* 2.操作选择 */        printf("请选择>>>>>>>/n");        scanf(" %c", &choice);    //输入选择                                  //" %c" 可以吃前面的空格和回车        while(getchar() != "/n"); //吃掉除choice外其它字符        ret = 0;                  //初始化点数        switch(choice)        {            case "0":             	printf("Goodbye!/n");    			return 0;   //退出            //掷骰子(产生1 ~ 6 随机数)            case "1":             	ret = rand() % 6 + 1;                break;            default: printf("无效选择!/n");        }    }    return 0;}

效果展示

今日练习

题目描述

骰子是一个有六个面的正方体,每个面分别印有1〜6之间的小圆点代表点数。假设这个游戏的规则是:两个人轮流掷骰子6次,并将每次投掷的点数累加起来。点数多者获胜;点数相同则为平局。

要求编写程序模拟这个游戏的过程,并求出玩100盘之后谁是最终的获胜者。

问题分析

思路可以参照前面掷骰子小游戏的实现原理。
实现步骤:两层循环,外层循环100次,内层循环6次,每次都将他们掷骰子的点数进行累加,最后总点数大的即为赢家,如果点数相同,则平局。

代码实现

#include #include #include int main(){    int sum_1 = 0, sum_2 = 0;    int i = 0, j = 0;    //用系统秒数初始化随机数种子    srand((unsigned)time(NULL));    for(i = 0; i < 100; i++)    {        for(j = 0; j < 6; j++)        {            //获取骰子点数            sum_1 += rand() % 6 + 1;            sum_2 += rand() % 6 + 1;        }    }    printf("甲的总点数:%d/n", sum_1);    printf("乙的总点数:%d/n", sum_2);    if(sum_1 > sum_2)        printf("甲获胜!/n");    else if(sum_1 == sum_2)        printf("平局.../n");    else        printf("乙获胜!/n");    return 0;}

运行结果

由于掷骰子点数是随机的,所以获胜者也是随机的。

结果1:

结果2:


把他们掷骰子次数调为1,试了n次之后,终于平局了?

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/124091.html

相关文章

  • C语言每日一练——62:选美比赛

    摘要:语言每日一练年月日文章目录题目描述问题分析代码实现运行结果题目描述用语言编写软件完成以下任务一批选手参加比赛,比赛的规则是最后得分越高,名次越低。 C语言每日一...

    tuomao 评论0 收藏0
  • 30分钟入门比特币与区块链

    摘要:文章前部分适合想了解比特币和区块链的非开发人员,整篇文章适合想转入比特币与区块链相关开发的技术人员。张三和李四均可通过查询区块链网络确认转账成功。   常见的比特币与区块链入门文章大约分为两类,一类是面向非开发人员的科普读物;另一类是面向开发人员的技术指南。前者易流于浅表,让读者接触了一堆名词和概念,却无法对比特币与区块链有个直观的认识;而后者又往往直接进入细节,使开发人员一叶障目不能...

    learning 评论0 收藏0
  • Python学习之路14-生成数据

    摘要:小结本篇主要讲述了如何生成数据集以及如何对其进行可视化如何使用创建简单的图表如果使用散点图来探索随机漫步过程如何使用创建直方图,以及如何使用直方图来探索同时掷两个面数不同的骰子的结果。 《Python编程:从入门到实践》笔记。从本篇起将用三篇的篇幅介绍如何用Python进行数据可视化。 1. 前言 从本篇开始,我们将用三篇的篇幅来初步介绍如何使用Python来进行数据可视化操作。本篇的...

    wanglu1209 评论0 收藏0
  • 用animation的steps属性制作帧动画

    摘要:于是我顺着他的思路,用上了在中的属性。修改效果如下但是这都不是我们需要的效果,因为帧动画的关键在于瞬变。在的中,有一个属性。表示将动画分为帧。这个位置变化没有过渡效果,这就是的特点阶跃性。  昨天火急火燎地接到一个任务,说是要做一个掷骰子的游戏,关于掷骰子期间的过渡动画,我本来是想用css 3d制作一个立体的骰子,然后叫UI给6张平面图贴上去。再用translate3d来操作。然而UI考虑得...

    googollee 评论0 收藏0
  • 用animation的steps属性制作帧动画

    摘要:于是我顺着他的思路,用上了在中的属性。修改效果如下但是这都不是我们需要的效果,因为帧动画的关键在于瞬变。在的中,有一个属性。表示将动画分为帧。这个位置变化没有过渡效果,这就是的特点阶跃性。 昨天火急火燎地接到一个任务,说是要做一个掷骰子的游戏,关于掷骰子期间的过渡动画,我本来是想用css 3d制作一个立体的骰子,然后叫UI给6张平面图贴上去。再用translate3d来操作。然而UI考虑得十...

    zhichangterry 评论0 收藏0

发表评论

0条评论

whlong

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<