详谈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 方法实现返回多个数据的代码
Apr 30 Javascript
javascript 表单规则集合对象
Jul 21 Javascript
分享一个用Mootools写的鼠标滑过进度条改变进度值的实现代码
Dec 12 Javascript
javascript时区函数介绍
Sep 14 Javascript
JavaScript 产生不重复的随机数三种实现思路
Dec 13 Javascript
asm.js使用示例代码
Nov 28 Javascript
js关于精确计算和数值格式化以及直接引js文件
Jan 28 Javascript
JS的get和set使用示例
Feb 20 Javascript
详解JavaScript中的事件流和事件处理程序
May 20 Javascript
解决angular2 获取到的数据无法实时更新的问题
Aug 31 Javascript
vue使用better-scroll实现下拉刷新、上拉加载
Nov 23 Javascript
Vue + element 实现多选框组并保存已选id集合的示例代码
Jun 03 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&amp;mysql(一)
2006/10/09 PHP
ThinkPHP 连接Oracle数据库的详细教程[全]
2012/07/16 PHP
php插入排序法实现数组排序实例
2015/02/16 PHP
关于PHP中字符串与多进制转换函数的实例代码
2016/11/03 PHP
PHP面向对象之工作单元(实例讲解)
2017/06/26 PHP
PHP递归实现快速排序的方法示例
2017/12/18 PHP
PHP面向对象类型约束用法分析
2019/06/12 PHP
Javascript的一种模块模式
2010/09/08 Javascript
Area 区域实现post提交数据的js写法
2014/04/22 Javascript
浅谈jQuery中对象遍历.eq().first().last().slice()方法
2014/11/26 Javascript
Angularjs 实现一个幻灯片示例代码
2016/09/08 Javascript
浅谈Node.js:Buffer模块
2016/12/05 Javascript
如何在vue项目中嵌入jsp页面的方法(2种)
2020/02/06 Javascript
Js Snowflake(雪花算法)生成随机ID的实现方法
2020/08/26 Javascript
Vue 按照创建时间和当前时间显示操作(刚刚,几小时前,几天前)
2020/09/10 Javascript
[02:04]2014DOTA2国际邀请赛 DK一个时代的落幕
2014/07/21 DOTA
Python实现的数据结构与算法之基本搜索详解
2015/04/22 Python
python爬取51job中hr的邮箱
2016/05/14 Python
详解Python中的__new__、__init__、__call__三个特殊方法
2016/06/02 Python
Python编程实现数学运算求一元二次方程的实根算法示例
2017/04/02 Python
Python3.6使用tesseract-ocr的正确方法
2018/10/17 Python
解决pycharm每次新建项目都要重新安装一些第三方库的问题
2019/01/17 Python
Python OOP类中的几种函数或方法总结
2019/02/22 Python
CSS3关于z-index不生效问题的解决
2020/02/19 HTML / CSS
HTML5之SVG 2D入门12—SVG DOM及DOM操作介绍
2013/01/30 HTML / CSS
有关HTML5 Video对象的ontimeupdate事件(Chrome上无效)的问题
2013/07/19 HTML / CSS
法律专业实习鉴定
2013/12/22 职场文书
求职面试个人自我评价
2014/02/28 职场文书
个人贷款承诺书
2014/03/28 职场文书
《天安门广场》教学反思
2014/04/23 职场文书
新教师培训方案
2014/06/08 职场文书
拉歌口号大全
2014/06/13 职场文书
借款协议书
2014/09/16 职场文书
介绍信模板
2015/01/31 职场文书
管理失职检讨书范文
2015/05/05 职场文书
HR在给员工开具离职证明时,需要注意哪些问题?
2019/07/03 职场文书