こんにちは。武田です。
2月9日は記録的な大雪となりましたが、みなさんはいかがお過ごしでしたか?
雪の日は、行動派なら「雪かき」、ひきこもりなら「プログラミング」に限りますね。
わたしはちなみに「プログラミング」です!
プログラミングの面白いところは、答えが一つではないところです。
どこか人生にも似ていると思います。
わたしは完成したプログラムよりも、プログラミングで試行錯誤している過程が好きです。
学生にC言語で、こんな課題を出しました。
画面に表示された10進数を16進数で答えるゲーム 仕様 ・問題はランダムに5問出題される ・0~15の10進数が画面に表示される ・ユーザはキーボードから答えを16進数で入力する ・解答後に「正解」「不正解」を表示する ・解答での大文字・小文字の区別はない 例)問題が「10」のとき、「A」も「a」も正解
問題データの持ち方でプログラムの内容も変わってくると思います。
わたしは文字型で問題と解答データを作成しました。
配列変数の初期化にはmemsetなども使ってC言語の基本にそって作ってみました。
scanfなどの危険な関数もあえて使わずに実践的に作ったつもりです。
以下、解答例です。
正直なところ、もっと簡単なプログラムでもできます。
/* answer16.c 画面に表示された10進数を16進数で答えるゲーム 仕様 ・問題はランダムに5問出題される ・0~15の10進数が画面に表示される ・ユーザはキーボードから答えを16進数で入力する ・解答後に「正解」「不正解」を表示する ・解答での大文字・小文字の区別はない 例)問題が「10」のとき、「A」も「a」も正解 Created by take3.asia on 2014/02/10. Copyright 2014 Shuichi Takeda, All rights reserved. */ #include <stdio.h> #include <string.h> #include <stdlib.h> #include <time.h> #include <ctype.h> #define MAX 16 int main(void) { int i, j, r; char mondai[MAX][3]; char kotae[MAX][2]; char kaitou[MAX]; // 配列の初期化 memset(mondai, 0, sizeof(mondai)); memset(kotae, 0, sizeof(kotae)); memset(kaitou, 0, sizeof(kaitou)); /* 問題と解答の設定 */ for(i=0; i<MAX; i++){ sprintf(mondai[i], "%d", i); /* 0, 1, 2...15 */ sprintf(kotae[i], "%X", i); /* 0, 1, 2...F */ } /* ランダムで5問出題 */ srand((unsigned)time(NULL)); printf("10進数を16進数に直して答えて下さい..."); getchar(); for(i=0; i<5; i++){ r = rand() % MAX; printf("[ %s ] の16進数は? ", mondai[r]); /* 解答する */ fgets(kaitou, sizeof(kaitou), stdin); sscanf(kaitou, "%2s", kaitou); for(j=0; kaitou[j] != '\0'; j++) kaitou[j] = toupper(kaitou[j]); /* 小文字入力は大文字に変換 */ rewind(stdin); /* 正誤 */ if(!strcmp(kotae[r], kaitou)){ printf("○\n"); } else{ printf("×\t->%s\n", kotae[r]); } } return 0; }
ところで、このプログラムには欠点があり、場合によっては同じ問題が続けて出題されてしまいます。
ランダムで毎回適当に出題しているからです。
重複しないで出題するにはどうすればいいでしょうか?
これが正式な課題です。
その方法は色々あります。