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