dポイントプレゼントキャンペーン実施中!

自分でじゃんけんゲームを作ってみたのですが、他の人のソースで
どういう風に組んでいるのか研究したいのでソースお願いします。
後、もっとこういう風にした方がいいとおもう所があればおねがいします。
<ソース>
#include<stdio.h>
#include<time.h>
#include<stdlib.h>

int main()
{
int i;
int n;

srand(time(NULL));
n=rand()%3;
printf("じゃんけんをします,0がグーで1がチョキで2がパーです\n");
printf("じゃんけんぽい!");
scanf("%d",&i);

if(i==0&&n==0){
printf("あいこです\n");
}
else if(i==0&&n==1){
printf("勝ちました\n");
}
else if(i==0&&n==2)
{
printf("負けました\n");
}

if(i==1&&n==0){
printf("負けました\n");
}
else if(i==1&&n==1){
printf("あいこです\n");
}
else if(i==1&&n==2)
{
printf("勝ちました\n");

}
if(i==2&&n==0){
printf("勝ちました\n");
}
else if(i==2&&n==1){
printf("負けました\n");
}

else if(i==2&&n==2){
printf("あいこです\n");
}
if(i>2)
{
printf("やりなおしてください\n");
}


return 0;
}

A 回答 (6件)

インデントに全角スペースを使ってます。

実際にコピーペーストする際には気をつけてください。
勝敗判定のコードをまとめて簡略化していますが、入力エラーチェックを強化したのでコード量は大して変わってません。

#include <stdio.h>
#include <stdlib.h>
#include <time.h>

#define GU 0
#define CHOKI 1
#define PA 2

#define MAX_STRLEN 256
int main()
{
 int i;
 int n;
 char input[MAX_STRLEN];
 char hand[][MAX_STRLEN] = {"グー", "チョキ", "パー"};

 srand(time(NULL));
 n=rand()%3;
 printf("じゃんけんぽい!\n");
 // 手を入力 -- 有効な数値が入るまで繰り返す
 while(1)
 {
  printf("あなたの手(グー:0 チョキ:1 パー:2):");
  fgets(input, MAX_STRLEN, stdin);
  if(sscanf(input, "%d", &i) < 1)
  {
   printf("数値を入力してください。\n");
  }else{
   if(i < GU || i > PA)
   {
    printf("0から2の範囲で入力してください。\n");
   }else{
    break;
   }
  }
 }
 // 自分の手と相手の手を表示
 printf("あなたの手:%s わたしの手:%s\n", hand[i], hand[n]);
 // 勝敗判定
 if(i == n)
 {
  printf("あいこです\n");
 }else{
  if((i + 1) % 3 == n)
  {
   printf("あなたの勝ちです\n");
  }else{
   printf("あなたの負けです\n");
  }
 }

 return 0;
}
    • good
    • 0
この回答へのお礼

配列を使ってみるのもいいですね。
while文で繰り返しやってみるのもいいですね。
ソースとても参考になったのでコンパイルさせていただきます。
1である限り繰り返しは考えつきませんでした。
面白いプログラミングですね。

お礼日時:2009/05/16 06:47

No.4です。


自分のを見直してみたら変なところがありました。

一つ目
> int pc, player; /* PC(私)とプレイヤー(あなた)の手 */
> enum { GU, CHOKI, PA, END };

どうせなら、
typedef enum { GU, CHOKI, PA, END } TE;
TE pc, player; /* PC(私)とプレイヤー(あなた)の手 */
とすべきでした。

二つ目
> const char *te[] = { "グー", "チョキ", "パー", "終了"};
> const char *message[] = { "負けました", "あいこです", "勝ちました" };

constにするなら
char const * const
ここまですべきかな?

三つ目
> if (player < 0 || player > END) {
> puts("やり直してください");
> continue;
> } else if (player == END)
> break;
do while文にした意味がない。
breakをcontinueに変えるか、while(1) {}でもよかった。
    • good
    • 0

#3のzwiです。


調子に乗って第2弾。マトリックス・タイプも既に出てますが勝率判定付きです。

#include<stdio.h>
#include<time.h>
#include<stdlib.h>

int main()
{
int i;
int n;
int hantei;
int allplay = 0;

//結果
static int hantei_count[3] = {0,0,0};
//勝ち負け
enum {
HANTEI_AIKO,
HANTEI_KACHI,
HANTEI_MAKE
};
//判定マトリックス
static int hantei_matrix[3][3] = {
HANTEI_AIKO, HANTEI_KACHI, HANTEI_MAKE,//i:0 n:0 i:0 n:1 i:0 n:2
HANTEI_MAKE, HANTEI_AIKO, HANTEI_KACHI,//i:1 n:0 i:1 n:1 i:1 n:2
HANTEI_KACHI, HANTEI_MAKE, HANTEI_AIKO//i:2 n:0 i:2 n:1 i:2 n:2
};
//判定表示用の文字列。
static char *hantei_str[3] = {
"あいこです",//HANTEI_AIKO,
"勝ちです", //HANTEI_KACHI,
"負けです" //HANTEI_MAKE
};
//表示用
static char *te[3] = {
"グー",// 0
"チョキ",// 1
"パー"// 2
};

srand(time(NULL));

while( 1 ) {
n=rand()%3;
printf("じゃんけんをします,0がグーで1がチョキで2がパーです。-1で終了します。\n");
printf("じゃんけんぽい!");
scanf("%d",&i);

//終了
if( i==-1 ) {
break;
}
//エラー判定
if( (i>2) || (i<0) ) {
printf("0,1,2を入力して、やりなおしてください\n");
continue;
}

//判定を得る。
hantei = hantei_matrix[i][n];
//結果表示
printf( "自分:%s(%d) コンピュータ:%s(%d) 判定は、%s。\n", te[i],i, te[n],n, hantei_str[hantei] );
//勝率の計算と表示
hantei_count[hantei]++;
allplay++;
printf( "あなたの勝率:%d%% あいこの確率:%d%%\n\n", hantei_count[HANTEI_KACHI]*100/allplay, hantei_count[HANTEI_AIKO]*100/allplay );

}

return 0;
}
    • good
    • 1
この回答へのお礼

いいプログラミングだと思います。
じっくり読ませていただいたのですが、配列の計算面白いです。
enumeを使うの思いつかなったです。
後は理解できます。
やはりwhile文を使って繰り返し判定を出すの必要だと思いました。

お礼日時:2009/05/16 07:01

配列を用いた方法が既に出ていますが、それ以外のところで参考になればと思いましたので、回答します



#include<stdio.h>
#include<time.h>
#include<stdlib.h>

int main()
{
int i;
int pc, player; /* PC(私)とプレイヤー(あなた)の手 */
enum { GU, CHOKI, PA, END };
const char *te[] = { "グー", "チョキ", "パー", "終了"};
typedef enum { LOOSE, EVEN, WIN} JUDGE;
const JUDGE result[3][3] = {
{EVEN, WIN, LOOSE},
{LOOSE, EVEN, WIN},
{WIN, LOOSE, EVEN}
}; /* プレイヤーの勝ち負けはresult[player][pc]で得られる */
const char *message[] = { "負けました", "あいこです", "勝ちました" };

srand((unsigned)time(NULL));

puts("じゃんけんをします");
for (i = 0; i < sizeof(te) / sizeof(te[0]); i++) {
printf("%dが%sで", i, te[i]);
}
puts("す");

do {
puts("じゃんけんぽい!");
scanf("%d",&player); /* 手抜き */

if (player < 0 || player > END) {
puts("やり直してください");
continue;
} else if (player == END)
break;

pc = (int)(rand() / (RAND_MAX + 1.0) * 3);

printf("あなたの手:%s\n", te[player]);
printf("私の手:%s\n", te[pc]);
puts(message[result[player][pc]]);
} while (player != END);

return 0;
}
    • good
    • 0
この回答へのお礼

構造体+配列わかりやすいです。
他の方で配列を使っている方もいたので、配列でまた作りなおしてみます。

お礼日時:2009/05/16 06:56

思いっきり配列を使ってみました。


少し仕組みも変わっていて遊ぶ人に分かりやすくしてあります。

#include<stdio.h>
#include<time.h>
#include<stdlib.h>

int main()
{
int i;
int n;
static char *hantei[3][3] = {
"あいこです",// i:0 n:0
"勝ちです", // i:0 n:1
"負けです", // i:0 n:2
"負けです", // i:1 n:0
"あいこです",// i:1 n:1
"勝ちです", // i:1 n:2
"勝ちです", // i:2 n:0
"負けです", // i:2 n:1
"あいこです" // i:2 n:2
};
static char *te[3] = {
"グー",// 0
"チョキ",// 1
"パー"// 2
};
srand(time(NULL));

while( 1 ) {
n=rand()%3;
printf("じゃんけんをします,0がグーで1がチョキで2がパーです。-1で終了します。\n");
printf("じゃんけんぽい!");
scanf("%d",&i);

if( i==-1 ) {
break;
}
if( (i>2) || (i<0) ) {
printf("0,1,2を入力して、やりなおしてください\n");
continue;
}

printf( "自分:%s(%d) コンピュータ:%s(%d) 判定は、%s。\n\n", te[i],i, te[n],n, hantei[i][n] );
}

return 0;
}
    • good
    • 0
この回答へのお礼

見てわかりやすいプログラムだと思いました。
配列を使うと、すっきりしますね。
コンパイルさせていただきます。

お礼日時:2009/05/16 06:52

>もっとこういう風にした方がいいとおもう所があればおねがいします。



printf("あいこです\n"); などの同じ文を繰り返し書いていますね。
勝ち負けの判定を関数にしましょう。

あと、「やりなおしてください」のメッセージと共に、
ユーザにプログラムの起動からやり直させるのはどうなんでしょう。
scanf("%d",&i); まで勝手に戻った方がよいのでは?
    • good
    • 0
この回答へのお礼

そうですね。勝ち負けの判定した方がいいですね。
やり直してくださいはwhile文を使って考えてみます。

お礼日時:2009/05/16 06:42

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!