こんにちは、コンジ(@pippi_kon)です。
この記事では『C言語でのクイズゲームの作り方』をご紹介しています。
前回は、クイズゲームの基本となる簡単な三択形式の問題の作り方をご紹介しました。
問題をただ愚直に表示するというシンプルな作りで、同じような処理を何度も行っていました。
なので今回は、似たような処理の部分をループ処理に置き換えてプログラムをスッキリさせます。
今回の目標
今回作成するプログラムの出力結果です。
[第1問]
リンゴは英語で何と言う?
1:apple 2:orange 3:banana
>>> 1
正解!
[第2問]
大正->昭和->○○->令和
○○に入る年号は?
1:慶応 2:明治 3:平成
>>> 2
不正解…
正解は 3:平成 です。
[第3問]
世界三大珍味はどれ?
1:イカスミ 2:キャビア 3:チーズ
>>> 2
正解!
出力結果自体は前回と変わりませんが、中身のプログラム処理は変わります。
前回は3つの問題をそれぞれprintf関数で表示していました。
そのため、同じ処理がプログラム内に3か所ありました。
今回は、これらを1つにまとめます。
プログラム全文
今回作成したプログラムのご紹介です。
のちほど、プログラムの解説を行います。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 |
#define _CRT_SECURE_NO_WARNINGS #include <stdio.h> #include <stdlib.h> int main(void) { int ans; int i; char q[3][5][100] = { {"リンゴは英語で何と言う?", "apple", "orange", "banana", "1"}, {"大正->昭和->○○->令和\n○○に入る年号は?", "慶応", "明治", "平成", "3"}, {"世界三大珍味はどれ?", "イカスミ", "キャビア", "チーズ", "2"} }; for (i = 0; i < 3; i++) { printf("[第%d問]\n", i + 1); printf("%s\n", q[i][0]); printf("1:%s 2:%s 3:%s\n", q[i][1], q[i][2], q[i][3]); printf(">>> "); scanf("%d", &ans); if (ans == atoi(q[i][4])) { printf("正解!\n\n"); } else { printf("不正解...\n"); printf("正解は %d:%s です。\n\n", atoi(q[i][4]), q[i][atoi(q[i][4])]); } } return 0; } |
プログラムの解説
ヘッダーの追加(atoi関数用)
3 |
#include <stdlib.h> |
新しく「stdlib.h」をインクルードしています。
これはのちに出てくる「atoi関数」を使用するために必要となります。
問題・選択肢の配列化
10 11 12 13 14 |
char q[3][5][100] = { {"リンゴは英語で何と言う?", "apple", "orange", "banana", "1"}, {"大正->昭和->○○->令和\n○○に入る年号は?", "慶応", "明治", "平成", "3"}, {"世界三大珍味はどれ?", "イカスミ", "キャビア", "チーズ", "2"} }; |
printf関数で愚直に表示していた問題文や選択肢を多次元配列に格納しました。
こうすることで、配列の添え字を変更するだけで問題文を切り替えることが可能になります。
左から順に「問題、選択1、選択2、選択3、正解の番号」となります。
for文で3回ループ
16 |
for (i = 0; i < 3; i++) { |
前回のプログラムでは問題の出題処理が3か所ありました。
これらをループ処理で一つにまとめました。
ループカウンターiを0から1ずつ増やし、3になったらループ終了。
つまり、3回ループさせます。
何問目かを表示
17 |
printf("[第%d問]\n", i + 1); |
何問目なのかはループカウンターiを利用して表示します。
iは0からスタートするのでそのまま使うと「第0問、第1問、第2問」となってしまいます。
なので表示時に+1して「第1問、第2問、第3問」となるようにしています。
問題文を表示
18 |
printf("%s\n", q[i][0]); |
問題文を表示します。
先ほど作成した多次元配列の中から問題を取り出します。
「q[i][0]」は、i行目の左から0番目という意味。
つまり、配列から取得されるものは…
ループ数 | 左から0番目 |
---|---|
1回目 | リンゴは英語で何と言う? |
2回目 | 大正->昭和->○○->令和\n○○に入る年号は? |
3回目 | 世界三大珍味はどれ? |
となります。
選択肢を表示
19 |
printf("1:%s 2:%s 3:%s\n", q[i][1], q[i][2], q[i][3]); |
選択肢を表示します。
こちらも問題文と同様に多次元配列の中から取り出します。
配列から取得されるものは…
ループ数 | 左から1番目 | 左から2番目 | 左から3番目 |
---|---|---|---|
1回目 | apple | orange | banana |
2回目 | 慶応 | 明治 | 平成 |
3回目 | イカスミ | キャビア | チーズ |
となります。
解答の判定
22 23 24 25 26 27 28 |
if (ans == atoi(q[i][4])) { printf("正解!\n\n"); } else { printf("不正解...\n"); printf("正解は %d:%s です。\n\n", atoi(q[i][4]), q[i][atoi(q[i][4])]); } |
入力された解答のチェック処理です。
チェックのもととなる正しい答えは多次元配列の中から取り出します。
配列から取得されるものは…
ループ数 | 左から4番目 |
---|---|
1回目 | 1 |
2回目 | 3 |
3回目 | 2 |
となります。
最後に
今回は、『似たような処理の部分をループ処理に置き換えてプログラムをスッキリ』させてみました。
こうすることで、プログラムが見やすくなったのと同時に、問題数を増やす場合に作業が簡単になりました。
問題数を増やす場合は以下のことをするだけでOKです。
- 多次元配列にデータ追加
- for文の最大ループ数を変更
では今回はここまで。おつかれさまでした!

(2021/04/16 08:34:13時点 Amazon調べ-詳細)
(2021/04/16 10:26:39時点 Amazon調べ-詳細)