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

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

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

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

Q&A

解決済

2回答

2858閲覧

繰り返し遊べる数当てゲームを作りたい

futonmin

総合スコア33

C

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

0グッド

0クリップ

投稿2020/06/06 21:35

私は今、C言語を使ってゲームクリアまたはゲームオーバーした後に「もう一度遊びますか?」などと聞いて繰り返し遊べる数当てゲームを作ろうとしています。
今抱えている問題は、ゲームを繰り返し遊んでいくと正常にゲームが進まなくなるということです。
2回繰り返し遊んだ後にもう一度繰り返したら正解である数字を入力しているのに正解と判断されなかったり、何回か遊んだ後にゲームをやめるを選択してもまたゲームが始まります。
下のコードのどこがダメなのか、どうすれば正常な繰り返し遊べる数当てゲームを作れるのか教えていただきたいです。
ゲーム製作中でやたらとprintfが多いので見にくかったらすいません

#include <stdio.h> #include <stdlib.h> #include <time.h> #pragma waring(disable:4996) int main(void) { //player=プレイヤーが打ち込んだ数値 //n=乱数 //con=ゲームを続けるかの選択肢 //mdr=選択したらストーリーに戻る int n, i, player, con, mdr; //answer=プレイヤーの選択肢 char answer; srand((unsigned)time(NULL)); //一通りゲームが終わって繰り返し遊ぶを選択したらここへ戻ってくる loop: n = rand() % 100 + 1; printf("ゲームの世界にようこそ!!"); rewind(stdin); getchar(); printf("君がこの世界のことをどれだけ知っているかは知らないが、"); rewind(stdin); getchar(); printf("この世界の優劣が全て数当てゲームで決まることくらいは知っているだろう?(Y/N)"); scanf("%c", &answer); //プレイヤーがYまたはyを入力した時 if (answer == 'Y' || answer == 'y') { printf("ほう...なかなか見込みのある小僧だ!"); rewind(stdin); getchar(); printf("いらないとは思うが一応ルール説明をしておこう"); rewind(stdin); getchar(); printf("ルールは簡単だ、コンピュータがランダムに決めた1から100までの数字を君が当てれれば君の勝ち"); rewind(stdin); getchar(); printf("外せば君の負けだ、チャンスは10回だ"); rewind(stdin); getchar(); printf("検討を祈っている"); rewind(stdin); getchar(); } //プレイヤーがNまたはnを入力した時 else if (answer == 'N' || answer == 'n') { printf("救いようのないクズめ!"); rewind(stdin); getchar(); printf("まだそこら辺に転がってるペットボトルのほうが見込みがあるわ!"); rewind(stdin); getchar(); printf("失望したよ...仕方がないから君の様なペットボトル以下の人間にも分かりやすく説明してやろう"); rewind(stdin); getchar(); printf("ルールは簡単だ、ペットボトル以下の君にとって簡単かは知らないがなwww"); rewind(stdin); getchar(); printf("コンピュータがランダムに決めた1から100までの数字を君が当てれれば君の勝ち"); rewind(stdin); getchar(); printf("外せば君の負けだ、チャンスは10回だ"); rewind(stdin); getchar(); printf("せいぜいペットボトルよりは優秀であることを祈っているよwww"); rewind(stdin); getchar(); } //プレイヤーがY,yまたはN,n以外のキーを押した場合 else { while (1) { printf("知ってるよな?"); scanf("%c", &answer); if (answer == 'Y' || answer == 'y') { printf("ほう...なかなか見込みのある小僧だ!"); rewind(stdin); getchar(); printf("いらないとは思うが一応ルール説明をしておこう"); rewind(stdin); getchar(); printf("ルールは簡単だ、コンピュータがランダムに決めた1から100までの数字を君が当てれれば君の勝ち"); rewind(stdin); getchar(); printf("外せば君の負けだ、チャンスは10回だ"); rewind(stdin); getchar(); printf("検討を祈っている"); rewind(stdin); getchar(); break; } else if (answer == 'N' || answer == 'n') { printf("救いようのないクズめ!"); rewind(stdin); getchar(); printf("まだそこら辺に転がってるペットボトルのほうが見込みがあるわ!"); rewind(stdin); getchar(); printf("失望したよ...仕方がないから君の様なペットボトル以下の人間にも分かりやすく説明してやろう"); rewind(stdin); getchar(); printf("ルールは簡単だ、ペットボトル以下の君にとって簡単かは知らないがなwww"); rewind(stdin); getchar(); printf("コンピュータがランダムに決めた1から100までの数字を君が当てれれば君の勝ち"); rewind(stdin); getchar(); printf("外せば君の負けだ、チャンスは10回だ"); rewind(stdin); getchar(); printf("せいぜいペットボトルよりは優秀であることを祈っているよwww"); rewind(stdin); getchar(); break; } } } //正常に動いているか確認するために乱数を表示 printf("%d\n", n); //10回まで答えることができる for (i = 0; i < 10; i++) { printf("数字を入力してくれ!:"); scanf("%d", &player); //入力した値が乱数より小さかった場合 if (n > player) { printf("もっと大きいぞ!"); rewind(stdin); getchar(); } //入力した値が乱数より大きかった場合 else if (n < player) { printf("もっと小さいぞ!"); rewind(stdin); getchar(); } //正解した場合 if (n == player) { printf("やったな!正解だ!"); rewind(stdin); getchar(); } //1回で正解した場合 if (i == 0) { printf("そんな...ありえない...おぬし、天才じゃったか..."); rewind(stdin); getchar(); printf("おぬしのスコアは100..."); rewind(stdin); getchar(); printf("「どうせまぐれだろ」の称号を授ける!"); rewind(stdin); getchar();     //2回で正解した場合 else if (i == 1) { printf("ばかな...勘のいいガキは嫌いだよ"); rewind(stdin); getchar(); printf("おぬしのスコアは90..."); rewind(stdin); getchar(); printf("「勘のいいガキ」の称号を授ける!"); rewind(stdin); getchar(); }//3回で正解した場合 else if (i == 2) { printf("シンプルに天才だな、すごいぞ"); rewind(stdin); getchar(); printf("おぬしのスコアは80..."); rewind(stdin); getchar(); printf("「天才」の称号を授ける!"); rewind(stdin); getchar(); }//4回で正解した場合 else if (i == 3) { printf("中の上レベルだな..."); rewind(stdin); getchar(); printf("天才の足元にも及ばないが普通にすごいぞ"); rewind(stdin); getchar(); printf("おぬしのスコアは70..."); rewind(stdin); getchar(); printf("「ちゃんと数当てゲームできて偉い」の称号を授ける!"); rewind(stdin); getchar(); }//5回で正解した場合 else if ("i==4") { printf("割と頑張った方だな、可もなく不可もなくレベルだ"); rewind(stdin); getchar(); printf("おぬしのスコアは60..."); rewind(stdin); getchar(); printf("「割と頑張ったのに褒められにくい人」の称号を授ける!"); rewind(stdin); getchar(); }//6回で正解した場合 else if ("i==5") { printf("コメントに困る微妙な位置だな...特に言いたいことはない"); rewind(stdin); getchar(); printf("おぬしのスコアは50..."); rewind(stdin); getchar(); printf("「割と平均的な人」の称号を授ける!"); rewind(stdin); getchar(); }//7回で正解した場合 else if (i == 6) { printf("ギリギリ赤点回避レベルだな"); rewind(stdin); getchar(); printf("おぬしのスコアは40..."); rewind(stdin); getchar(); printf("「赤点予備軍」の称号を授ける!"); rewind(stdin); getchar(); }//8回で正解した場合 else if (i == 7) { printf("親が心配するレベルの出来だな"); rewind(stdin); getchar(); printf("たまには実家に帰ってやれよ..."); rewind(stdin); getchar(); printf("おぬしのスコアは30..."); rewind(stdin); getchar(); printf("「たまには実家に帰れ」の称号を授ける!"); rewind(stdin); getchar(); }//9回で正解した場合 else if (i == 8) { printf("まあ、気にすんなよ...そんな日もあるさ..."); rewind(stdin); getchar(); printf("ココア入れるけど飲む?"); rewind(stdin); getchar(); printf("あっ、いらない?...ごめん..."); rewind(stdin); getchar(); printf("おぬしのスコアは20..."); rewind(stdin); getchar(); printf("「気まずい空気」の称号を授ける!"); rewind(stdin); getchar(); }//10回で正解した場合 else if (i == 9) { printf("ギリギリセーフだ!おめでとう!"); rewind(stdin); getchar(); printf("おぬしのスコアは10..."); rewind(stdin); getchar(); printf("「ペットボトル以上の実力」の称号を授ける!"); rewind(stdin); getchar(); } //ゲームを続けるか終わるか選択 printf("ゲームを続けるかい?続けるなら1を終わるなら1以外を押してくれ\n"); scanf("%d", &con); //1ならloopに戻る if (con == 1) { goto loop; } //1以外を押したらゲームを終わる else { break; } } } //不正解(ゲームオーバー)の場合 if (n != player) { printf("残念、ゲームオーバーだ"); rewind(stdin); getchar(); printf("おぬしのスコアは0..."); rewind(stdin); getchar(); printf("「ペットボトル戦士(笑)」の称号を授ける!"); rewind(stdin); getchar(); printf("ゲームを続けるかい?続けるなら1を終わるなら1以外を押してくれ\n"); scanf("%d", &con); //1ならloopに戻る if (con == 1) { goto loop; } //1以外を押したらゲームを終わる else { return 0; } } }コード

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

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

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

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

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

cateye

2020/06/06 23:10 編集

300行を超えるmain()は止めて、機能別に関数に切り出しては? あと、前に戻るgotoはデバグが難しい。・・・forループの中から飛んでいる・・・ 2回めでn, i, player, con, mdr, answerやキーバッファが起動時と同じことが保証できますか? ・・・1関数60行以下がお勧め・・・ //2回で正解した場合・・・の前に全角空白が入っています。また、'}'が不整合! if ("i==4")は?・・・ほかも・・・printf()に改行'\n'がないのは? //不正解(ゲームオーバー)の場合・・・は、main()の外・・・インデントをちゃんと付けましょう ちゃんとコンパイルできるコードを上げて下さい。
futonmin

2020/06/07 06:03

実行環境は詳細の文字セットを「マルチバイト文字セットを使用する」、C/C++の全般のSDLチェックを「いいえ」、C/C++のコード生成のランタイムライブラリを「マルチスレッド デバッグ (/MTd)」に変更しています それ以外はいじってないです
futonmin

2020/06/07 06:16

cateyeさんの質問に対してですが私の勉強不足でほとんど理解できなかったのですが、機能別に関数を切り出してみます。 2回めでn, i, player, con, mdr, answerやキーバッファが起動時と同じことは保証できません、わからないです。 とりあえずわからないことは調べながら、質問しながらやっていきます。ご了承ください。
raccy

2020/06/07 07:21

すいません、質問からは、Windowsなのか、Macなのか、Linuxなのかすらわかりません。Macを使っているに違いないと勝手に決めつけて答えても良いのですか?ということです。
futonmin

2020/06/07 07:23

Windowsです
guest

回答2

0

ベストアンサー

ちょとヒントを・・・

c

1#include <stdio.h> 2 3static void ans(int n) 4{ 5 static const char *msg[][5]={ 6 { "そんな...ありえない...おぬし、天才じゃったか...", 7 "おぬしのスコアは100...", 8 "「どうせまぐれだろ」の称号を授ける!", 9 0 10 },{ 11 "ばかな...勘のいいガキは嫌いだよ", 12 "おぬしのスコアは90...", 13 "「勘のいいガキ」の称号を授ける!", 14 0 15 },{ 16 "シンプルに天才だな、すごいぞ", 17 "おぬしのスコアは80...", 18 "「天才」の称号を授ける!", 19 0 20 },{ 21 "中の上レベルだな...", 22 "天才の足元にも及ばないが普通にすごいぞ", 23 "おぬしのスコアは70...", 24 "「ちゃんと数当てゲームできて偉い」の称号を授ける!", 25 0 26 } 27 }; 28 // 29 for(int i=0;msg[n][i];i++){ 30 puts(msg[n][i]); 31 } 32 getchar(); 33} 34// 35int main(void) 36{ 37 for( int i= 0; i < 4; i++){ 38 ans(i); 39 } 40 return 0; 41} 42

実行結果

text

1usr ~/Project/test % ./a.out 2そんな...ありえない...おぬし、天才じゃったか... 3おぬしのスコアは100... 4「どうせまぐれだろ」の称号を授ける! 5 6ばかな...勘のいいガキは嫌いだよ 7おぬしのスコアは90... 8「勘のいいガキ」の称号を授ける! 9 10シンプルに天才だな、すごいぞ 11おぬしのスコアは80... 12「天才」の称号を授ける! 13 14中の上レベルだな... 15天才の足元にも及ばないが普通にすごいぞ 16おぬしのスコアは70... 17「ちゃんと数当てゲームできて偉い」の称号を授ける! 18

追記
1.前処理…変数の初期化など
2.乱数を派生させ数値を当てさせる
…正解の段階についてメッセージを表示
3.再挑戦の意思確認
…10回終了時にやめるならループを抜ける
…再挑戦は2.に戻る

投稿2020/06/07 04:32

編集2020/06/07 05:00
cateye

総合スコア6851

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

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

futonmin

2020/06/07 06:26

ヒントありがとうございます。他の方にも機能別の関数を使うことを助言いただいたのでやってみます。
cateye

2020/06/07 07:09 編集

機能というのは、入力→処理→出力で考えると分けやすく成ります。 ↑の例では、状態によってメッセージを切り替えています。 ・・・この場合は、回答回数によってメッセージを切り替える方法です。出力はありません(void)が・・・ 参考:https://qiita.com/motoki1990/items/d3c747bda3d7465ad8fb
futonmin

2020/06/07 07:31

助言ありがとうございます。 static関数について調べながら入力、処理、出力のコードを書いていきたいと思います
futonmin

2020/06/07 07:32

貼っていただいたサイトも参考にさせていただきます
cateye

2020/06/07 07:43 編集

関数の頭のstaticにかんしては、うちのコンパイラ(clang10)が文句を言うので、付けてるだけです^^; ・・・たぶん『自分しか使わないならstaticにしなさい』とか言われたようなw ・・・プロトタイプ宣言でも良いのだけれど・・・
futonmin

2020/06/07 08:07

プロトタイプ宣言を使ってみます
guest

0

scanf("%c", &answer); が 2か所ありますが、どちらも
%c の前にスペースを入れて、" %c" にしたらどうなりますか?

投稿2020/06/07 00:31

kazuma-s

総合スコア8224

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

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

futonmin

2020/06/07 06:22

1発で正解すると正常に進みますが、1回以上間違えてから正解を入力すると「もっと大きいぞ!」と入力されもう一度正解を入力するとスコア表示に移りゲームを続けるか続けないか聞かれます
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問