圖 1. 附一張圖文不符的圖

相信大家稍微看過AMXX函數的也會知道,
AMXX有三種函數可以生成隨機數字:
複製程式
native random(max) //可以抽取 0 至 (max - 1) 範圍內的整數
native Float:random_float(Float:a, Float:b); // 可以抽取 a 至 b 範圍內的小數
native random_num(a, b) // 可以抽取 a 至 b 範圍內的正負整數
乍看一下沒啥分別也是產生隨機數字
但其實兩者在運作上不相同:
random_float 、random_num是直接向引擎獲取隨機數
而random()則是使用AmxModx內置生成隨機數
你問我知道這些有啥用?
呃,沒錯的確聽起來沒啥用
不過既然兩者實現方式不同,那執行速度上可能就有差別喔...?

以下是使用
分析器分別執行10000次測試出來:
random(20) time :
0.000093187176
0.000094055468
0.000090957132
random_num(0,20) time :
0.000162057616
0.000242643696
0.000160149244
random_float(0.0,20.0) time:
0.000151322136
0.000199439368
0.000146716752
從結果可見,同樣是抽取0至20範圍內的數字, random() 整體在速度上會比 random_num() 快

,
如果你喜歡運行速度快
(即使你完全體感不出來
),你可能會想選擇用random()

-----------------------------------------
但random()只能抽「 0 至 max-1」的條件下,會有許多情況下也不適用,

所以在這分享一些從網上找到的公式,令 random() 整體實用性提升

:
random_chance複製程式
#define random_chance(%0) (%0 > random(100))
random_chance(25) 執行10000次的速度 :
0.000096780092
0.000096626784
0.000093949460
檢查機率百分比,若抽中了會回傳1,反之則回傳0,
由於不需運算所以效能跟本身 random() 幾乎沒差別
random_fastgetnum複製程式
#define random_fastgetnum(%0,%1) (random(%1 - %0 + 1) + %0)
random_fastgetnum(0,20) 執行10000次的速度 :
0.000091732720
0.000110157688
0.000091345996
可以抽取 %0 至%1 範圍內的數字,但只限正整數
random_sighnum複製程式
#define random_sighnum(%0) (random(2 * %0 + 1) - %0)
random_sighnum(20) 執行10000次的速度 :
0.000106322552
0.000105548456
0.000127152180
可以抽取 0 至 %0 範圍內的數字,並會隨機將數字轉為正數或負數
random_getnum複製程式
#define random_getnum(%0,%1) (%0 + (random(RAND_MAX) % (%1 - %0 + 1)))
random_getnum(-20,20) 執行10000次的速度 :
0.000149931260
0.000141040200
0.000122050440
相比random_fastgetnum,這個可以抽取 %0 至%1 範圍內的正負整數,
所以用途很廣泛,但因要進行% 運算所以執行速度較慢 (接近random_num所需效能)
如果你是以效能優先,建議跟 random_fastgetnum、random_sighnum 靈活配合運用
random_slowgetnum複製程式
#define random_slowgetnum(%0,%1) (floatround(((float(random(RAND_MAX)) / float(RAND_MAX) * (%1 - %0 + 1)) + %0), floatround_floor))
random_slowgetnum(-20,20) 執行10000次的速度 :
0.000478622104
0.000423543492
0.000444157876
這個可以抽取 %0 至%1 範圍內的正負整數,
但由於需進行不少浮點數運算,所以執行速度是所有公式之中最慢,
唯一好處是由於將要抽的數字拆分成0.0至1.0小數,然後再運算得出範圍內的整數,
所以"可能"體感上抽取數字會更均匀一點,
就好像 random(2) 和 (random(50) > 25) 體感上後者數字更隨機,即使機率一樣,
除非有特別需求,否則整體上建議使用random_getnum就好
randomf複製程式
#define randomf(%0) (Float:((float(random(RAND_MAX)) / float(RAND_MAX)) * Float:%0))
randomf(20.0) 執行10000次的速度 :
0.000258840008
0.000240448800
0.000254451900
可以抽取 0至 %0 範圍內的小數,但因為要進行浮點數除法,
所以會被原生random_float慢,
要不要使用就自己衡量,這裡只提供给大家參考用
random_getfloat複製程式
#define random_getfloat(%0,%1) (Float:(float(random(RAND_MAX)) / float(RAND_MAX) * (Float:%1 - Float:%0)) + Float:%0)
random_getfloat(0.0,20.0) 執行10000次的速度 :
0.000356375972
0.000366431980
0.000398652484
可以抽取 %0至%1 範圍內的小數
但缺點同上,同樣只提供给大家參考用
--------------------------------------------------------
如果你看完對random()有興趣想試試看,

你可以下載附件random.inc,
在自己源碼加上#include <random>便可使用上面的define了~
