【学习拓展】C语言 随机数应用:伪随机机制
2015-10-06 12:54
387 查看
一、总论
1.伪随机机制的意义
1.1 什么是伪随机机制日常生活中大家都喜欢玩单机或者网络游戏,而在这些游戏中常常会存在随机,比如暴击率20%或者被动击晕15%等等,而在这些随机事件中,我们往往被告知这些随机事件也能分成两类:一类是固定的概率,常被称为“真随机”,另一类是根据游戏行为有变化的概率,则叫做“伪随机”。我们都知道计算机只能产生伪随机数,那么这里的“真随机”和“伪随机”也不是我们通常对于计算机生成随机数的随机性质的定义,而是关于这个可见概率的具体实施方法。
1.2 为什么要使用伪随机机制
所谓的“真随机”在足够大的样本下,其中某一段的连续样本会距离整体期望产生较大的偏差,简单地说,就是“脸黑,怎么一直不暴击”或者“怎么脸那么好,一直在爆击”。而“伪随机”则在具体的游戏进程中对概率进行了及时的修正,以图实现足够稳定的样本子序列。举个简单的例子的话,就是当你打不出爆击时会增加下一次的概率,而你连续打出爆击时则会降低概率,虽然这对于某些运气好的玩家来说可能是一个噩耗,但是总体上来说,这挽救了某些运气实在太糟糕的朋友。
2. 一个合理的伪随机机制的数据
2.1 以一个被动击晕技能为模版假设这个技能来自某款知名ARPG游戏,并且这个技能在某个前版本里被修正成了伪随机机制
被动击晕:概率25%
显然这个数据的大小是和我们玩的各类游戏中的被动都十分接近的,所以这个样本有其代表性
2.2 伪随机机制的实现数据
首先需要感谢前辈们为我们分析出了WAR3这款经典的RTS游戏内的伪随机实现过程,我们可直接套用这个关系来实现我们的伪随机机制。
P是游戏中显示的概率,c是实际操作概率,maxN是第N次连续不触发后必定触发的临界,Pcount为大样本测试下的实际概率
而具体实现流程则是
1.第一次攻击,概率为C,如果暴击返回1,未爆击进入2
2.第二次攻击,概率为2C,如果暴击返回1,未爆击进入3
……
N.第N次攻击,必定爆击,返回1
那么我们的代码也会依照着这样一个明确的流程来实现。
二、实现
//伪随机实现过程 #include<iostream> #include<cstdlib> #include<cstring> using namespace std; #define P 200 //P和C均扩大若干倍以方便计算 #define C 84.75 // #define maxN 11 //参照表格 #define Num 100 //实际测试组数 int main() { bool a[1001]; double cUsing=C; int p,count=0; int i,j; srand(time(NULL));//设置种子 for(i=1;i<=Num;i++){ memset(a,false,sizeof(a));//初始化判断生效数组 for(j=0;j<=(int)cUsing;j++){//根据当前的第N步C值将前C个值赋值为真 a[j]=true; } p=(int)1000*rand()/RAND_MAX;//生成随机数0~1000 if(a[p]){//根据数组的值判断是否生效 cout<<cUsing<<" Y"<<endl; count++; cUsing=C; } else{ cout<<"N"<<endl; cUsing+=C; } } cout<<1.0*count/Num<<endl;//输出实际概率 return 0; }
通过调整Num我们来测试多组数据
Num#######实际样本概率(理论值0.25)###误差[(理论-实际)/理论]
100 ####### 0.235 ################### -0.06
100 ####### 0.247 ################### -0.012
1000 ###### 0.255 #################### 0.02
1000 ###### 0.251 #################### 0.004
10000 ##### 0.2516 ################### 0.0064
10000 ##### 0.2518 ################### 0.0072
100000 #### 0.24989 ################## 0.00044
100000 #### 0.25048 ################## 0.00192
可以料想到随着样本的足够大,我们的确可以实现较为稳定的输出结果:25%的暴击概率
三、总结
随着网络游戏的不断发展,概率触发这个增进游戏不确定度的机制在游戏中愈发多的被使用,如炉石传说中的食人魔一族、DOTA2中各类击晕和爆击,甚至是整个RPG游戏族内的装备爆率,都要利用到概率这一利器,而其中有一些是固定概率的“真随机”,而另一部分则是不定概率“伪随机”,这些各有特色的机制让我们的游戏过程更为随机,让我们的游戏结果更为的出乎意料,也让我们获得了更多快乐。而这个应用则让我们实际操作了一次伪随机机制的运行过程,让我们对游戏背后的运行原理加深了理解,希望能够帮助到未来有志于从事游戏开发的朋友。
如发现有代码上的错误或者有所疑问,请在博文后留言。
相关文章推荐
- 使用C++实现JNI接口需要注意的事项
- 关于指针的一些事情
- 100 个最佳 Ubuntu 应用(中)
- 在 AppImage、Flathub 和 Snapcraft 平台上搜索 Linux 应用
- c++ primer 第五版 笔记前言
- share_ptr的几个注意点
- 24 个必备的 Linux 应用程序
- 注册表趣味应用小集
- 远程控制技术的应用
- 路由器访问列表的应用
- xDSL技术及其应用
- C#定时器和随机数
- Lua中调用C++函数示例
- Lua和C语言的交互详解
- Lua教程(一):在C++中嵌入Lua脚本
- 基于XML的桌面应用
- Lua教程(二):C++和Lua相互传递数据示例
- SQL Server 2008 R2 应用及多服务器管理
- 基于C#生成随机数示例
- ORACLE随机数DBMS_RANDOM包