※ 引述《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