C言語

【C言語】クイズゲーム作成(6)問題をランダム(シャッフル)出題

クイズゲーム作成(6)問題をランダム出題

こんにちは、コンジ(@pippi_kon)です。

この記事では『C言語でのクイズゲームの作り方』をご紹介しています。

前回は、スコア(解答結果)の記録と表示をする方法をご紹介しました。

クイズが終わった後に結果発表すると、なんかそれっぽくなりますよね!

今回は、よりクイズゲームっぽくさせるために、問題をランダム(シャッフル)で出題する方法をご紹介します。

OS:Windows 10(x64)
開発環境:Visual Studio 2019(Community)

今回の目標

今回作成するプログラムの出力結果です。

[第1問]
世界三大珍味はどれ?
1:イカスミ 2:キャビア 3:チーズ
>>> 1
不正解…
正解は 2:キャビア です。

[第2問]
リンゴは英語で何と言う?
1:apple 2:orange 3:banana
>>> 1
正解!

[第3問]
大正->昭和->○○->令和
○○に入る年号は?
1:慶応 2:明治 3:平成
>>> 3
正解!

–クイズ終了–
[第1問]…×
[第2問]…○
[第3問]…○
あなたは 3 問中 2 問正解でした (正答率:66 %)

前回までと出題される順番が違っていることにお気づきでしょうか?

今回のプログラムでは、実行するたびに出題される順番が変わります。

やっていることは単純で、

  1. クイズ数分の乱数(0 or 1 or 2)を生成する
  2. 乱数と同じ配列番号のクイズが出題されたかチェック
  3. 出題されていたら乱数の生成しなおし
  4. 出題されていなかったら出題する

これをクイズ数分繰り返しています。

 

プログラム全文

今回作成したプログラムのご紹介です。

のちほど、プログラムの解説を行います。

 

 


プログラムの解説

ヘッダーの追加(乱数生成用)

 

stdlib.h」「time.h」をインクルードしています。

これらは乱数を生成するために必要となります。

stdlib.hは以前追加していましたが、その後不要になったので消してました。今回再度追加します

 

フラグ制御用定数を追加

 

対象のクイズが出題されたかどうかをチェックするためにフラグ制御を行います。

フラグ値としてON(1)、OFF(0)を定義しておきます。

 

構造体にフラグ追加

 

構造体メンバーに『このクイズは出題済みか』をチェックするためのフラグを追加します。

フラグ値は以下の2パターンです。

項目
FLAG_ON(1) 出題済み
FLAG_OFF(0) 未出題

 

フラグ初期化処理の追加

 

追加したフラグ(done_flag)を初期化する処理を追加します。

すべてのクイズは関数「set_quiz」を呼んで登録するようになっているので、この関数内で初期化すればラクチンです!

一律『FLAG_OFF(未出題)』に初期化します。

 



乱数の生成

クイズをランダム出題するために乱数を使用します。

 

乱数を保持するための変数rを宣言します。

 

 

乱数を初期化するための処理を追加します。

この一文がないと、初回のビルド時は乱数が生成されますが、次回以降は初回と同じ値が生成されてしまいます

プログラム実行毎に乱数を生成するために、乱数の初期化処理を行います。

上記は『現在時刻で乱数を初期化する』という意味です。

 

 

rand関数で乱数を生成します。

rand関数はランダムな数値を返却します。

これだけだとちょっと使い勝手が悪いのですが、任意の値で割った余り(剰余)を求めることで使い勝手が大幅にアップします。

剰余では、必ず「0~指定した任意の値-1」の値が求められます。

5で割った余りは0~4のいずれかに、100で割った余りは0~99のいずれかになるといった感じです。

今回、クイズは全部で3問あります。

3で割った余りを求めれば、返却される値は0,1,2のいずれかとなりますので、どのクイズを出題するかランダムに選択できるというわけです。

 

最後に、生成した乱数に対応するクイズを出題するように変更します。

具体的には、quiz[i]としていたところをquiz[r]に変更します。

 

 

 

 

 

出題済みかチェック

 

構造体メンバーの「done_flag」の値をチェックし、出題済み(FLAG_ON)だった場合は後続のループ処理をスキップ(continue)します。

continueは、強制的に次のループ処理を行うというもの。

continue以降の処理は実行されず、ループの先頭に戻ります。

このとき、forループを使用していると、forの3つ目の要素(i++)が実行されてしまいます。

今回の場合、continue後はiの値を変えたくないので、ループの種類をwhileループに変更しました。

 

変更に伴い、変数iの初期化処理を追加しています。

 

また、ループ処理の最後で変数iをカウントアップしています。

 

 

クイズ出題済みフラグを立てる

 

クイズを出題したら、そのクイズの出題済みフラグをONにします。

こうすることで、次回以降このクイズが出題されることはありません。

 



最後に

今回は、『問題をランダム(シャッフル)で出題する方法』をご紹介しました。

乱数処理はクイズゲームだけでなくいろいろな場面で使用します。

使いこなせるようになっておきましょう!

 

では今回はここまで。おつかれさまでした!

【2020年版】定番の解説本!C言語入門におすすめの参考書_サムネ
【2021年版】定番の解説本!C言語入門におすすめの参考書『C言語初心者にオススメしたいプログラミング参考書』をご紹介します。...
created by Rinker
¥2,750
(2021/05/18 10:49:56時点 Amazon調べ-詳細)

created by Rinker
¥2,530
(2021/05/18 10:49:57時点 Amazon調べ-詳細)

ABOUT ME
コンジ
コンジ
自分のやりたいことでお金を稼げる生活に憧れて脱サラ。 アプリ開発やブログ運営をしながらのんびり暮らしています。