详谈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 相关文章推荐
Document 对象的常用方法
Jul 31 Javascript
Jquery 获得服务器控件值的方法小结
May 11 Javascript
html a标签-超链接中confirm方法使用介绍
Jan 04 Javascript
jQuery中die()方法用法实例
Jan 19 Javascript
JavaScript事件委托用法分析
Jan 24 Javascript
使用AngularJS编写较为优美的JavaScript代码指南
Jun 19 Javascript
jquery插件jquery.confirm弹出确认消息
Dec 22 Javascript
JavaScript中windows.open()、windows.close()方法详解
Jul 28 Javascript
jquery.Callbacks的实现详解
Nov 30 Javascript
浅谈Redux中间件的实践
Jul 27 Javascript
微信小程序五子棋游戏的悔棋实现方法【附demo源码下载】
Feb 20 Javascript
Angular7中创建组件/自定义指令/管道的方法实例详解
Apr 02 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常用函数总结(数组,字符串,时间,文件操作)
2013/06/27 PHP
ThinkPHP3.1新特性之字段合法性检测详解
2014/06/19 PHP
浅谈php正则表达式中的非贪婪模式匹配的使用
2014/11/25 PHP
ThinkPHP模版引擎之变量输出详解
2014/12/05 PHP
PHP异常处理浅析
2015/05/12 PHP
PHP链表操作简单示例
2016/10/15 PHP
thinkPHP中_initialize方法实例分析
2016/12/05 PHP
PHP使用Session实现上传进度功能详解
2019/08/06 PHP
PHP中关于php.ini参数优化详解
2020/02/28 PHP
PHP实现基本留言板功能原理与步骤详解
2020/03/26 PHP
javascript 多种搜索引擎集成的页面实现代码
2010/01/02 Javascript
javascript中的107个基础知识收集整理 推荐
2010/03/29 Javascript
javascript的switch用法注意事项分析
2015/02/02 Javascript
javascript面向对象程序设计高级特性经典教程(值得收藏)
2016/05/19 Javascript
Javascript实现基本运算器
2017/07/15 Javascript
解决Vue2.0自带浏览器里无法打开的原因(兼容处理)
2017/07/28 Javascript
vue-cli构建项目使用 less的方法
2017/10/04 Javascript
webpack-dev-server自动更新页面方法
2018/02/22 Javascript
关于Angularjs中跨域设置白名单问题
2018/04/17 Javascript
解决layui 复选框等内置控件不显示的问题
2018/08/14 Javascript
JQuery属性操作与循环用法示例
2019/05/15 jQuery
layui 表格操作列按钮动态显示的实现方法
2019/09/06 Javascript
原生JS实现顶部导航栏显示按钮+搜索框功能
2019/12/25 Javascript
vue 解决setTimeOut和setInterval函数无效报错的问题
2020/07/30 Javascript
vue select 获取value和lable操作
2020/08/28 Javascript
500行Python代码打造刷脸考勤系统
2019/06/03 Python
PYTHON EVAL的用法及注意事项解析
2019/09/06 Python
以SQLite和PySqlite为例来学习Python DB API
2020/02/05 Python
Django调用百度AI接口实现人脸注册登录代码实例
2020/04/23 Python
简历上的自我评价怎么写
2014/01/28 职场文书
师范毕业生求职信
2014/07/11 职场文书
田径运动会通讯稿
2014/09/13 职场文书
信访维稳工作汇报
2014/10/27 职场文书
青年文明号申报材料
2014/12/23 职场文书
会计工作岗位职责
2015/02/03 职场文书
关于Python中*args和**kwargs的深入理解
2021/08/07 Python