详谈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里的条件判断
Feb 27 Javascript
JavaScript delete 属性的使用
Oct 08 Javascript
Javascript中的call()方法介绍
Mar 15 Javascript
js获取表格的行数和列数的方法
Oct 23 Javascript
基于JavaScript实现根据手机定位获取当前具体位置(X省X市X县X街道X号)
Dec 29 Javascript
Webwork 实现文件上传下载代码详解
Feb 02 Javascript
JS组件Bootstrap ContextMenu右键菜单使用方法
Apr 17 Javascript
JavaScript编写棋盘覆盖代码详解
Aug 28 Javascript
详解Vue路由History mode模式中页面无法渲染的原因及解决
Sep 28 Javascript
使用vue-router beforEach实现判断用户登录跳转路由筛选功能
Jun 25 Javascript
vue-calendar-component 封装多日期选择组件的实例代码
Dec 04 Vue.js
vue 页面跳转的实现方式
Jan 12 Vue.js
全面了解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
关于手调机和数调机的选择
2021/03/02 无线电
php下通过POST还是GET来传值
2008/06/05 PHP
一些 PHP 管理系统程序中的后门
2009/08/05 PHP
php流量统计功能的实现代码
2012/09/29 PHP
joomla实现注册用户添加新字段的方法
2016/05/05 PHP
PHP chunk_split()函数讲解
2019/02/12 PHP
在JavaScript中遭遇级联表达式陷阱
2007/03/08 Javascript
8款非常棒的响应式jQuery 幻灯片插件推荐
2012/02/02 Javascript
jquery ajax 调用失败的原因示例介绍
2013/09/27 Javascript
Javascript中replace()小结
2015/09/30 Javascript
NodeJS和BootStrap分页效果的实现代码
2016/11/07 NodeJs
详解MVC如何使用开源分页插件(shenniu.pager.js)
2016/12/16 Javascript
vue实现树形菜单效果
2018/03/19 Javascript
angularJs自定义过滤器实现手机号信息隐藏的方法
2018/10/08 Javascript
Koa 使用小技巧(小结)
2018/10/22 Javascript
angular inputNumber指令输入框只能输入数字的实现
2019/12/03 Javascript
element-ui如何防止重复提交的方法步骤
2019/12/09 Javascript
JavaScript 变量,数据类型基础实例详解【变量、字符串、数组、对象等】
2020/01/04 Javascript
JS script脚本中async和defer区别详解
2020/06/24 Javascript
关于uniApp editor微信滑动问题
2021/01/15 Javascript
[01:15:44]首部DOTA2纪录片今日23时全网上映
2014/03/19 DOTA
python pdb调试方法分享
2014/01/21 Python
Python中类的定义、继承及使用对象实例详解
2015/04/30 Python
python 实现对文件夹中的图像连续重命名方法
2018/10/25 Python
python3使用matplotlib绘制散点图
2019/03/19 Python
浅谈python的输入输出,注释,基本数据类型
2019/04/02 Python
python 监控服务器是否有人远程登录(详细思路+代码)
2020/12/18 Python
世界上最好的帽子:Tilley
2016/11/27 全球购物
Farfetch台湾官网:奢侈品牌时尚购物平台
2019/06/17 全球购物
什么是.net的Remoting技术
2016/07/08 面试题
施工安全标语
2014/06/07 职场文书
学校节能宣传周活动总结
2014/07/09 职场文书
建筑专业毕业生求职信
2014/09/30 职场文书
陕西导游词
2015/02/04 职场文书
组织委员竞选稿
2015/11/21 职场文书
用人单位的规章制度,怎样制定才是有效的?
2019/07/09 职场文书