質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

Q&A

解決済

3回答

2724閲覧

数字当てゲームを作りたい

h_proc

総合スコア68

C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

1グッド

1クリップ

投稿2019/02/23 09:04

編集2019/02/23 22:52

数字当てゲームを作っています。コンピューターに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}
DrqYuto👍を押しています

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

cateye

2019/02/23 10:53 編集

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が負数になったらどうなりますか?
jimbe

2019/02/24 08:26

> 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); とする必要がございます.
cateye

2019/02/24 10:43 編集

あら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);にしています。
h_proc

2019/02/24 12:12

ありがとうございます。コメントの付け方など、至らない点が多くあることが分かりました。皆さんのコメントを参考に修正したいと思います。
jimbe

2019/02/24 16:45

ああ, 申し訳ありません. 言語を複数同時に使ってしまいまして, 混乱しておりました.
guest

回答3

0

ベストアンサー

  • testとdebugのやり方を習得しよう。

じゃないとトラブルのたんびに誰かにお伺いをたてねばならん。

  • やりたいことを箇条書きあるいは疑似コードで表現せよ
得点 = 50 回数 = 0  while ( 得点 > 0 && 得点 < 1000 ) { 回数++ 問題 = 0~9 の乱数 回答 = 入力値 得点 += 問題 と 回答 の 差に基づく評価値 回数 と 得点 を表示する }

んでもってコレ↑をCで表現せよ。

投稿2019/02/23 13:22

編集2019/02/23 16:25
episteme

総合スコア16614

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

cateye

2019/02/23 14:26 編集

乱数の発生をループの外側でやるか内側でやるかよくわからない・・・ (一回ごとの点数が有るから内側説が有望かも) あと、while ( 得点 > 0 || 得点 < 1000 ) { → while ( 得点 > 0 && 得点 < 1000 ) {
episteme

2019/02/23 16:28

外でやるんなら「何回の入力でHitするか」が得点になると思うんよね。 ...指摘ありがとです。条件のトコ、修正しときました。
guest

0

BAが出たようなので・・・

c

1#include <stdio.h> 2#include <stdlib.h> 3// 4//0〜9の乱数を発生させる。 5int rand_n(void); 6//入力された数字とコンピュータが出した数字を比較して点数を返す。 7int guess(int); 8// 9/************************************* 10*************************************/ 11// 12int rand_n(void) { return rand() % 10; } 13// 14int guess(int f) 15{ 16 static int cnt = 1; 17 static const int point[] = { 18 // 10回ぐらいでプレイヤーが勝つ 19// 400, 300, 250, 150, 100, 50, -10, -20, -30, -50 20 // 30回ぐらいでプレイヤーが勝つ 21 200, 100, 50, 25, 10, 0, -25, -50, -100, -200 22 23 }; 24 int g; 25 char buf[32]; 26 27 printf("Stage%d: Yor point is %d\n", cnt, f); 28 puts("数字を予測してください。"); 29 // 30 fgets(buf, sizeof buf, stdin); 31 sscanf(buf, "%d", &g); 32 // 緊急脱出用^^; 33 if (0 > g || g > 9) { 34 puts("quit!"); 35 exit(1); 36 } 37 // 38 printf("Selected number is %d\n\n", g); 39 // 40 int p = abs(rand_n() - g); // abs()は結果が負になった時の対策 41 // for DEBUG 42 if (p == 0) { 43 puts("equal"); 44 } 45// printf("%d\n", p); 46 // 47 f += point[p]; 48 // 49 cnt++; 50 // 51 return f; 52} 53 54int main(void) 55{ 56 puts("guess NUMBER"); 57 58 puts("0~9の数字がランダムに選択されるので、\n" 59 "選択された数字を当ててください。\n"); 60 61 puts("You have 50 points\n"); 62 63 int f = 50; 64 do{ 65 f = guess(f); 66 }while (f > 0 && f < 1000); 67 68 // 69 if (f <= 0) { 70 puts("your loss ;-p"); 71 } else { 72 puts("Your wins v^^"); 73 } 74 // 75 puts("Quit this game!"); 76 77 return 0; 78} 79

 一応動作確認はしていますが、分かるでしょうか?
何かいい変数名がないかちょっと考えたのですが、このままとします。

投稿2019/02/24 10:23

編集2019/02/25 10:20
cateye

総合スコア6851

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

cateye

2019/02/24 11:07 編集

ちなみに得点についてはjimbeさんの言うようにテーブルにしています。“連続した数値でデータを引用をする”という時はテーブルに出来ないか?とか考えましょうd^^ (まぁ、今回は0〜9と範囲が狭いのでswitchもありかw) また、私がコメントに書いた負の数になった時どうするか?は解決しましたか?・・・ヒントはjimbeさんが書いてくれています。みなさんの書いてくれたことを精査して必要な情報を引き出しましょう d^^
cateye

2019/02/25 10:23

長くなるので最後だけ・・・ Stage6: Yor point is 135 数字を予測してください。 1 Selected number is 1 Stage7: Yor point is 145 数字を予測してください。 11 quit! 「緊急脱出」は、ゲームが終わらないかやめたい時用
guest

0

まず乱数とは何か知るべきです。

C

1#include <stdio.h> 2#include <stdlib.h> 3 4 5int rand_n(void) { 6 return 0 + (int)(rand()*(9 - 0 + 1.0) / (1.0 + RAND_MAX)); 7} 8 9int main(void) { 10 printf("%d\n", rand_n()); 11 printf("%d\n", rand_n()); 12 printf("%d\n", rand_n()); 13 14 return 0; 15}

実行結果 Wandbox

stdout

18 23 37

rand_nを呼び出す度、毎回違う値が返ってきます。
ご提示のプログラムについても同じで、途中で何回も答えが変わっています

ゲームとして成立させるなら、
一回だけrand_nを呼び出し、その返り値を答えとして変数に格納しておくべきです。

しかし、キーボードからの入力値とコンピューターから表示される数字の差が正しく計算されておらず、試しに表示させた(31行目)ところ、-18456と表示されてしまいました。

C

printf("%d\n", g - rand());

前述のとおり乱数の値は毎回異なりますし、
randはrand_nよりもっと広い範囲の整数を返しますから、何ら不思議では無いです。

その他、怪しい箇所

上から順に列挙します。
0. グローバル変数のfとローカル変数のfが共存している。
0. 不要なプロトタイプ宣言が並んでいる。
0. rand_nの実装について、なぜ0を加算しているのか。
0. gess ⇒ guess
0. fを初期化した直後に値を判定しても意味が無い。
0. for (int i = 0; f == 100; i++) 継続条件が仕様に反する。

ゲームを作るのは確かに楽しいですが、もうちょっと簡単なものから始めてはいかがですか。
特にループの挙動について入念な復習が必要です。

ゲーム中、値の入力を一回しか受け付けていないことに気付いているでしょうか。

質問編集を受けて

rand_nを呼び出す度に答えが変わっています。
一回だけrand_nを呼び出し、その返り値を答えとして変数に格納しておくべきです。

投稿2019/02/23 09:22

編集2019/02/24 01:45
LouiS0616

総合スコア35660

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

h_proc

2019/02/23 12:54

ありがとうございます。もう一度考え直してみます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問