设为首页收藏本站喵玉殿官方微博

 找回密码
 少女注册中
搜索
查看: 9070|回复: 12

[编程算法] 从STG录像回放到随机数生成

  [复制链接]
发表于 2015-1-16 11:05:44 | 显示全部楼层 |阅读模式
这是10个小时之前在群里讨论的(这就是为啥技术区冷清
感觉有存档的价值,遂开帖讨论。


目前从群里面得到的看法是

一个录像文件,应当存储弹幕的生成参数和随机数种子
以及玩家的按键操作

回放的时候按照弹幕生成参数和随机数种子来生成弹幕
用记录的玩家按键操作来重现对自机的操作

于是,这里就涉及到了,随机数的生成算法
以及弹幕的生成算法

此帖就是讨论这些的。
发表于 2015-1-16 11:07:55 | 显示全部楼层
本帖最后由 漆黑之翼 于 2015-1-16 11:54 编辑

幻想人形演武有个64K的随机数表
实时算的话感觉上用SFMT算法的比较多


回复

使用道具 举报

发表于 2015-1-16 11:08:13 | 显示全部楼层
luastg的伪代码我试着译过来
回复

使用道具 举报

 楼主| 发表于 2015-1-16 11:32:15 | 显示全部楼层
漆黑之翼 发表于 2015-1-16 11:07
幻想人形演武有个64K的随机数表感觉上用SFMT算法的比较多

其实随机数表是个很好的想法

因为Rnd这函数是伪随机,真正在统计上用的几乎是随机数表,或者是其他方案。

而且随机数表是在一个已知范围内的随机,游戏里面使用这个是很便利的。
可以重现游戏过程。

而真随机的话,我倾向监听电源的噪音,嗯,输入220V交流里面的杂波
或者是声卡里的噪音波形。
这应该就是采用了现实世界这个最大的随机数表了吧
回复

使用道具 举报

发表于 2015-1-16 14:13:02 | 显示全部楼层
本帖最后由 lrdcq 于 2015-1-16 14:15 编辑

路过,帖一下在webSTG中用到的伪随机数算法,因为想尽量节约运算量所以写得超级简单(其实函数分布呈明显波状,不靠谱,但是写游戏只要不压在取数周期上就无明显规律,所以能用)

  1. //randomseed为一个八位数
  2. random=function(){
  3.         var tp=randomseed+count*178279;
  4.         tp=(tp/1000)*(tp%1000);
  5.         tp=tp%100000/100000;
  6.         count++;
  7.         //count loop
  8.         return tp;
  9. }

复制代码

回复

使用道具 举报

发表于 2015-1-16 14:28:42 | 显示全部楼层
我觉得的话,作为决定随机弹幕的种子,可以采用(字母+数字)*n的一个种子【比如:KBH76YUGD】,然后根据每一位设定一个意义,比如每一个随机弹幕的数量、出现方式之类的,这样每回开局的时候只需要运算一次就能获得整个这次游戏时全部的随机弹幕的设定
回复

使用道具 举报

 楼主| 发表于 2015-1-16 15:21:16 | 显示全部楼层
玛艾露贝莉_赫恩 发表于 2015-1-16 14:28
我觉得的话,作为决定随机弹幕的种子,可以采用(字母+数字)*n的一个种子【比如:KBH76YUGD】,然后根据每 ...

从一个已知的随机字符串来生成很大的随机数表么?
我突然想到了MD5。。。
任给一字符串,计算其MD5(可以吧
把得到的MD5值接到给定字符串后面,作为新的字符串进行以上计算
原给定字符串的长度来控制计算次数。。。

不知道效果如何(
回复

使用道具 举报

发表于 2015-1-16 15:56:26 | 显示全部楼层
drzzm32 发表于 2015-1-16 15:21
从一个已知的随机字符串来生成很大的随机数表么?
我突然想到了MD5。。。
任给一字符串,计算其MD5(可 ...

感觉没有很大必要。。。字母+数字一共36个,也就是36的n次方种形式,感觉基本上已经够了。
回复

使用道具 举报

发表于 2015-1-16 20:13:02 | 显示全部楼层
嗯.....???
不明白....
既然是錄像(.rpy?),對負責「錄影」的程式來說,所有的彈幕﹑自機移動都已經是常數了吧?
要討論隨機生成,是不是,不應該對「錄像」這方面下手?

還是,是我對「錄像」的誤解!?
回复

使用道具 举报

发表于 2015-1-16 21:27:50 | 显示全部楼层
本帖最后由 ofz 于 2015-1-16 21:30 编辑

hihihi,晚上好。

据我所知随机数生成器和初始化种子在多数语言里都是标准的配置(如 c 里面的 srand,java 里面的 Random(seed),与其自己费脑筋去实现一个 RNG,如果没有特殊需求的话还是用这些经过精心编写并广泛验证的东西比较好呢。但如果用的是 javascript 这种功能上残缺的(只有随机数生成器而不能设置种子),或者是在 shader 这样底层的环境下,自己写随机数生成器似乎就是必须的了

嘛,伪随机数的算法很多的,我也没有特地去了解过。参考这边的帖子,随便贴几个方案好了(以下都是 javascript
http://stackoverflow.com/questions/521295/javascript-random-seeds

1. 最简单偷懒的办法:直接利用正弦函数的分布
  1. var seed = 1;
  2. function random() {
  3.     var x = Math.sin(seed++) * 10000;
  4.     return x - Math.floor(x);
  5. }
复制代码
应该不要过多解释吧(在 shader 里面会看到类似的代码)。这个方法足够简单,速度也还可以。但缺点同样明显:因为正弦函数本身不均匀的特性,会有更高的概率出现在 0 或者 1 附近(看 http://jsfiddle.net/bhrLT/17/


2. 稍微复杂但可靠一点的
  1. var m_w = 123456789; // seed 1
  2. var m_z = 987654321; // seed 2
  3. var mask = 0xffffffff;

  4. // Takes any integer
  5. function seed(i) {
  6.     m_w = i;
  7. }

  8. // Returns number between 0 (inclusive) and 1.0 (exclusive),
  9. // just like Math.random().
  10. function random()
  11. {
  12.     m_z = (36969 * (m_z & 65535) + (m_z >> 16)) & mask;
  13.     m_w = (18000 * (m_w & 65535) + (m_w >> 16)) & mask;
  14.     var result = ((m_z << 16) + m_w) & mask;
  15.     result /= 4294967296;
  16.     return result + 0.5;
  17. }
复制代码
算法的细节我不懂,看 http://en.wikipedia.org/wiki/Multiply-with-carry

3. 再掺和进去一些 Magic Number
  1. // the initial seed
  2. Math.seed = 6;

  3. // in order to work 'Math.seed' must NOT be undefined,
  4. // so in any case, you HAVE to provide a Math.seed
  5. Math.seededRandom = function(max, min) {
  6.     max = max || 1;
  7.     min = min || 0;

  8.     Math.seed = (Math.seed * 9301 + 49297) % 233280;
  9.     var rnd = Math.seed / 233280;

  10.     return min + rnd * (max - min);
  11. }
复制代码
说到算法里面的 Magic Number(就是那些不知道怎么来的奇怪数字),印象最深的还是卡马克大神的浮点数开方算法呢(那是我第一次在代码注释里面看见 WTF...
咦,你说你是做游戏的,但是你不认识卡马克大神?赶紧去看 doom启示录 吧,他一定会成为你的偶像的!

4. 最安全稳妥的办法:按照某种成熟的算法自己实现一个 PRNG
比如这边就是一个 javascript 上面用 RC4 算法写的 PRNG https://github.com/davidbau/seedrandom
技术细节参考 http://davidbau.com/archives/201 ... d_quintillions.html

稍微提一下,可能有人觉得奇怪,随机数只是用来增加游戏的不可预测性的和乐趣的,还跟安全性有关吗?抛开利用随机数来生成密钥这样的使用方式,拿一个俄罗斯方块游戏来说,随机数将决定下一次会出现什么类型的方块。如果你的随机数算法不够健壮,那么玩家可以通过之前出现的方块的顺序推测出你使用的算法和种子,由于伪随机数的本质,游戏接下来会出现的什么方块他就都可以预测出来了!最差的情况是某人可以根据这个写一个自动玩游戏的程序。唔...就这个例子来说,似乎危害不够大呢...也许应该拿纸牌之类的游戏举例子比较好,但是我不会玩牌(摊手

最后贴一句来自我们的 “计算机之父” 冯-诺依曼 的意(bi)味(ge)深(hen)长(gao)的话
"Anyone who uses arithmetic methods to produce random numbers is in a state of sin."
  -- John von Neumann


回复

使用道具 举报

您需要登录后才可以回帖 登录 | 少女注册中

本版积分规则

合作与事务联系|无图版|手机版|小黑屋|喵玉殿

GMT+8, 2025-10-31 11:08

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

快速回复 返回顶部 返回列表