详谈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 21 Javascript
Jquery replace 字符替换实现代码
Dec 02 Javascript
js function定义函数的几种不错方法
Feb 27 Javascript
JavaScript中字符串分割函数split用法实例
Apr 07 Javascript
jquery插件orbit.js实现图片折叠轮换特效
Apr 14 Javascript
关于JS中的apply,call,bind的深入解析
Apr 05 Javascript
jQuery操作dom实现弹出页面遮罩层(web端和移动端阻止遮罩层的滑动)
Aug 25 Javascript
JavaScript实现图片轮播组件代码示例
Nov 22 Javascript
JavaScript实现移动端页面按手机屏幕分辨率自动缩放的最强代码
Aug 18 Javascript
Vue基本使用之对象提供的属性功能
Apr 30 Javascript
layer.alert回调函数执行关闭弹窗的实例
Sep 11 Javascript
js实现飞机大战小游戏
Aug 26 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 miniBB中文乱码问题解决方法
2008/11/25 PHP
array_multisort实现PHP多维数组排序示例讲解
2011/01/04 PHP
PHP容易忘记的知识点分享
2013/04/30 PHP
提升你网站水平的jQuery插件集合推荐
2011/04/19 Javascript
页面回到顶部的三种实现(锚标记,js)
2012/10/01 Javascript
js获取dom的高度和宽度(可见区域及部分等等)
2013/06/13 Javascript
NodeJS的url截取模块url-extract的使用实例
2013/11/18 NodeJs
js操作模态窗口及父子窗口间相互传值示例
2014/06/09 Javascript
自定义Angular指令与jQuery实现的Bootstrap风格数据双向绑定的单选与多选下拉框
2015/12/12 Javascript
jQuery实现图片文字淡入淡出效果
2015/12/21 Javascript
JQuery的Pager分页器实现代码
2016/05/03 Javascript
JavaScript中实现键值对应的字典与哈希表结构的示例
2016/06/12 Javascript
Javascript基础回顾之(三) js面向对象
2017/01/31 Javascript
vue上传图片组件编写代码
2017/07/26 Javascript
js实现简单模态框实例
2018/11/16 Javascript
mockjs+vue页面直接展示数据的方法
2018/12/19 Javascript
使用Vue CLI创建typescript项目的方法
2019/08/09 Javascript
Vue中import from的来源及省略后缀与加载文件夹问题
2020/02/09 Javascript
vue项目使用高德地图的定位及关键字搜索功能的实例代码(踩坑经验)
2020/03/07 Javascript
Python使用Supervisor来管理进程的方法
2015/05/28 Python
解决Django migrate No changes detected 不能创建表的问题
2018/05/27 Python
python和pygame实现简单俄罗斯方块游戏
2021/02/19 Python
Python 中导入csv数据的三种方法
2018/11/01 Python
python合并已经存在的sheet数据到新sheet的方法
2018/12/11 Python
使用matlab或python将txt文件转为excel表格
2019/11/01 Python
Python中BeautifuSoup库的用法使用详解
2019/11/15 Python
基于HTML5 Canvas 实现商场监控实例详解
2017/11/20 HTML / CSS
Algenist奥杰尼官网:微藻抗衰老护肤品牌
2017/07/15 全球购物
大学生毕业自我鉴定
2013/11/06 职场文书
会计找工作求职信范文
2013/12/09 职场文书
简历上的自我评价怎么写
2014/01/28 职场文书
我们的节日清明节活动总结
2014/04/30 职场文书
红头文件任命书范本
2014/06/05 职场文书
社区四风存在问题及整改措施
2014/10/26 职场文书
2014年医院个人工作总结
2014/12/09 职场文书
一年之计:2019年下半年的计划
2019/05/07 职场文书