私は今、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; } } }コード
300行を超えるmain()は止めて、機能別に関数に切り出しては?
あと、前に戻るgotoはデバグが難しい。・・・forループの中から飛んでいる・・・
2回めでn, i, player, con, mdr, answerやキーバッファが起動時と同じことが保証できますか?
・・・1関数60行以下がお勧め・・・
//2回で正解した場合・・・の前に全角空白が入っています。また、'}'が不整合!
if ("i==4")は?・・・ほかも・・・printf()に改行'\n'がないのは?
//不正解(ゲームオーバー)の場合・・・は、main()の外・・・インデントをちゃんと付けましょう
ちゃんとコンパイルできるコードを上げて下さい。
実行環境はなんですか?環境依存の動作が含まれているため、どこが悪いかはっきりしません。たとえば、`rewind(stdin)`はWindowsのCランタイム環境ではキーボード入力クリアですが、
https://docs.microsoft.com/ja-jp/cpp/c-runtime-library/reference/rewind?view=vs-2019
Linux等の別のOSでは期待通りの動作はしません。
実行環境は詳細の文字セットを「マルチバイト文字セットを使用する」、C/C++の全般のSDLチェックを「いいえ」、C/C++のコード生成のランタイムライブラリを「マルチスレッド デバッグ (/MTd)」に変更しています
それ以外はいじってないです
cateyeさんの質問に対してですが私の勉強不足でほとんど理解できなかったのですが、機能別に関数を切り出してみます。
2回めでn, i, player, con, mdr, answerやキーバッファが起動時と同じことは保証できません、わからないです。
とりあえずわからないことは調べながら、質問しながらやっていきます。ご了承ください。
すいません、質問からは、Windowsなのか、Macなのか、Linuxなのかすらわかりません。Macを使っているに違いないと勝手に決めつけて答えても良いのですか?ということです。
Windowsです
回答2件
あなたの回答
tips
プレビュー