許敏 雷麗娟
摘 要 本文對(duì)隨機(jī)數(shù)生成函數(shù)在Flash的應(yīng)用中的弱點(diǎn)進(jìn)行分析,并提出新的方案,并加以代碼實(shí)現(xiàn)。
關(guān)鍵詞 偽隨機(jī)數(shù) 隨機(jī)數(shù)生成函數(shù)
中圖分類號(hào):TP311.12 文獻(xiàn)標(biāo)識(shí)碼:A
隨機(jī)數(shù)原本是為試驗(yàn)中得到隨機(jī)結(jié)果而產(chǎn)生的,在統(tǒng)計(jì)學(xué)中經(jīng)常使用隨機(jī)數(shù)來(lái)抽取試驗(yàn)樣本或者進(jìn)行蒙特卡羅模擬法計(jì)算等。在現(xiàn)實(shí)中隨機(jī)數(shù)常發(fā)生在如擲骰子、抽簽、彩票等物理現(xiàn)象中,我們稱這樣的隨機(jī)數(shù)叫做物理性隨機(jī)數(shù)。真正意義上的物理性隨機(jī)數(shù)是在實(shí)驗(yàn)過(guò)程中表現(xiàn)的分布概率,是不可預(yù)測(cè)的、不可見(jiàn)的;而在計(jì)算機(jī)中的隨機(jī)數(shù)是按照隨機(jī)數(shù)的算法模擬產(chǎn)生的,其結(jié)果是確定的并且也是可見(jiàn)的,故在計(jì)算機(jī)上利用隨機(jī)函數(shù)產(chǎn)生的隨機(jī)數(shù),稱為偽隨機(jī)數(shù)。
偽隨機(jī)數(shù)在計(jì)算機(jī)中使用比較普遍,尤其在密碼學(xué)上,它是利用計(jì)算機(jī)高級(jí)語(yǔ)言里的隨機(jī)數(shù)函數(shù)與密碼學(xué)中的原始理論算法相結(jié)合來(lái)生成不可逆的新密碼。在我們熟知的計(jì)算機(jī)高級(jí)語(yǔ)言里,如C語(yǔ)言、Java等語(yǔ)言都具備對(duì)應(yīng)的隨機(jī)數(shù)生成函數(shù)。這些隨機(jī)數(shù)生成函數(shù)的使用起來(lái)相對(duì)簡(jiǎn)單,就C語(yǔ)言為例:你只需在程序中調(diào)用rand()函數(shù)便可以生成0-RAND_MAX之間的隨機(jī)數(shù),要想產(chǎn)生整數(shù),只需調(diào)用取整函數(shù)int( )使其數(shù)據(jù)規(guī)整即可。
在計(jì)算機(jī)中實(shí)現(xiàn)隨機(jī)數(shù)相當(dāng)簡(jiǎn)單,這種簡(jiǎn)單使得我們?cè)贔lash的應(yīng)用中缺少靈活性或許說(shuō)并不能滿足一些特殊場(chǎng)合的需求,因此,我們需在原始隨機(jī)數(shù)函數(shù)Math.random( )基礎(chǔ)上增加一些數(shù)學(xué)的技巧來(lái)實(shí)現(xiàn)新的隨機(jī)數(shù)函數(shù),以方便ActionScript3代碼在不同環(huán)境中得到更為廣泛的應(yīng)用。
在Flash游戲編程中,經(jīng)常會(huì)利用隨機(jī)函數(shù)來(lái)實(shí)現(xiàn)游戲中的隨機(jī)地圖和隨機(jī)游戲內(nèi)容等,因而對(duì)于游戲而言,強(qiáng)調(diào)隨機(jī)函數(shù)的重要性一點(diǎn)也不為過(guò)。舉個(gè)找茬游戲例子,幾乎每局比賽的內(nèi)容讓玩家無(wú)法預(yù)先得知,并且每局的關(guān)鍵茬點(diǎn)也不同,這些都是對(duì)于隨機(jī)元素的合理運(yùn)用。自然,游戲這樣做的目的在于保持有趣、不確定性以及平等,讓玩家永遠(yuǎn)不知道下局會(huì)發(fā)生什么。游戲的隨機(jī)性在大多數(shù)游戲中早已被廣泛使用,并且除了游戲之外,也有其他地方在使用隨機(jī)數(shù),如圖形效果等。隨機(jī)數(shù)存在于各種現(xiàn)實(shí)生活的形狀和大小中,各種不同的隨機(jī)性就成為我們所要研究的方向。
以下是我們?nèi)绾谓⒑瘮?shù)使之完成對(duì)應(yīng)的變化。
1 整數(shù)
讓我們來(lái)看看從它的數(shù)學(xué)公式:Math.floor(Math.random() * (1 + High - Low)) + Low這是用于生成隨機(jī)整數(shù),或許你還記得。但只要在擴(kuò)展一點(diǎn),我們便可以看到另一方式:Math.floor(Math.random() * Range) + Low使用Range來(lái)取代(1 + High - Low)范圍。
2 非整數(shù)
在現(xiàn)實(shí)當(dāng)中,整數(shù)的需求并不是常見(jiàn)的,而非整數(shù)卻不然,要想獲得非整數(shù),其實(shí)在程序?qū)崿F(xiàn)很簡(jiǎn)單,只需去掉Math.floor(),則原先的公式變成:Math.random() * Range + Low這時(shí)隨機(jī)產(chǎn)生的非整數(shù)便常用于隨機(jī)旋轉(zhuǎn)和隨機(jī)大小的案例中。讓我們來(lái)看個(gè)例子,要獲得0到3以內(nèi)的非整數(shù),它的公式很顯然就是Math.random() * 3,但需要記住它的取值范圍是包括0,但不包括3。
3 間距公式
說(shuō)到間距,一般是針對(duì)整數(shù)而言,自然在公式前又該帶回Math.floor()。這一次,我們來(lái)加強(qiáng)難度,生成任何隨機(jī)從0到100之間的奇數(shù):Math.floor(Math.random * 50) * 2 + 1,通過(guò)Math.floor(Math.random * 50)產(chǎn)生0到50的隨機(jī)整數(shù),再乘以2,得到偶數(shù),再加1,便是奇數(shù)了。如果將其總結(jié),公式該為:Math.floor(Math.random * Range) * Spacing + Low。
4 四舍五入
如果生成一個(gè)0到100隨機(jī)的非整數(shù),讓它們的間距為0.5時(shí),四舍五入就起到關(guān)鍵性的作用。但如果不使用Math.round(),則需要變通地解決,Math.floor(Math.random * 200) / 2,先將范圍擴(kuò)大至200,然后通過(guò)除以2來(lái)還原范圍,得到小數(shù)0.5的間距。
5 左右數(shù)
讓我們?cè)倏戳硗庖环N間距,例如-1和1,它們分別在0的左邊和右邊,間距為2,我們稱-1和1為左右數(shù)。其公式為:Math.floor(Math.random() * 2) * 2 – 1。
6 素?cái)?shù)
最后,我們來(lái)討論下隨機(jī)素?cái)?shù)的實(shí)現(xiàn),素?cái)?shù)并非像偶數(shù)或奇數(shù)那樣間隔均勻,單純通過(guò)數(shù)學(xué)公式很難完成,這時(shí)我們需要?jiǎng)?chuàng)建一個(gè)素?cái)?shù)數(shù)組:var primes:Array = [2, 3, 5, 7, 11, 13, 17, 19, 23, 29],利用數(shù)組的下標(biāo)的自然數(shù)規(guī)律來(lái)實(shí)現(xiàn)取出隨機(jī)素?cái)?shù)的工作,其公式:primes[Math.floor(Math.random() * primes.length)]。由于范圍是數(shù)組的長(zhǎng)度并且AS3數(shù)組的下標(biāo)由0開(kāi)始,所以我們可以取到在素?cái)?shù)數(shù)組中任意素?cái)?shù)。
7總結(jié)
最后需要注意的是,你可以使用int()函數(shù)來(lái)取代Math.floor(),它產(chǎn)生的結(jié)果完全一樣,但如果Math.random()乘以一個(gè)負(fù)數(shù),在測(cè)試時(shí),Math.floor()比int()運(yùn)算速度快15倍左右。這是罕見(jiàn)的,所以如果要考慮運(yùn)行速度的問(wèn)題,則改變程序本身,使用快速代碼就顯得格外重要了。
參考文獻(xiàn)
[1] 隨機(jī)數(shù)的產(chǎn)生.豆丁網(wǎng):http://www.docin.com/p-571025674.html.2013.
[2] Gary Rosenzweig,ActionScript3.0游戲編程.人民郵電出版社,2012.