- 追加された行はこの色です。
- 削除された行はこの色です。
*数当てゲーム [#j1e784ae]
これまでに勉強したことを使って、次のような簡単な数当てゲームを作ります。
コンピューターがある数を一つ決め、プレイヤーがその数を当てます。
コンピューターは、プレイヤーが答えた数が正解よりも大きいか小さいかだけを教えます。
*考え方 [#e134d110]
*実行結果をイメージする [#c224395d]
プログラムを作るときは、まず、プログラムを書き始める前に、アルゴリズムまたはフローチャートを考えます。
プログラムを作るときは、まず、プログラムの実行結果をイメージします。
最初に、このゲームを実行すると、コンピューターがプレイヤーに入力を要求します。
プレイヤーがキーボードから数を入力すると、コンピューターが、それに対してメッセージを出力します。
これを、正解するまで繰り返します。
したがって、次のような感じになるようにプログラムを作ります。
整数を入力してください:
99
大きすぎます
整数を入力してください:
11
小さすぎます
整数を入力してください:
33
正解!
実行結果をイメージすることで、どんな処理が行われるのか、どんな処理が繰り返されるのかが、ある程度明確になります。
*フローチャートを作る [#e134d110]
次に、プログラムを書き始める前に、フローチャート(またはアルゴリズム)を考えます。
このプログラムは、二つの部分に分けることができます。
+コンピューターがある数(正解)を一つ決める
+プレイヤーが答える
最初の、コンピューターがある数(正解)を一つ決めるところは、[[計算ゲーム>授業/C言語基礎/計算ゲーム]]と同じように、乱数を使えばできます。
乱数の使い方がわからない場合は、プログラム中に正解の値を自分で指定してもかまいません。
乱数の使い方がわからない場合は、自分で正解の値を決めてもかまいません。
その次の、プレイヤーが答えるところは、これまでに勉強した制御構造(条件分岐と繰り返し)を組み合わせて作ります。
この部分の中心は、ユーザーが答えて、それが正解よりも大きいか小さいかを教えるというものですから、キーボードからの入力と条件分岐を組み合わせると、次のようになります。
+scanf関数でキーボードから入力する
+if文で入力された数と正解を比べる
--入力された数が正解よりも大きいならば、「大きすぎる」と表示する
--入力された数が正解よりも小さいならば、「小さすぎる」と表示する
これを、正解が入力されるまで繰り返します。
これを、そのままフローチャートにすると、次のようになります。
#ref(./number1.png,50%)
ところが、これだと、繰り返しの部分がC言語の繰り返し処理のフローチャートと対応していないので、プログラムとして書きにくいです。
そこで、繰り返しの文をC言語の繰り返し処理のフローチャートに対応するように、フローチャートを書き直します。
#ref(./number2.png,50%);
*プログラム [#k81d93b9]
ここでは、正解は1から100までの整数にします。
*プログラムを作る [#k81d93b9]
フローチャートができたら、プログラムを作ります。
乱数を使って正解の数を決める部分だけを作ると、次のようになります。
#geshi(c){{
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main(void) {
int r;
srand((unsigned int) time(NULL));
r = rand() % 100 + 1;
return 0;
}
}}
ここでは、正解の数は、1から100までの整数としています。
rand関数、srand関数、time関数の使い方については、[[計算ゲーム>授業/C言語基礎/計算ゲーム]]を復習しましょう。
次に、その後の繰り返し処理を形だけ作ります。
#geshi(c){{
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main(void) {
int r;
srand((unsigned int) time(NULL));
r = rand() % 100 + 1;
while ( ) {
}
printf("正解!\n");
return 0;
}
}}
ただし、これだとコンパイル時にwhile文の繰り返し条件でエラーになりますので、実際には、条件を 1 にしておくといいです。(忘れないように注意が必要です。)
条件を考えるのは後にして、先に、繰り返し処理の中を考えましょう。
繰り返し処理の中だけを考えると、次のようになります。
#geshi(c){{
printf("1から100までの整数を入力してください:\n");
scanf("%d", &a);
if (a > r) {
printf("大きすぎます\n");
} else if (a < r) {
printf("小さすぎます\n");
}
}}
そこで、これをwhile文の波括弧 { } の中にいれて、新しく登場した変数 a の宣言を追加します。
#geshi(c){{
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main(void) {
int r, a;
これを実現する方法は、いくつかあります。
srand((unsigned int) time(NULL));
r = rand() % 100 + 1;
まず、最初はwhile文の条件が必ず満たされないようにして、前置判定する方法。
#geshi(c){{
a = -1;
while (a != r) {
while ( ) {
printf("1から100までの整数を入力してください:\n");
scanf("%d", &a);
if (a > r) {
printf("大きすぎます\n");
} else if (a < r) {
printf("小さすぎます\n");
}
}
printf("正解!\n");
return 0;
}
}}
次に、無限ループにして、break文で無限ループを中断する方法。
正解でない間、繰り返すので、繰り返し条件は「a と r が等しくない」という式になります。
また、最初は、繰り返し条件を必ず満たすようにしなければならないので、a の値を1から100まででない値に初期化します。
#geshi(c){{
while (1) {
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main(void) {
int r, a;
srand((unsigned int) time(NULL));
r = rand() % 100 + 1;
a = -1;
while (a != r) {
printf("1から100までの整数を入力してください:\n");
scanf("%d", &a);
if (a > r) {
printf("大きすぎます\n");
} else if (a < r) {
printf("小さすぎます\n");
} else {
break;
}
}
printf("正解!\n");
}}
最後に、do-while文で、後置判定する方法。
#geshi(c){{
do {
printf("1から100までの整数を入力してください:\n");
scanf("%d", &a);
if (a > r) {
printf("大きすぎます\n");
} else if (a < r) {
printf("小さすぎます\n");
}
} while (a != r);
printf("正解!\n");
return 0;
}
}}
これで完成です。