详谈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 相关文章推荐
关于JavaScript中var声明变量作用域的推断
Dec 16 Javascript
使用GruntJS链接与压缩多个JavaScript文件过程详解
Aug 02 Javascript
基于jquery实现的图片在各种分辨率下未知的容器内上下左右居中
May 11 Javascript
js点击button按钮跳转到另一个新页面
Oct 10 Javascript
简述Jquery与DOM对象
Jul 10 Javascript
基于jQuery实现鼠标点击导航菜单水波动画效果附源码下载
Jan 06 Javascript
鼠标点击input,显示瞬间的边框颜色,对之修改与隐藏实例
Dec 26 Javascript
微信小程序 地图map实例详解
Jun 07 Javascript
一篇文章让你彻底弄懂JS的事件冒泡和事件捕获
Aug 14 Javascript
探究一道价值25k的蚂蚁金服异步串行面试题
Aug 21 Javascript
如何在vue中使用HTML 5 拖放API
Jan 14 Vue.js
JavaScript如何优化逻辑判断代码详解
Jun 08 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的5个入手程序
2006/11/23 PHP
使用淘宝IP库获取用户ip地理位置
2013/10/27 PHP
使用openssl实现rsa非对称加密算法示例
2014/01/24 PHP
PHP彩蛋信息介绍和阻止泄漏的方法(隐藏功能)
2014/08/06 PHP
php提取身份证号码中的生日日期以及验证是否为成年人的函数
2015/09/29 PHP
8个必备的PHP功能开发
2015/10/02 PHP
php中的登陆login实例代码
2016/06/20 PHP
php让json_encode不自动转义斜杠“/”的方法
2020/04/27 PHP
在网页中屏蔽快捷键
2006/09/06 Javascript
js中通过父级进行查找定位元素
2014/06/15 Javascript
探讨js字符串数组拼接的性能问题
2014/10/11 Javascript
javascript弹出页面回传值的方法
2015/01/28 Javascript
director.js实现前端路由使用实例
2015/02/03 Javascript
JS数组array元素的添加和删除方法代码实例
2015/06/01 Javascript
解析JavaScript模仿块级作用域
2016/12/29 Javascript
Bootstrap按钮组简单实现代码
2017/03/06 Javascript
浅谈Express异步进化史
2017/09/09 Javascript
jQuery 开发之EasyUI 添加数据的实例
2017/09/26 jQuery
浅谈vue路径优化之resolve
2017/10/13 Javascript
Vue核心概念Getter的使用方法
2019/01/18 Javascript
vue 实现强制类型转换 数字类型转为字符串
2019/11/07 Javascript
Python字符串的一些操作方法总结
2019/06/10 Python
Python实现把类当做字典来访问
2019/12/16 Python
用python实现一个简单的验证码
2020/12/09 Python
python中time tzset()函数实例用法
2021/02/18 Python
Zavvi西班牙:电子游戏、极客服装、Blu-ray、Funko Pop等
2019/05/03 全球购物
PHP经典面试题
2016/09/03 面试题
对于没有初始化的变量的初始值可以作怎样的假定
2014/10/12 面试题
SQL数据库笔试题
2016/03/08 面试题
校园十佳歌手策划书
2014/01/22 职场文书
2014年教师节座谈会发言稿
2014/09/10 职场文书
2015年酒店年度工作总结
2015/05/23 职场文书
爱国主义电影观后感
2015/06/18 职场文书
2016入党积极分子党校培训心得体会
2016/01/06 职场文书
乡镇干部学习心得体会
2016/01/23 职场文书
html5调用摄像头截图功能
2022/01/18 Javascript