详谈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 相关文章推荐
比较简单实用的使用正则三种版本的js去空格处理方法
Nov 18 Javascript
JQUERY THICKBOX弹出层插件
Aug 30 Javascript
28个JS验证函数收集
Mar 02 Javascript
jQuery-ui中自动完成实现方法
Jun 10 Javascript
jQuery实现带滚动线条导航效果的方法
Jan 30 Javascript
异步JS框架的作用以及实现方法
Oct 29 Javascript
javascript 将共享属性迁移到原型中去的实现方法
Aug 31 Javascript
JS中微信小程序自定义底部弹出框
Dec 22 Javascript
基于JavaScript表单脚本(详解)
Oct 18 Javascript
微信小程序实现的一键连接wifi功能示例
Apr 24 Javascript
微信小程序实现发送模板消息功能示例【通过openid推送消息给用户】
May 05 Javascript
vue cli安装使用less的教程详解
Jul 12 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
使用sockets:从新闻组中获取文章(二)
2006/10/09 PHP
php 远程图片保存到本地的函数类
2008/12/08 PHP
解析百度搜索结果link?url=参数分析 (全)
2012/10/09 PHP
php的闭包(Closure)匿名函数初探
2016/02/14 PHP
新浪的图片新闻效果
2007/01/13 Javascript
jQuery bind事件使用详解
2011/05/05 Javascript
Javascript图像处理—平滑处理实现原理
2012/12/28 Javascript
JavaScript/Js脚本处理html元素的自定义属性解析(亲测兼容Firefox与IE)
2013/11/25 Javascript
js左右弹性滚动对联广告代码分享
2014/02/19 Javascript
jQuery验证插件 Validate详解
2014/11/20 Javascript
jQuery+CSS实现一个侧滑导航菜单代码
2016/05/09 Javascript
第一次接触神奇的Bootstrap表单
2016/07/27 Javascript
BootStrap Table 设置height表头与内容无法对齐的问题
2016/12/28 Javascript
JS实现简单拖拽效果
2017/06/21 Javascript
解决vue-router在同一个路由下切换,取不到变化的路由参数问题
2018/09/01 Javascript
element-ui tooltip修改背景颜色和箭头颜色的实现
2019/12/16 Javascript
基于vue+element实现全局loading过程详解
2020/07/10 Javascript
[03:14]2014DOTA2西雅图国际邀请赛 EG战队巡礼
2014/07/07 DOTA
Python解析树及树的遍历
2016/02/03 Python
python 弹窗提示警告框MessageBox的实例
2019/06/18 Python
python中使用while循环的实例
2019/08/05 Python
Python re 模块findall() 函数返回值展现方式解析
2019/08/09 Python
python 读取更新中的log 或其它文本方式
2019/12/24 Python
Python3 利用face_recognition实现人脸识别的方法
2020/03/13 Python
解决python中显示图片的plt.imshow plt.show()内存泄漏问题
2020/04/24 Python
使用python-cv2实现视频的分解与合成的示例代码
2020/10/26 Python
交通专业个人自荐信格式
2013/09/23 职场文书
爱情保证书范文
2014/02/01 职场文书
趣味活动策划方案
2014/02/08 职场文书
留守儿童工作方案
2014/06/02 职场文书
初中班主任教育随笔
2015/08/15 职场文书
2016年中学法制宣传日活动总结
2016/04/01 职场文书
MySQL Shell的介绍以及安装
2021/04/24 MySQL
使用pycharm运行flask应用程序的详细教程
2021/06/07 Python
用Python编写简单的gRPC服务的详细过程
2021/07/04 Python
python库Tsmoothie模块数据平滑化异常点抓取
2022/06/10 Python