数字当てゲームを作っています。コンピューターに0~9のランダムな数を一つ表示させ、利用者には数を予測してもらい、キーボードから入力してもらいます。キーボードからの入力値とコンピューターから表示される数字の差により、利用者にポイントを与えたり、引いたりして、持ち点が1000点または0点になったら終了させます。このようなプログラムを書きました。しかし、いつまでたっても持ち点が50点のままです。一体どこが間違っているのでしょうか。教えていただけると嬉しいです。よろしくお願いいたします。
c
1#include <stdio.h> 2#include<stdlib.h> 3 4int rand_n(void);//これは乱数を表示する関数 5 6int rand_n(void) { 7 8 int m = 0; 9 m = 0 + (int)(rand()*(9 - 0 + 1.0) / (1.0 + RAND_MAX)); 10 11 return m; 12 13} 14int guess(int n , int m);//入力された数字とコンピュータが出した数字の差を計算してくれる関数 15 16int guess(int n, int m) { 17 int s = 0; 18 19 if (n > m) { 20 s = n - m; 21 22 } 23 else { 24 s = m - n; 25 26 } 27 return s; 28} 29int hold(int s, int f); 30 31int hold(int s,int f) {//持ち点を計算してくれる関数 32 33 34 //for (int i = 0; f < 1000; i++) { 35 36 if (s == 0) { 37 f = f + 400; 38 } 39 else if (s == 1) { 40 f = f + 300; 41 } 42 else if (s == 2) { 43 f = f + 250; 44 } 45 else if (s == 3) { 46 f = f + 150; 47 } 48 else if (s == 4) { 49 f = f + 100; 50 } 51 else if (s == 5) { 52 f = f + 50; 53 } 54 else if (s == 6) { 55 f = f - 10; 56 } 57 else if (s == 7) { 58 f = f - 20; 59 } 60 else if (s == 8) { 61 f = f - 30; 62 } 63 else if (s == 9) { 64 f = f - 50; 65 } 66 67 //printf("%d回目終了!あなたの持ち点は%d点です。\n", i+1, f); 68 //} 69 return f; 70} 71 72 73int main(void) { 74 printf("GESS NUMBER\n"); 75 76 printf("You have 50 points\n"); 77 78 //キーボードからの入力を受け付ける 79 int f = 50; 80 for (int i = 0; f < 1000; i++) { 81 int n = 0; 82 printf("予測した数字(0~9)を入力してください。\n"); 83 84 scanf("%d", &n); 85 86 rand_n();//コンピューターがえらんだ数字を表示する 87 88 printf("コンピューターが選んだ数字は%d\n", rand_n()); 89 90 int t = 0; 91 92 t = guess(n, rand_n());//入力値との差を計算する 93 94 hold(t,f);//持ち点の計算をする。 95 96 printf("%d回目終了!あなたの持ち点は%d点です。\n", i + 1, f); 97 } 98 printf("Yor point is 1000!\n"); 99 100 printf("Quit this game\n"); 101 102 return 0; 103}
int f = 50;の直後にif (f == 0) {が有るのはなぜでしょう?・・・この判定は必ず偽になりますよね?
で、return 0 + (int)(rand()*(9 - 0 + 1.0) / (1.0 + RAND_MAX));
単純に0〜9を発生させるだけならrand()%10ではだめですか?
また、rand_n()を毎回呼んでると乱数の値が変わりますが、意図したことでしょうか? rand_n() - gが負数になったらどうなりますか?
> int rand_n(void);//これは乱数を表示する関数
> int rand_n(void) { (略)
関数を先に宣言致しますのは, コード上, 実際の定義の前にその関数を使用する別の関数が書かれている場合と記憶しています.
このように続けられるのは不要で, 宣言は削除されても問題無いかと思います.
また, rand_n 関数は '表示' (printf)を行っておりません.
コメントが実際と異なると, それが正しいかどうかを判断するため, 開発に向いていた思考が止まり易くなってしまいます.
間違ったコメントは削除し, コードがコメントとして機能するように, 変数名やメソッド名を決定頂くほうが宜しいかと思います.
例: s → score, guess() → difference()
> int guess(int n , int m);//入力された数字とコンピュータが出した数字の差を計算してくれる関数
n と m の差でしたら, Math.abs() メソッドが御座います.
int guess(int n, int m) { return Math.abs(n, m); } //入力された数字とコンピュータが出した数字の差を計算してくれる関数
で済み, コードの見通しが多少良くなるかと思います.
> int hold(int s,int f) {//持ち点を計算してくれる関数
s が 0~9 の範囲を取り, f を加減算されるのでしたら, 配列のご使用がシンプルかと思います.
int[] values = { 400,300,250,150,100,50,-10,-20,-30,-50 }
int hold(int s,int f) { return f + values[s]; } //持ち点を計算してくれる関数
なお, hold 関数は計算結果を **戻り値** として返しております. パラメータとして渡している f は, 呼び出し側では変化致しません. (これは f を '値渡し' しているためです. )
計算結果を f に入れ直されるのであれば,
f = hold(t,f);
とする必要がございます.
あらW・・・やっぱそうだよね(゚д゚)(。_。)(゚д゚)(。_。) ウンウン
ちなみに、うちのコンパイラ(clang version 8.0.0)は、-Weverything有効にしてるんで・・・
t176063.c:12:5: warning: no previous prototype for function 'rand_n' [-Wmissing-prototypes]
int rand_n(void) { return rand() % 10; }
^
t176063.c:14:5: warning: no previous prototype for function 'guess' [-Wmissing-prototypes]
int guess(int f)
^
2 warnings generated.
「プロトタイプ何とかしろ」みたいな文句言うんで・・・
Math.abs() ?・・javaなので、私はint p = abs(rand_n() - g);にしています。
ありがとうございます。コメントの付け方など、至らない点が多くあることが分かりました。皆さんのコメントを参考に修正したいと思います。
ああ, 申し訳ありません. 言語を複数同時に使ってしまいまして, 混乱しておりました.

回答3件
あなたの回答
tips
プレビュー