自分でじゃんけんゲームを作ってみたのですが、他の人のソースで
どういう風に組んでいるのか研究したいのでソースお願いします。
後、もっとこういう風にした方がいいとおもう所があればおねがいします。
<ソース>
#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で質問しましょう!

このQ&Aを見た人はこんなQ&Aも見ています

このQ&Aを見た人が検索しているワード

このQ&Aと関連する良く見られている質問

Qアルバムに貼るかわいいイラストを探しています

アルバムに吹き出しや春夏秋冬それぞれのイラストなどを貼ってかわいくしたいのですが、学校のプリントで使われるようなイラストしか見つけられず・・・

どなたかかわいいイラスト知りませんか??

Aベストアンサー

Word・Excelなど、Microsoft Officeのテンプレートは、結構使えるものが多いですよ。

http://office.microsoft.com/ja-jp/templates/

Qif ( fp == NULL ){ を if ( fp == 0){ へ変更した場合

http://oshiete.goo.ne.jp/qa/8897349.html
 ですが
if ( fp == NULL ){ を
if ( fp == 0){
 fopen dekina と表示してくれるのでしょうか?
  試す環境がございませんので
 よろしくお願いいたします。

Aベストアンサー

>if ( fp == 0){
> fopen dekina と表示してくれるのでしょうか?

はい、表示してくれます。
NULLは、通常、(void*)0 の値が定義されていますので、実体は0と同じです。
しかし、NULLはポインターに対して定義されているのなので、
if ( fp == NULL) と書いたほうがよいでしょう。
一方、0は数値を表すので、
if (fp == 0)とは、書かないほうがよいでしょう。
int a;
が定義されていたとき、
if (a ==0) は、a(という数値を表す変数)の値が0か否かを判断するので、これでよいですが
if ( a== NULL) は、a(という数値を表す変数)の値がNULLか否かを判断するので、
違和感がありますから、使用しないほうが良いでしょう。

Qかわいい女の子のイラスト素材集(もしくは書いてくれる人)

かわいい女の子のイラストを探してます。

サンプルがなく説明しずらいですが、
風俗求人誌やバイト雑誌に使われているような、
かわいいアニメ調のイラストが希望です。

広告やwebに掲載したいので、
フリーでもかまいませんが、
イラストレータなどでのデータ化していればベストです。

ネットで素材集やリンク先をめぐってみましたが、
納得するものがなく。
イラスト書きを請け負っていただける方でもいいのですが・・・

イラスト集の入手方法や手配方法を、
なにかご存知の方いらっしゃればよろしくお願いいたします。

使用環境は、
WinXPで、
Illustrator 9・10 です。
前にそんなイラストレータ素材を見たことがあるので、
どこかにあるかとはおもうですが・・・

Aベストアンサー

こんにちは。

ここでは「人探し・求人」は残念ながら出来ないのですよ…。
私は、実際かけますが(プロです)、だからと言ってどうやって連絡取るのでしょう?個人同士での連絡は取れない規約です。

では、キャラクターの素材集のサイトをご紹介します。
http://www.dex.ne.jp/mantan/frame.cgi?rtn=3&tmptype=/mantan/search/std2_search_redirecter.jhtml&channel=10&db=d&ldtype=t&n_list=12&ctgptn=1&ctg=10171214

ここの素材は有名で、あちこちでよく使われています(女の子のイラストでなくても)。
会員になれば、DLし放題ですので、一度ごらんになってみてください。

参考URL:http://www.dex.ne.jp/mantan/frame.cgi?rtn=3&tmptype=/mantan/search/std2_search_redirecter.jhtml&channel=10&db=d&ldtype=t

こんにちは。

ここでは「人探し・求人」は残念ながら出来ないのですよ…。
私は、実際かけますが(プロです)、だからと言ってどうやって連絡取るのでしょう?個人同士での連絡は取れない規約です。

では、キャラクターの素材集のサイトをご紹介します。
http://www.dex.ne.jp/mantan/frame.cgi?rtn=3&tmptype=/mantan/search/std2_search_redirecter.jhtml&channel=10&db=d&ldtype=t&n_list=12&ctgptn=1&ctg=10171214

ここの素材は有名で、あちこちでよく使われています(女の子のイラストでなくても)...続きを読む

Qこのかわいいイラストの画家サンを教えてください☆

このかわいいイラストの画家サンを教えてください☆

Aベストアンサー

これわたしももってまーす^^
Brian Wildsmithさんですよ^^

Qif~else文の中にまたif~else文をいれるには。

 このプログラムを思うように実行したいのですが、できません。
コンパイルはできるのですが、警告が4つほど出て、結果も自分が思ってるのとは違います。
プログラムのどこを改善すべきか教えてください。
OSはWindows XPで、コンパイラはボーランドのフリーコンパイラを使用しています。
#include<stdio.h>
int main(){
int a,b,c,d;
printf("1か0を入力してください。\n");
scanf("%d",&a);
if(a=0)
{
printf("2か3を入力してください。\n");
scanf("%d",&b);
if(b=2){
printf("今まで合計は%dです。\n",a+b);
}
if(b=3){
printf("今まで合計は%dです。\n",a+b);
}
else {
printf("指定した数字を入力して下さい。\n");
}
}
else if(a=1)
{
printf("あなたは%dを入力しました。\n",a);
}
else
{
printf("指定した数字を入力してください。\n");
}
return 0;
}

 このプログラムを思うように実行したいのですが、できません。
コンパイルはできるのですが、警告が4つほど出て、結果も自分が思ってるのとは違います。
プログラムのどこを改善すべきか教えてください。
OSはWindows XPで、コンパイラはボーランドのフリーコンパイラを使用しています。
#include<stdio.h>
int main(){
int a,b,c,d;
printf("1か0を入力してください。\n");
scanf("%d",&a);
if(a=0)
{
printf("2か3を入力してください。\n");
scanf("%d",&b);
if(b=2){
printf("今まで合計...続きを読む

Aベストアンサー

No1に追加です。No6のかたが回答されていますが、せっかく途中まで書いたので参考までに回答させていただきます。矢印のある行が変更したところです。(矢印は入力しないでください)今は試せないんですけど多分これでできると思います。うまくいかなかったらすいません。あと字下げしても投稿する際に左寄せになってしまうようなので見づらいかもしれませんが許してください。もっといいやり方があると思いますけど参考にしてみてください。

#include<stdio.h>
int main(){
int a,b,c,d;
printf("1か0を入力してください。\n");
scanf("%d",&a);
if(a==0) ←
{
printf("2か3を入力してください。\n");
scanf("%d",&b);
if(b==2) ←
{
printf("今まで合計は%dです。\n",a+b);
}
else  ←
{ 
if(b==3) ←
{ 
printf("今まで合計は%dです。\n",a+b); 
}
else  
{
  printf("指定した数字を入力して下さい。\n"); 
}  ←この } は20行目のelseを終了する意味
}  ←この } は14行目のelseを終了する意味
}  ←この } は7行目のifを終了する意味

if(a==1) ←初めのifが当てはまらなかったり、初めのifの処理を終えるとここへ来る。
{
printf("あなたは%dを入力しました。\n",a);
}
else ←
{
printf("指定した数字を入力してください。\n");
}
return 0;
}

No1に追加です。No6のかたが回答されていますが、せっかく途中まで書いたので参考までに回答させていただきます。矢印のある行が変更したところです。(矢印は入力しないでください)今は試せないんですけど多分これでできると思います。うまくいかなかったらすいません。あと字下げしても投稿する際に左寄せになってしまうようなので見づらいかもしれませんが許してください。もっといいやり方があると思いますけど参考にしてみてください。

#include<stdio.h>
int main(){
int a,b,c,d;
printf("1か0を入...続きを読む

Qかわいいイラスト

入場券とか整理券とか商品引換券の一部に入れられるようなかわいいイラストのダウンロードできるサイトを教えてください。
ついでに、窓枠もあったら教えてください。

Aベストアンサー

んーーー。「かわいい」と思うかどーかは個人によって色々だから、ご自身で検索されたほうが手っ取り早いと思います☆

私、いいサイト知ってるんです~♪

良かったら、参考URLのサイトを1度覗いてみてください。「画像専門のサーチエンジン」なんですが、よくある素材屋リンク集みたいなのじゃなく、画像そのものを検索できるので、とっても重宝します。^^

ここだったら、yasichanさんが気に入る画風のイラストも、きっと見つかるんじゃないかと思います。

P.S:えと。「窓枠」っていうのは、意味が分かりませんでした。(自爆)

参考URL:http://www.ran.co.jp/Sozai/html/Sozai.html

Qtry{}catch(){}とデストラクタの関係を教えてください。

try-catchでメモリ確保を含むクラスをスローした場合、デストラクタはどの時点で働くのか、教えてください。たとえば、↓の使いかたは大丈夫でしょうか?

【1】
try{
 throw(CError(100, "エラー情報"));
}catch(CError& err){
 //ここでerrを参照しても問題ないのでしょうか?
}

【2】
try{
 CError err(100, "エラー情報");
 throw(err); // (1)
}catch(CError& err){
 //ここでerrを参照しても問題ないのでしょうか?
 //まだデストラクタはちゃんと動作するのでしょうか?
 //catchが呼び出し元のメンバであったりしても大丈夫なのでしょうか?
}

宜しくお願いします。

Aベストアンサー

【1】【2】どちらの場合も問題がありません。
コンパイラが必要に応じてerrオブジェクトのコピーを作成します。
デストラクタが呼び出されるタイミングはコンパイラに依存するところもあると思いますが、
例えばVC7.1では【2】は以下のように動作します。
(1) errオブジェクトのコンストラクタが呼び出される
(2) CErrorクラスのテンポラリオブジェクト(以下a)のコピーコンストラクタが呼び出される。
(3) errオブジェクトのデストラクタが呼び出される
(4) catch文まで到達
(5) aオブジェクトのデストラクタが呼び出される。

VC7.1では、【1】は以下のように動作します。
(1) errオブジェクトのコンストラクタが呼び出される
(2) catch文まで到達
(3) errオブジェクトのデストラクタが呼び出される。

コンパイラがオブジェクトのコピーを省略しているようです。

Q結婚式の招待状用のかわいいイラストのあるサイト

結婚式の招待状用のかわいいイラストのあるサイトしっているかた教えてください。

Aベストアンサー

http://www.maruai.jp/pri/
http://www.templatebank.com/

有名なところだったら
この辺でしょうか。。。

過去に似たような質問がいくつかあったので参考までにどうぞ。

参考URL:http://oshiete1.goo.ne.jp/kotaeru.php3?q=246467

Q{x = x>y ? x:y; return x;}

#include <iostream>
using namespace std;

inline int max(int x, int y){x = x>y ? x:y; return x;}

int main()
{
int num1, num2, ans;

cout << "2つの整数を入力して。\n";
cin >> num1 >> num2;

ans = max(num1, num2);

cout << "最大値は" << ans << "です。\n";

return 0;
}
の{x = x>y ? x:y; return x;}の部分の意味が解りません。

Aベストアンサー

inline int max(int x, int y){x = x>y ? x:y; return x;}
これを普通に関数で書くと

int max(int x, int y)
{
x = x>y ? x:y;
return x;
}

です。

x = 部分は右辺の結果が代入されます。これはわかりますよね。
x>y?x:y;
と書くと?より左にある条件式を判定し、その結果が真である場合は:で区切られた左側の値を、偽である場合は右の値を帰します。
x>yが真であればxを、偽であればyを返します。
それが、左辺値xに代入され、関数の戻り値として帰ります。

従って、2つの値をこの関数に入れると、大きいほうの値が帰ることになります。


人気Q&Aランキング

おすすめ情報