乱数を作るクラス
ランダムに並べ替える作業というのは滅多にないのだけれど、絶妙に忘れかけた頃に発生するので、
このときにクラスまで作っていた。
んで、改めて見直してみたら、イマイチやなあ、と(笑)。
そんなわけで、作り直してみた。
乱数を作るクラスの改良
前に作ったやつは、あくまでも「1~最大数」をランダムに並べ替えるというだけだった。
そこで、今回は、
- 最小値と最小値を指定できるようにする
- 要素数を指定できるようにする
の2点を追加することにした。
あと、クラス名とか変数名、プロパティ名も大幅に見直した。
コード
さっそく、クラスモジュールのコードを示す。
クラス名は「RandomNumbers」に変えた。
リスト1 クラスモジュール
Option Explicit
'Variables'
Private Item_() As Long
'Properties'
Public Property Get Item(ByVal i As Long) As Long
Item = Item_(i)
End Property
Public Property Get Count() As Long
Count = UBound(Item_) + 1
End Property
'Constructor'
Private Sub Class_Initialize()
ReDim Item_(0)
Item_(0) = 1
End Sub
'Methods'
Public Sub setRandomNumbers(ByVal maxNum As Long, _
ByVal countOfElements As Long, _
Optional ByVal minNum As Long = 1, _
Optional ByVal hasDuplicate As Boolean = False)
'///minNum~maxNumまでの整数をランダムに並べて配列に格納する。'
'///引数maxNum:最大数'
'///引数countOfElements:出来上がりの要素数'
'///引数minNum:最小数'
'///引数hasDuplicate:重複を許可するならTrue'
'///ただし、要素数が数値の種類数(maxNum-minNum+1)より大きいときは、'
'///Falseが渡されてもTrueに変える。'
If countOfElements > maxNum - minNum + 1 Then _
hasDuplicate = True
Dim isUsed() As Boolean
ReDim isUsed(countOfElements - 1)
Dim i As Long
ReDim Item_(countOfElements - 1)
Randomize
Dim tmp As Long
For i = 0 To countOfElements - 1
Do
tmp = Int((maxNum - minNum + 1) * Rnd + minNum)
'///乱数:Int((最大値 - 最小値 + 1) * Rnd + 最小値)'
Loop Until isUsed(tmp - minNum) = False
Item_(i) = tmp
If Not hasDuplicate Then isUsed(tmp - minNum) = True
Next
End Sub
まあ、大枠では変えていないので、説明は省略w
使ってみる
次のコードで実験。
リスト2 標準モジュール
Public Sub testRandomNumbers()
Dim rndNums As New RandomNumbers
With rndNums
Call .setRandomNumbers(10, 10, 1, False) '……(1)'
Dim i As Long
For i = 0 To .Count - 1
Debug.Print .Item(i)
Next
Debug.Print String(5, "=")
Call .setRandomNumbers(20, 20, 11, True) '……(2)'
For i = 0 To .Count - 1
Debug.Print .Item(i)
Next
End With
End Sub
setRandomNumbersメソッドを2回呼び出して、それぞれ取得したランダムな数列をイミディエイトに書き出すだけのコード。
(1)の
Call .setRandomNumbers(10, 10, 1, False)
では、
最大値10(第1引数)、最小値1(第3引数)で、重複を許さず(第4引数)に、ランダムに並べた10個(第2引数)の数字を得ることになる。
同様に、(2)の
Call .setRandomNumbers(20, 20, 11, True)
では、
最大値20(第1引数)、最小値11(第3引数)で、重複を許して(第4引数)、ランダムに並べた20個(第2引数)の数字を得ることになる。
ちなみに、(2)で
Call .setRandomNumbers(20, 20, 11, False)
と、第4引数をFalseにしたとしても、setRandomNumbersメソッド内部でTrueに変えるようにしてある。(リスト1参照)
これは、たとえば「1~5を重複しないようにランダムに10個並べろ!」とか言われても、
そんなの、デキッコナイス!
となるに決まっているからである。
実行結果

この通り。
うまくいっている。
おわりに
これに、あとひと工夫すれば、

こんなふうに、記号をランダムに散らす、といったことに使えます。
学校の先生なんかが、記号式のテスト問題の解答をテキトーに散らすのに使えるんじゃないですかね。
あとは、競輪の出目予想とかw