
Cプログラムについて質問です。
列挙体と関数を用いてじゃんけんゲームを作成しています。
コンパイラは上手くいったのですが、何回か実行してみてコンピュータ側はグーしか出してくれません。
そして3つ警告が出てしまいます。
C26812 列挙型 'janken' は対象範囲外です。'enum' (Enum.3) より 'enum class' を優先します。
C6001 初期化されていないメモリ 'shoubukekka' を使用しています。 Project2
C6031 戻り値が無視されました: 'scanf' Project2
やはりこの警告のせいでグーしか出してくれないのでしょうか?
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
typedef enum janken { Gu = 0, Choki = 2, Pa = 5 } JPON;
int saikoro(void) {
int sai;
srand((unsigned)time(NULL));
sai =rand()%6+1;
return(0);
}
JPON sysjan(int sai)
{
int pon;
switch (sai) {
case 1: pon = Gu; break;
case 2: pon = Gu; break;
case 3: pon = Choki; break;
case 4: pon = Choki; break;
case 5: pon = Pa; break;
case 6: pon = Pa; break;
}
return ((JPON)0);
}
int shoubu(JPON kenin, JPON kenout)
{
int shoubukekka;
switch (kenin) {
case Gu:
if (kenout == Gu) shoubukekka = 0;
else if (kenout == Choki) shoubukekka = 1;
else shoubukekka = -1;
break;
case Choki:
if (kenout == Gu) shoubukekka = -1;
else if (kenout == Choki) shoubukekka = 0;
else shoubukekka = 1;
break;
case Pa:
if (kenout == Gu) shoubukekka = 1;
else if (kenout == Choki) shoubukekka = -1;
else shoubukekka = 0;
break;
}
return (shoubukekka);
}
void watashinoken(JPON ken)
{
switch (ken) {
case Gu: printf("わたしはグーを出しました。\n"); break;
case Choki: printf("わたしはチョキを出しました。\n"); break;
case Pa: printf("わたしはパーを出しました。\n"); break;
}
}
void anatanoken(JPON ken)
{
switch (ken) {
case Gu: printf("あなたはグーを出しました。\n"); break;
case Choki: printf("あなたはチョキを出しました。\n"); break;
case Pa: printf("あなたはパーを出しました。\n"); break;
}
}
void kekka(int r)
{
switch (r) {
case -1: printf("あなたの負けです\n"); break;
case 1: printf("あなたの勝ちです\n"); break;
case 0: printf("あいこです\n"); break;
}
}
int main(void) {
JPON choken;
JPON sysken;
int ken_buf;
int sai;
int shoubukekka;
do {
printf("\nジャンケンをしましょう。\n");
printf("\nグーは0 チョキは2 パーは5を入れます。\n");
printf("\nじゃんけんぽん!はいどうぞ:\a");
scanf("%d", &ken_buf);
choken = (JPON)ken_buf;
if ((choken != Gu) && (choken != Choki) && (choken != Pa))
printf("\n@@@@正しく入れてください!@@@@\n");
} while (!(choken == Gu || choken == Choki || choken == Pa));
sai = saikoro();
sysken = sysjan(sai);
shoubukekka = shoubu(choken, sysken);
printf("\a");
anatanoken(choken);
watashinoken(sysken);
kekka(shoubukekka);
printf("\n終わります。おつかれさまでした。\n\n");
return(0);
}
A 回答 (5件)
- 最新から表示
- 回答順に表示
No.5
- 回答日時:
> 少し修正を加えて上手いこといきました。
そりゃ良かったです。
> グーを3回連続で出してくることはありますが、ちゃんと他の手も出すようになりました。
一応、グーの3回連続出現、ってのは4%くらいの確率で起こりうるんで、25回に1回くらいの確率で出るんで、まぁ気にせんでもエエんちゃうかな。
No.4
- 回答日時:
> 何回か実行してみてコンピュータ側はグーしか出してくれません。
まず、「そりゃそうだ」と言う話。
前回
https://oshiete.goo.ne.jp/qa/12336707.html
参照すると、コンピュータの手は、
> 1.3 1~6のサイの目を引数で受け取り、目が1,2ならグーを、3,4ならチョキを、5,6ならパーを発生させる関数sysjanを作成せよ。(sysjanはコンピュータが出す拳)
で定義されてる
> JPON sysjan(int sai)
がコントロールしてるんだけど、まず今回、ここの定義が間違ってます。
> return ((JPON)0);
って定義したでしょ?
って事は毎回0しか返さなく、って事は、列挙体JPONの定義により毎回グーしか出してません。そしてその上のswitch文での判定が全く役に立ってない無駄な処理になっている。
まず、そのreturn ((JPON)0);を消す。
そして、
switch (sai) {
case 1: pon = Gu; break;
case 2: pon = Gu; break;
case 3: pon = Choki; break;
case 4: pon = Choki; break;
case 5: pon = Pa; break;
case 6: pon = Pa; break;
}
って書いてるけど、多分switch文とbreak文の関係がまだキチンと分かってないんじゃないかしらん。
ぶっちゃけ、ここで直接returnしちまって構わない。breakはswitch文から脱出するんだけど、returnは大枠の関数自体から脱出するんで、ここでreturnを使っても良いです。っつーか、手を返すのがこの関数の目的なので。
従って、
switch(sai) {
case 1: case 2: return Gu;
case 3: case 4: return Choki;
default: return Pa;
}
って書いちゃって構わない。ここでreturnしておけば関数がJPONで定義された値を返して、関数sysjan「自体から」脱出してくれます。
そして変数ponなんざ用意しないで良いです。従って代入も要りません。
もう一つ。ここで定義されてる仮引数saiな何なのか、と言う事。ここに手の基となる「数値」が入る、ってのが
> ~6のサイの目を引数で受け取り、目が1,2ならグーを、3,4ならチョキを、5,6ならパーを発生させる関数sysjanを作成せよ。
の要求なんだけど、関数saikoroの定義がおかしい。
ここも最後に
> return(0);
となってるけど、「関数が全部return(0)で終わる」ワケではない。これやっちゃうとどんな計算しようとも「0を返す」ので計算が無駄になっちゃう。main関数でのreturn(0)と意味が違うので、returnの通常での使い方を知ってください。
ここは、
return rand()%6+1;
が正しい。計算結果をそのまま返してください。じゃないと他の関数(この場合はsysjan)で結果を受け取れない。そして、ここでも変数saiは全く必要ないです。
C言語だと・・・結構な確率で「何でもかんでも変数用意して代入する」と言うような形式薦める本とか、まぁ、そういう「書法」を推薦する場合が多いと思うんですが、必要ない場合はやらんで良いです。main関数内でも
> int sai;
して
> sai = saikoro();
とかしてるけど、ぶっちゃけ、
sysken = sysjan(saikoro());
しちゃって大丈夫です。これならsaikoroの返り値がsysjanの引数になって、そしてsysjanの返り値がsyskenに代入されてる、って一発で分かります。
変数は「使い回しをする」前提で必要になるもので、一回こっきりしか使わない(この場合、変数saiが登場するのはここだけ、です)場合はわざわざ変数を用意する必要はないです。むしろ関数に関数の結果をそのまま手渡した方がコード上は明解だと思います・・・・まぁ、人によってはそう感じないかもしれませんがね。
回答ありがとうございました。
少し修正を加えて上手いこといきました。
グーを3回連続で出してくることはありますが、ちゃんと他の手も出すようになりました。
No.3
- 回答日時:
int saikoro(void) {
int sai;
srand((unsigned)time(NULL));
sai =rand()%6+1;
return(0);
}
の、returnしている 0 は、一体何を意味しているのか、考えましょう。
あなたが書いたのですよね?何のつもりで書いたかを思い出しましょう。
そもそもsaikoroという関数の機能はどういうつもりだったのでしょうか?思い出しましょう。
関数sysjanも同様。
全く別のレベルの話として、
srand((unsigned)time(NULL));
は、プログラムの最初で一度だけ実行します。mainの先頭に移動しましょう。
No.2
- 回答日時:
> int saikoro(void) {
> int sai;
> srand((unsigned)time(NULL));
> sai =rand()%6+1;
> return(0);
> }
最後にreturn(0);で、必ず0を返すようになっている。
return(sai);
とすべき。
> JPON sysjan(int sai)
> {
> int pon;
>
> switch (sai) {
> case 1: pon = Gu; break;
> case 2: pon = Gu; break;
> case 3: pon = Choki; break;
> case 4: pon = Choki; break;
> case 5: pon = Pa; break;
> case 6: pon = Pa; break;
> }
>
> return ((JPON)0);
> }
ここも最後にreturn ((JPON)0);で、必ず0を返すようになっている。
No.1
- 回答日時:
> C26812 列挙型 'janken' は対象範囲外です。
'enum' (Enum.3) より 'enum class' を優先します。> C6001 初期化されていないメモリ 'shoubukekka' を使用しています。 Project2
> C6031 戻り値が無視されました: 'scanf' Project2
原因を追究し警告が出ないよう処置しましょう。
> やはりこの警告のせいでグーしか出してくれないのでしょうか?
わかりません。
まず、グー、チョキ、パーを決める処理アルゴリズムは現状どうなっていて、それが適切な方法であるかどうかの判断があるでしょう。
次に、それが適切な方法である場合、アルゴリズム通りのソースコートになっておるかどうかの解析があるでしょう。
で。
それを設計・製造をされたご自身で行ってみられてのご質問なのかどうか・・・があります。
参考まで。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- C言語・C++・C# カードシャッフルのブログラムを使ってc言語でブラックジャックをしたい 2 2022/04/12 15:13
- C言語・C++・C# c言語の問題です 3 2023/01/10 16:15
- C言語・C++・C# プログラミングの授業の課題です 1 2023/01/17 22:15
- C言語・C++・C# c言語の問題の説明、各所ごとに 5 2023/07/26 11:03
- C言語・C++・C# C言語のエラーについて 2 2022/07/11 13:56
- C言語・C++・C# C言語 3 2022/11/09 13:27
- JavaScript jsで、switch文で書かれた分をif文にできませんか。 1 2022/07/28 15:10
- JavaScript switch文のswitch(n)の部分を複数の値にするか、if文に変えてほしいです。 1 2022/07/27 17:18
- C言語・C++・C# プログラムの時、フローチャートはどうなりますか?図でお願いします。 int main(void) { 1 2022/10/01 22:45
- C言語・C++・C# C言語で再起関数とポインタを用いて文字列反転をする方法がわかりません。 4 2023/04/29 20:32
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
10個出力で改行したいのですが...
-
printf で二進表示を行いたい。
-
C言語に関する質問です
-
コマンドラインに出力した文字...
-
*を使ったジグザグのラインをプ...
-
c言語
-
High-performance Embedded Wor...
-
scanfに文字が入力されたときに...
-
4の倍数を論理演算で表す。。
-
ホームページをC言語で作りたい...
-
8人分のテストの点数を入力し、...
-
改行について 1行に何個かづ...
-
2次方程式の解の表示
-
cshの文字列操作(0埋め)
-
C言語 (ラックナンバー)
-
C言語の数値入力
-
すごろくに使用するサイコロ
-
ガウスの消去法、後退代入について
-
c言語で2000年以降カレンダーを...
-
C言語での数字の花形表示
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
コンパイルエラーについて
-
printf で二進表示を行いたい。
-
コマンドラインに出力した文字...
-
(C言語)めちゃくちゃな値にな...
-
c言語でAからZまでを表示する...
-
printfの出力内の文字をdefine...
-
defineで定数が置き換えられな...
-
c言語で2000年以降カレンダーを...
-
cshの文字列操作(0埋め)
-
10個出力で改行したいのですが...
-
4の倍数を論理演算で表す。。
-
ホームページをC言語で作りたい...
-
コマンドプロンプトがすぐ消える
-
教えてください!!
-
Cプログラムについて
-
サイコロをふって、出た目のパ...
-
strcmp
-
じゃんけんゲームの応用
-
C言語でマウス入力(クリックや...
-
printfの有無で値が変化する
おすすめ情報