详谈JS中实现种子随机数及作用


Posted in Javascript onJuly 19, 2016

前言

在前端开发中,尤其是游戏开发,经常会用到随机数,那么我们会第一时间想到:Math.random,大家略微的看看如下代码:

for (var i= 0; i<10; i++) { document.writeln(Math.random() +"<br />"); }

运行如上代码,也确实生成了10个不同的数字,当然你可以生成更多,看起来挺不错的,如果仅仅如此,那么本文就没必要写了。

示例

试着想一下,如果在某一个场景,我们做一个游戏,用户玩到一半的时候退出了,这样用户下次进来可以选择继续上一次的进度继续玩,那么现在问题来了:用户玩的进度以及用户的积分等简单的描述数据,我们都可以记录下来,但是游戏里绘制的障碍物、飞行物以及很多装饰类的小玩意儿,他们甚至是每次用户点开始随机输出的,要把画布上所有的东西以及它们的大小,位置等都记录下来,实在是没必要。

于是种子随机数就闪亮登场了,我们如果在画布上元素随机绘制的时候,有一个种子值,页面上所有元素的位置、大小等都是根据这个种子来算的,那么等到第二次绘制的时候只需要传入这个种子,就可以重现之前未完成的画布元素。

那么这个时候,你会发现JS里面自带的Math.random就不好使了,无法满足需求,我们继续看这段代码:

Math.seed = 5; Math.seededRandom = function(max, min) { max = max || 1; min = min || 0; Math.seed = (Math.seed * 9301 + 49297) % 233280; var rnd = Math.seed / 233280.0; return min + rnd * (max - min); }; for (var i= 0; i<10; i++) { document.writeln(Math.seededRandom() +"<br />"); }

运行如上代码你会发现如果种子Math.seed不变,那么生成的随机数是不会变化的,哦了,如果引入这个函数,那么重现游戏场景可以实现了,虽然还需要做更多的细节处理,但机制上是能保证的,本文的重点不是实现一个这样的游戏。

本文的重点是:(Math.seed * 9301 + 49297) % 233280,为什么会是这三个值,而不是其它的到底这三个数字有什么神秘的来历呢?

像Math.seededRandom这种伪随机数生成器叫做线性同余生成器(LCG, Linear Congruential Generator),几乎所有的运行库提供的rand都是采用的LCG,形如:

I n+1=aI n+c(mod m)

生成的伪随机数序列最大周期m,范围在0到m-1之间。要达到这个最大周期,必须满足:
1.c与m互质

2.a - 1可以被m的所有质因数整除

3.如果m是4的倍数,a - 1也必须是4的倍数

以上三条被称为Hull-Dobell定理。作为一个伪随机数生成器,周期不够大是不好意思混的,所以这是要求之一。因此才有了:a=9301, c = 49297, m = 233280这组参数,以上三条全部满足。

总结

以上就是关于种子随机数在JS中如何实现和作用介绍的内容,希望给JavaScript学习者有所帮助

Javascript 相关文章推荐
jQuery获取节点和子节点文本的方法
Jul 22 Javascript
javascript实现修改微信分享的标题内容等
Dec 11 Javascript
js实现鼠标悬浮给图片加边框的方法
Jan 30 Javascript
AngularJS中实现显示或隐藏动画效果的方式总结
Dec 31 Javascript
微信小程序 实现拖拽事件监听实例详解
Nov 16 Javascript
AngularJS服务service用法总结
Dec 13 Javascript
JS实现iframe自适应高度的方法示例
Jan 07 Javascript
cnpm加速Angular项目创建的方法
Sep 07 Javascript
详解vue 兼容IE报错解决方案
Dec 29 Javascript
layui table去掉右侧滑动条的实现方法
Sep 05 Javascript
vue draggable resizable gorkys与v-chart使用与总结
Sep 05 Javascript
vue项目使用高德地图的定位及关键字搜索功能的实例代码(踩坑经验)
Mar 07 Javascript
全面了解JavaScript对象进阶
Jul 19 #Javascript
EasyUI中在表单提交之前进行验证
Jul 19 #Javascript
jQuery EasyUI提交表单验证
Jul 19 #Javascript
js 动态添加元素(div、li、img等)及设置属性的方法
Jul 19 #Javascript
JS把内容动态插入到DIV的实现方法
Jul 19 #Javascript
JS动态给对象添加事件的简单方法
Jul 19 #Javascript
老生常谈js动态添加事件--- 事件委托
Jul 19 #Javascript
You might like
PHP 文件缓存的性能测试
2010/04/25 PHP
PHP Filter过滤器全面解析
2016/08/09 PHP
一个高效的JavaScript压缩工具下载集合
2007/03/06 Javascript
IE和FireFox(FF)中js和css的不同
2009/04/13 Javascript
javascript面向对象入门基础详细介绍
2012/09/05 Javascript
IE中getElementsByName()对有些元素无效的解决方案
2014/09/28 Javascript
详细解读JavaScript的跨浏览器事件处理
2015/08/12 Javascript
Jquery全选与反选点击执行一次的解决方案
2015/08/14 Javascript
js实现类似菜单风格的TAB选项卡效果代码
2015/08/28 Javascript
再次谈论React.js实现原生js拖拽效果引起的一系列问题
2016/04/03 Javascript
String字符串截取的四种方式总结
2016/11/28 Javascript
使用BootStrap实现悬浮窗口的效果
2016/12/13 Javascript
JavaScript实现的select点菜功能示例
2017/01/16 Javascript
webpack+vue中使用别名路径引用静态图片地址
2017/11/20 Javascript
vue 实现类似淘宝星级评分的示例
2018/03/01 Javascript
vue实现tab切换外加样式切换方法
2018/03/16 Javascript
利用jquery和BootStrap实现动态滚动条效果
2018/12/03 jQuery
微信小程序webview实现长按点击识别二维码功能示例
2019/01/24 Javascript
javascript之分片上传,断点续传的实际项目实现详解
2019/09/05 Javascript
微信小程序 点击切换样式scroll-view实现代码实例
2019/10/11 Javascript
node+multer实现图片上传的示例代码
2020/02/18 Javascript
Vue Router的手写实现方法实现
2020/03/02 Javascript
python使用pyhook监控键盘并实现切换歌曲的功能
2014/07/18 Python
详解python基础之while循环及if判断
2017/08/24 Python
Python实现PS滤镜碎片特效功能示例
2018/01/24 Python
TensorFlow的权值更新方法
2018/06/14 Python
python绘制热力图heatmap
2020/03/23 Python
python输入中文的实例方法
2020/09/14 Python
Pytorch - TORCH.NN.INIT 参数初始化的操作
2021/02/27 Python
英国花园药房: The Garden Pharmacy
2017/12/28 全球购物
播音主持专业个人自我评价
2014/01/09 职场文书
《掌声》教学反思
2014/02/23 职场文书
安全在我心中演讲稿
2014/09/01 职场文书
大学生饮品店创业计划书范文
2019/07/10 职场文书
Redis Cluster集群动态扩容的实现
2021/07/15 Redis
排查MySQL生产环境索引没有效果
2022/04/11 MySQL