こんにちは。武田です。
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;
}
ところで、このプログラムには欠点があり、場合によっては同じ問題が続けて出題されてしまいます。
ランダムで毎回適当に出題しているからです。
重複しないで出題するにはどうすればいいでしょうか?
これが正式な課題です。
その方法は色々あります。