棋牌开发中的随机数

自助开通VIP,整站资源任意下载

    棋牌开发和随机数脱不开关系,因为无论牛牛、梭哈、还是斗地主、麻将,发到的牌都是要运用随机函数的。

随机数是指理论上没有规律可循、在指定范围内每个数的出现几率相等、无法根据之前的数来预测下一个数的数列。一般随机数生成器的基本原理是:首先初始化一个随机种子,其初始值可以是任意的整数;在每次获取随机数时,以随机种子为基础进行某种特殊的运算,获得一个随机数并返回之,然后再对随机种子进行某种运算,改变随机种子的值。这样,就可以生成许多比较随机的数,但同一个初始值的随机种子将会生成完全相同的随机数列。

自然界中发生的现象,只有两种可能:一种是在一定条件下,必然会出现的(或必然不会出现的)事情,如向上抛出的物体必然会下落等;另一种是在一定条件下,不能预见它出现的结果,如“石头、剪子、布”,又如每次从同一高度落下同一只硬币,就不能够预见它哪一面向上,哪一面向下。也就是说,正、反两面的出现是随机的。

随机数就是这样的一种不可预知其出现数值的数字序列,就像每次掷同一颗质地均匀的骰子,可能出现1到6几个数字。这六个数就是随机数的序列。

将放射性物质在一定的时间内放出的粒子数作为随机数,是最理想的。因为它没有人工的干预,所以它是真正的随机数。然而这种随机数,使用起来非常复杂,十分不便。因而在实际中,并不采用这种方法,而是用计算机制作出来。由计算机产生的随机数,是在0和1之间的、无穷无尽的序列。然后根据需要,再在此基础上扩大、转化成任意范围内的随机数。

由计算机制作的随机数,是按照一定的公式计算出来的。这里涉及到伪随机数的概念,什么是伪随机数呢?伪随机数是使用一些称为种子(seed)的初始值通过某种算法得到的。这个算法是确定的,因此产生的数字序列在统计上并不是随机的。不过,假如这个算法优良,那么结果得到的数字序列就能够通过许多合理的随机性测试。这些数字通常被称为伪随机数(psreudorandom number)。除非你知道算法和种子,否则就不大能推测出这个序列。因此,严格来说,并不是真正的随机数,人们把它叫做“伪随机数”。尽管如此,在实际应用中,还是能够满足要求的。伪随机数的缺点是,它具有周期性。就是说,经过一定的序列之后,它又重复回来了。如果这个周期很大,对实际应用并没有什么影响。我们权且可以把它当做随机数看待罢了。随机数在生活当中有着非常广泛的应用,电脑游戏、各种摇彩活动、心理试验、统计工作等,都离不开随机数。寻找计算简单、循环周期很大的随机数,则是数学家的课题。

计算机擅长生成伪随机数,但不擅长生成真正的随机数。伪随机数看起来是随机的,但在算法上是基于前一个随机数计算的。真正的随机数是不可预测的,不重复的,不确定的,并不是将前一个随机数作为输入来生成的。为随机数序列总会重复,只要使用相同的种子,便可准确再现。常用的一种情况:使用当前时间周期数初始化随机数生成器。生成随机数的理想方式是使用随机的物理源,在没有硬件源的情况下,从大量不相关的源中获取随机输入,并使用一个强大的混合函数将他们混合在一起。

    用于随机输入的有:系统日期和时间;系统启动后经过的时间(最小时间单位);用户名或ID;计算机名称或ID;系统线程和进程的状态;CPU继存器的状态;CPU周期(又称机器周期,机器内部各种操作大致可归属为对CPU内部的操作和对主存的操作两大类,由于CPU内部操作速度较快,CPU访问一次内存所花的时间较长,因此用从内存读取一条指令字的最短时间来定义,这个基准时间就是CPU周期(机器周期)。一个指令周期常由若干CPU周期构成。),栈中的内容;鼠标和游戏杆的位置;最后N次击键或控制器输入之间的时间间隔;内存状态(已分配的字节数、可用的字节数等);硬盘驱动器的状态;最后的N个系统消息;GUI状态(窗口位置);最后N个网络分组之间的时间间隔;最后N个网络分组中的数据;存储在主存储器、视频存储器等的半随机地址中的数据;硬件标示符:CPUID,硬盘驱动器ID,BIOSID,网卡ID等。每种输入都提供了一定程度的随机性,从输入源获得的混乱程度越高,输出的随机性越强。

    硬件源(物理源)的输入来源:来自无源声卡(如麦克风)的输入;摄象机的输入;驱动器(硬盘,光驱,DVD)的寻道时间;INTER810芯片组的硬件RNG等。

    混合函数的使用:以非线性的方式将各项输入组合起来,生成输出。DES(以及其他对称加密程序);DIFFIE-HELLMAN(以及其他公共密钥加密程序);MD5,SHA-1(以及其他哈希加密程序)。

    局限性:速度慢,结果的随机度完全取决与输入样本的混乱程度。适用于可持续使用几天的随机数生成器种子值。

好了,下面来看一下这句话是什么意思:
srand(time(NULL));
先看srand()函数有什么作用。它是用来设定种子(seed)的,例:srand(n),则n就是你设定的种子。如果每次设定的种子相同,比如srand(1),那么相当于不调用srand()函数(注意 :如果不显式调用srand()函数,系统只会默认调用一次srand(1)函数,即在第一个rand()函数之前调用;执行第2个第3个……rand()之前不会再调用srand(1)),那么接下来你再调用rand(),得到的随机数序列是相同的,这里给一个例子:

windows 32 console

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

void main( void )
{
int i;

/ Seed the random-number generator with current time so that
the numbers will be different every time we run.
/
//srand( (unsigned)time( NULL ) );

/ Display 10 numbers. /
for( i = 0;   i < 10;i++ )
printf( ”  %6dn”, rand() );
}

注意,这个程序中,我把srand( (unsigned)time( NULL ) )给注释起来了,所以每次运行该程序时,种子是默认给出的,都是同一个值,(vc++中默认种子的值为1),既然种子一样,就像我前面提到的,算法是一定的,所以每次产生的随机数序列都是相同的。在我的电脑上每次运行程序都产生这10个数:

41

18467

6334

26500

19169

棋牌开发中的随机数

15724

11478

29358

26962

24464

所以说这些数是伪随机数。因为真正的随机数每次产生时都不应该相同,包括这个序列也不应该相同。所以说我们要产生真正的随机数,就应当在每次调用rand()之前设定不同的种子,怎样做到这一点呢?使用time(NULL)。

time(NULL)返回的是一个time_t类型的数据,实际上是一个无符号整型(unsigned int)的数据,在这个32位的无符号数中,高16位存放当前Date(年月日)的信息,低16位存当前放Time(时分秒)的信息。时间是在不断变化的,所以每次调用time(NULL)返回的值是不同的(当然两次调用的时间间隔大于等于1秒才行,因为time_t中的信息只精确到秒)
这样srand(time(NULL));    就可以保证每次都会设定新的 种子,从而再调用rand()时会得到不同的随机数序列:再给个例子[2]这个例子仅仅是把前面的例子多加了一句srand(time(NULL));    )

棋牌开发中的随机数

windows 32 console

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

void main( void )
{
int i;

/ Seed the random-number generator with current time so that
the numbers will be different every time we run.
/
srand(time(NULL));

/ Display 10 numbers. /
for( i = 0;   i < 10;i++ )
printf( ”  %6dn”, rand() );
}

这样每次运行程序都会得到10个不同的数,并且每次得到的这10个数都是不同的(注意理解我的意思,每次产生的10个数组成的序列不同)。

注意time(NULL)的作用其实就是将当前时间保存到一个UNIT中返回,

time_t osBinaryTime=time(NULL);相当于以下代码:

CTime   t=CTime::GetCurrentTime();

time_t   osBinaryTime=t.GetTime();

本站源码仅做学术研究,自娱自乐使用,不得用于赌博性质的非法商业用途!转载请说明出处!
棋牌资源网 » 棋牌开发中的随机数

这里有你所需要的,找专业的人做专业的事!

游戏演示 联系客服