详谈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 相关文章推荐
FireFox中textNode分片的问题
Apr 10 Javascript
jQuery消息提示框插件Tipso
May 04 Javascript
实现音乐播放器的代码(html5+css3+jquery)
Aug 04 Javascript
Bootstrap自动适应PC、平板、手机的Bootstrap栅格系统
May 27 Javascript
JS与HTML结合使用marquee标签实现无缝滚动效果代码
Jul 05 Javascript
使用JavaScript实现链表的数据结构的代码
Aug 02 Javascript
jQuery plugin animsition使用小结
Sep 14 jQuery
iview给radio按钮组件加点击事件的实例
Sep 30 Javascript
layui 富文本编辑器和textarea值的相互传递方法
Sep 18 Javascript
layui form.render('select', 'test2') 更新渲染的方法
Sep 27 Javascript
countUp.js实现数字动态变化效果
Oct 17 Javascript
JS数组reduce()方法原理及使用技巧解析
Jul 14 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数组一对一替换实现代码
2012/08/31 PHP
PHP中把stdClass Object转array的几个方法
2014/05/08 PHP
windows7下安装php的imagick和imagemagick扩展教程
2014/07/04 PHP
PHP实现bitmap位图排序与求交集的方法
2016/07/28 PHP
PHP入门教程之面向对象基本概念实例分析
2016/09/11 PHP
用js实现预览待上传的本地图片
2007/03/15 Javascript
js 操作css实现代码
2009/06/11 Javascript
js简单设置与使用cookie的方法
2016/01/22 Javascript
Three.js基础部分学习
2017/01/08 Javascript
bootstarp modal框居中显示的实现代码
2017/02/18 Javascript
p5.js入门教程之鼠标交互的示例
2018/03/16 Javascript
不得不知的ES6小技巧
2018/07/28 Javascript
vue服务端渲染缓存应用详解
2018/09/12 Javascript
详解三种方式解决vue中v-html元素中标签样式
2018/11/22 Javascript
element-ui 时间选择器限制范围的实现(随动)
2019/01/09 Javascript
JS字符串补全方法padStart()和padEnd()
2020/05/27 Javascript
小程序实现左滑删除的效果的实例代码
2020/10/19 Javascript
[59:26]DOTA2上海特级锦标赛D组资格赛#1 EG VS VP第二局
2016/02/28 DOTA
利用Python找出序列中出现最多的元素示例代码
2017/12/08 Python
浅谈dataframe中更改列属性的方法
2018/07/10 Python
django session完成状态保持的方法
2018/11/27 Python
numpy数组之存取文件的实现示例
2019/05/24 Python
python celery分布式任务队列的使用详解
2019/07/08 Python
Django基于客户端下载文件实现方法
2020/04/21 Python
Python新手学习raise用法
2020/06/03 Python
Python单元测试及unittest框架用法实例解析
2020/07/09 Python
python爬虫使用requests发送post请求示例详解
2020/08/05 Python
python3.7中安装paddleocr及paddlepaddle包的多种方法
2020/11/27 Python
葡萄牙鞋子品牌:Fair
2016/12/10 全球购物
酒店服务实习自我鉴定
2013/09/22 职场文书
音乐器材管理制度
2014/01/31 职场文书
2014最新党员批评与自我批评材料
2014/09/24 职场文书
龙潭大峡谷导游词
2015/02/10 职场文书
旅行社计调工作总结
2015/08/12 职场文书
SQL Server携程核心系统无感迁移到MySQL实战
2022/06/01 SQL Server
HttpClient实现文件上传功能
2022/08/14 Java/Android