今回のC言語テストでは、今までの知識でもゲームっぽいモノは作れるという意味で提示しています。ゲームには乱数がつきものなので、その使い方の具体的な記述についても慣れて欲しかったんですね。ということで、問題毎に解説していきます。


問9. テレビ局判定

#include <stdio.h> #include "Define.H" void main() { int nCH; // チャンネル番号 // テレビチャンネル番号の入力 printf("テレビのチャンネル番号を入力してください : "); scanf_s("%d", &nCH); // チャンネル番号からテレビ局を判断する printf(FWHITE); switch (nCH) { case 1: printf("東海テレビです。\n"); break; case 3: printf("NHK総合です。\n"); break; case 5: printf("CBCテレビです。\n"); break; case 9: printf("NHK教育です。\n"); break; case 11: printf("メ~テレです。\n"); break; case 25: printf("テレビ愛知です。\n"); break; case 35: printf("中京テレビです。\n"); break; default: printf(FRED); printf("そんなテレビ局はありません。\n"); break; } printf(ATBCLEAR); }
switch の使い方の履修問題となります。case の数値を列挙体にしている人がいるかもしれませんが、名古屋近郊に住んでいる人には、この番号と曲名は円周率と同じくらい当たり前の割り当てなので、そのまま即値で書いてしまいますね😁


  • 問10. 足し算問題

#include <stdio.h> #include <stdlib.h> #include <time.h> #include "Define.H"
void main() {
int num1; // 足し算の値1 int num2; // 足し算の値2 int nAnswer; // ユーザーが入力した解答 // 乱数の初期化 srand((unsigned)time(NULL)); // 問題の作成 num1 = rand(); num2 = rand(); // 問題の表示と入力 printf("%d+%d=", num1, num2); printf(FCYAN); scanf_s("%d", &nAnswer); // 正解か調べる if (num1 + num2 == nAnswer) { printf(FYELLOW); printf("正解!!\n"); } else { printf(FRED); printf("外れ! "); printf(FWHITE); printf("正解は %d でした。\n", num1 + num2); } printf(ATBCLEAR); }

まず大事なのが include です。srand の初期化に time を使いますので、time.h の読み込みが必要です。もちろん rand を使う為に stdlib.h も必要ですね。

問題で二つの数値に関しては、特に指定が無かったため、rand() から得られた値をそのまま使っていますが、適当な範囲にしたりと加工していても OK です。printf と scanf_s の間で色を変えると、入力文字の色を変える事が出来ます。

正解判定はこの解答例では if の中で直接加算して判定しています。加算結果を別途使用する事が無い場合は、このように if の中だけで済ませてしまう方が僅かではありますが、メモリ的速度的に有利です。まあ、外れの場合にもう一度答えを表示していますから、変数に入れても良かったんですけどね。なので、この問題の正解は複数あります。
※ PS1 / PS2 の出力で21ピン変換します。が、これでそのまま出力できているかは不明ですが(後述

  • 問11. 謎の番号

#include <stdio.h> #include <stdlib.h> #include <time.h> #include "Define.H" void main() {
int nCorrectNumber; // 正解 int nUserNumber; // ユーザーの入力した数 // 謎の数値を作る srand((unsigned)time(NULL)); nCorrectNumber = (rand() % 5) + 1; // ユーザー入力 printf("1~5の謎の番号を当ててみよう : "); scanf_s("%d", &nUserNumber); // 正解の表示 printf("\n"); printf("謎の数は %d でした!!\n", nCorrectNumber); // 入力の数が正解か確認 if (nUserNumber == nCorrectNumber) { printf(FYELLOW); printf("当たり!!\n"); } else if (nUserNumber < nCorrectNumber) { printf("もっと大きい。\n"); } else { printf("もっと小さい。\n"); } printf(ATBCLEAR); }
1~5 までのランダムな値を取り出す rand を記述できるかが最初のチェックポイント。単純に %5 としただけだと 0 からになってしまいますが、このようなミスはうっかりやってしまいがちです。正解判定式で if ~ else if ~ else という流れで記述できていればエレガントです。


  • 問12. 所定範囲なら命中

#include <stdio.h> #include <stdlib.h> #include <time.h> #include "Define.H"

void main() {
float fTarget; // 狙う値 float fAttack; // ユーザーの入力の値 srand((unsigned)time(NULL)); // ターゲットを作る // ※乱数同士を掛けることで更にランダムな値とする。 fTarget = ((rand() * rand()) % 10000) / 1000.0f; // ユーザーの入力 printf("どこを狙いますか? (0.000~9.999) : "); printf(FCYAN); scanf_s("%f", &fAttack); // 正解表示 printf(FWHITE); printf("ターゲットは %.3f にいました!!\n", fTarget); // 当たり判定 if (fAttack == fTarget) { // 全く同じ値 printf(FGREEN); printf("ビンゴ!!\n"); } else if (fAttack <= fTarget + 1.0f && fAttack >= fTarget - 1.0f) { // ターゲットの値がプラスマイナス1以内 printf(FCYAN); printf("命中!\n"); } else { printf(FRED); printf("外れ....\n"); } printf(ATBCLEAR); }
元の問題提示が小学4年生向けなので Hint! としてあったので、あまり悩まなかったのでは無いかと思います。小数の乱数はこのような小数点以下の桁数で割るのが定番です。なお、浮動小数を == で判定していますが、ここは実は環境によって動作が微妙に変わってしまいますので、本当はこの書き方は避けたいところです。厳密に判定する場合は。有効桁数で桁上げした後に整数にキャストしてから比較判定すると良いと思います。

さて、答え合わせは如何だったでしょうか。次回からはループの説明に入ります。処理の流れを上に戻す事が出来るようになりますので、ゲームのメインループを作る事が出来ます!

>> C言語013 ループに進む
※ 先のケーブルをこのコンバーターに通すと綺麗なデジタル出力が得られます。