VisualBasic(脳トレ的アプリ005: リストのシャッフルの方法)
■問題作成部分のコーディングの推敲中(その2)。
問題の選択肢の作成については、前回から少し修正してひとまず終わりにした。
選択肢はできたけど、現在のコードでは正答の位置を1つ目の部分(リストの0番目の要素)に固定しているので、選択肢をシャッフルする方法について考える。
やりたいこととして、10の要素を持つリストのうち0~8番目の要素をシャッフルすること。下の図のような感じ。
0~8番目を選択肢、9番目を正答を入れるところにしている。 0~8番目で重複がないことはこれより前のコードでチェックしている。
やり方はいろいろあると思うけど、例えば、次の手順で入れ替えができる。
1.移し先のリストを作成する。
2.0から8までの乱数を発生させ、その要素を抜き取り、移し先のリストに追加する。これで元のリストは7の要素のリストとなる。
3.0から7までの乱数を発生させ、その要素を抜き取り、移し先のリストに追加する。
4.2と3を繰り返し、元のリストから9番目の要素以外を移す。
5.最後に9番目の要素を移す。
この考え方で作成したコードが下記のもの。
Function shuffle(ByVal candidateList As List(Of Integer))
Dim shuffledList As New List(Of Integer)
Dim index As Integer
For i = 8 To 0 Step -1
index = Int(((i + 1) * Rnd()))
shuffledList.Add(candidateList(index))
candidateList.Remove(candidateList(index))
Next
shuffledList.Add(candidateList(0))
Return shuffledList
End Function
ここで、For i = 8 To 0 Step -1は、8から順に7、6、5と-1ずつ減らすループ。iの数が減っていくので、乱数も0から8の中から(i = 8)、0から7の中から(i = 7)...と減っていく。
アプリを動かすと、問題なくシャッフルされている。
もっと大きな要素を扱う場合、コードの性能面も考えた方がいいかもしれないけど、10要素だけなので性能面は良しにする。これで問題作成部分については完了。
次は、プログレスバーやボタンのデザインあたりについて改善したい。
今のアプリが下のような感じになる。