※ 引述《ZMTL (夜风/潇湘 VR板已经开板!)》之铭言:
: 嗯,虽然我是APP工程师,但大学不是唸本科毕业后才半路出家的,
: 对这点真乱数、假乱数以前耳闻过讨论却没什么概念,刚好跟游戏有关想到就问一下。
首先要有一个观念
目前没有所谓的真乱数
程式里用随机函式(后面用rand()代称)产生的乱数全都是假乱数
rand()有很多种,但不论哪种都是人写出来的
有自己写过的就会知道流程大概都如下
1.给一个seed > 2.算法做运算 > 3.得一个值 > 跳回2得3 loop
所以seed固定,后面产出的值也都会固定,连续取3的值建表就是所谓的随机表,这是正常的
不同的seed会有不同的表,更改seed可以视作"洗牌"
通常是用系统时间或tick做seed
: 首先举例使用假乱数表的游戏,以下有稍微简化过程:
: 1.魔物猎人:世界
: “炼金”功能是拿X个珠子生成三颗新的珠子,存盘读档结果不会变。
: 后来被发现有一张表,像这样
: A B C
: D E A
: A A C
: 如果你是这次炼金出来是ABC,下次炼金出来是DEA,下下次炼金出来是AAC
: 那你可以先不练金,去打两场任务出来就会变成AAC。
: (实际上打任务推进的序列是1、1、2轮回,按下不提)
: 细节:https://forum.gamer.com.tw/C.php?bsn=5786&snA=137873
: 2.神奇宝贝
: “生蛋”功能是公母方配种生出子代,特定变因固定下存盘读档结果遗传项不会变。
: 父母都有 A B C D E F六项能力,分别遗传父母的哪几项在变因固定下是不会变的,
: 但变因不包括父母是谁,所以可以确认会遗传哪一项后再更换父母取得特定遗传的子代,
: 进阶一点用法就是找到第XXXX次会生出色违后,
: 用低步数就生出来的神奇宝贝跳过中间不需要的部分,
: 在指定的位子再更会为要的神奇宝贝快速取得色违。
: 细节:https://home.gamer.com.tw/creationDetail.php?sn=3427102
: 那问题来了,
: 如果说是避免玩家用SL大法来硬洗出想要的成果,却反而造成未来成果会被预测,
: 难道单机游戏做不到真正在产出结果当下进行乱数,或者乱数表假乱数表有什么优点吗?
: 其实对这问题有疑问好久了w
: 很多人说MHW洗珠子无聊会消耗热情,但经过PM的洗礼我真的觉得还好XD
: 顺带一提,很多线上游戏/网络游戏的都市传说有时候我不会完全不信的原因也是这个。
老实说我觉得就是写程式的人问题
大多数都是直接call平台内建的rand()来用
而没有去了解该rand()的内部算法
所以容易被试出来更改seed的时间点(甚或进游戏后就没改过)
造成大量试错后会被发现规律性
要避免其实也很简单
就是在call rand()前更改seed就好了
但其实单机游戏被试出来也不是啥大问题就是
线上游戏或手游通常会比较注意这块
所以比较不会发生上面的问题
不过还是会有例外...
因为平台内建的rand()...改seed后产出的第1个值
不见得没有规律性喔~揪咪
有发现这点的人就会去找其他(或自写)rand()来用
Unity有发过这方面的文
有兴趣可以看看
https://blogs.unity3d.com/2015/01/07/a-primer-on-repeatable-random-numbers/
里面也有比较各rand()的优劣
以前自己实际跑的结果
https://i.imgur.com/JN9518o.png
seed固定
https://i.imgur.com/6kwkDsg.png
seed变动
看看那个精美的System.Random