• ベストアンサー
※ ChatGPTを利用し、要約された質問です(原文:4択問題のプログラムでランダムに出題する処理で困っています)

質問:4択問題のプログラムでランダムに出題する処理で困っています

このQ&Aのポイント
  • 質問者は、4択の問題を解答し、最後に正解数を表示するプログラムを作成しているが、ランダムに出題しつつ同じ問題が出題されないようにする方法について困っている。
  • データテーブルに問題と選択肢、解答、正解を格納し、最終的な目標は300問の問題からランダムに100問出題して結果を表示するプログラムを作成したいということ。
  • 現在は10問で動くプログラムを作成しており、NextQuestion_Click関数を使用して次の問題に進む処理を実装している。

質問者が選んだベストアンサー

  • ベストアンサー
回答No.1

まず「次の問題に進む時、問題の参照にiを使わず、乱数で求めた0~299の値を使う」と言うように変更しましょう。 そして「初期化時や無回答で次の問題に進んだ時の、解答(SelectAnswr)にセットする値を工夫する事で、未出題か出題済みか判定する」と言う処理をして、問題の重複を避けましょう。 ヒントだけ。 ヒントは以下の通り。 ヒント1. 「解答(SelectAnswr)」に入る値を「回答された"ア"~"エ"」「無回答でスキップした"S"」「まだ出題してない""」の3種類にする。 (無回答でのスキップが出来ない、つまり、選択肢のどれかを選ばないと「次の問題」ボタンが押せない、と言う処理の場合「無回答でスキップした"S"」は不要) ヒント2. 最初の初期化時に「300件全部、解答(SelectAnswr)の値を""にして、すべて未出題」にする。 ヒント3. 出題時に問題を参照する時「DataSet1.DataTable1(i).ほげほげ」のように「(i)」で参照するのをやめる。 代わりに、乱数で「解答(SelectAnswr)の値が、まだ出題してない""になっている問題」を探す。 つまり「乱数で0~299の値を作り、解答(SelectAnswr)の値が""なら、その乱数が出題番号になり、解答(SelectAnswr)の値が""じゃないなら乱数の作り直し」をすればよい。 ヒント4. 変数の「i」は「最初は-1」「1題出題するごとに1を足す」「100題目が終わったら終了」の目的以外には使わない。 つまり「DataSet1.DataTable1(i).ほげほげ」っていう書き方を全部無くす。 ヒント5. 選択肢を選ばずに「次の問題」を押してしまった場合「解答(SelectAnswr)」の値が「まだ出題してない""」のまま次に進んでしまっては困るので、次に進む前に「解答(SelectAnswr)の値を"S"にする」と言う処理をして「出題済み」にする。 (無回答でのスキップが出来ない、つまり、選択肢のどれかを選ばないと「次の問題」ボタンが押せない、と言う処理の場合、この処理は不要) ヒントは以上。 なお、この方法は「300問中100問」などのように、最後の100問目に近い時も未出題の問題が多い場合は問題ありませんが「すべての問題を出題する」などの場合、最後の問題に近くなると未出題の問題が減り「残りの問題が乱数にヒットせず、次の問題に進む際に時間がかかる」と言う欠点があるので注意して下さい。今回のように「300問中100問」であれば問題はありません。

ryousuke33
質問者

お礼

とても助かりました。ありがとうございます。

その他の回答 (5)

  • redfox63
  • ベストアンサー率71% (1325/1856)
回答No.6

BindingSourceは使い勝手が悪いかも ・・・ BindingSourceがユーザーに見えてしまっていると問題の移動自体が自由に行えてしまいます これは抑制したほうがいいように思います CurrnecyManagerを導入してこれで出題位置を特定したほうがいいように思います 300問中100問出題などとするのであれば DataTableに問題,回答選択子,正解などのほかに 出題順序用のフィールドを設けて この出題順序フィールドに乱数を代入しソートした結果を使って見てはいかがでしょう

  • rivoisu
  • ベストアンサー率36% (97/264)
回答No.5

訂正 問題文=worksheets("問題シート").cells(問題番号,2) worksheets("問題シート").cells(問題番号,1)=1 あら、余計だったかな

  • rivoisu
  • ベストアンサー率36% (97/264)
回答No.4

問題は「300問の中から重複無く問題を選ぶ」ということだと解釈します。 300問の問題はどこかのシートに書かれているはずですね。 一部しかコードは書きませんが、 初期化でその空いている列をクリアーする。A列とする その後問題を選ぶたびに過去に出したかチェックする '問題選択 問題番号=選択番号() 問題文=worksheets("問題シート").cells(選択番号,2) worksheets("問題シート").cells(選択番号,1)=1 Function 選択番号() As Integer   Dim ix1 As Integer   Randomize     ix1 = Int((Rnd * 10) + 1)   While worksheets("問題シート").Cells(ix1, 1) = 1     ix1 = Int((Rnd * 10) + 1)   Wend   選択番号=ix1 End Function

  • tochansa
  • ベストアンサー率76% (23/30)
回答No.3

あああ! chie65535さんごめんなさい・・・m(__)m せっかくのヒントなのに邪魔してしまいました。

  • tochansa
  • ベストアンサー率76% (23/30)
回答No.2

問題の入ってるデータテーブルってPublicなものですか? そうであるならば、「既に使用した(Used)」というような列を作って、 Private Sub NextQuestion_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles NextQuestion.Click ' 前の問題の答え合わせや、いろんな処理(割愛します) Dim rnd As New Random Dim Qindex As Intege while ' データテーブルから問題の番号を選ぶ処理 Qindex = rnd.Next(0, 300) ' 選んだ問題が既に使用されたものかチェック if DataSet1.DataTable1(i).used = 0 then ' 初めて使要する問題ならループを抜ける DataSet1.DataTable1(i).used = 1 exit loop end if loop End sub こんな感じでしょうか?動作確認して無いので不備はあるかもです。

専門家に質問してみよう