ポーカーで質問です。
Posted: 2010年6月16日(水) 21:02
知り合いがポーカー作ると勉強になるよ、教えてくれたのでポーカーのプログラムを作っています。
とりあえずジョーカーなし、交換なしでカードが出て、役を判定させるプログラムを作ったのですがうまく動作しません。(役を判定させるif文の中に入りません)
以下そのプログラムですが、プログラムを記載する前に注意点としていくつか述べておくと
①現状すべてmain関数の中に書いています。
(あとあと全体像ができてきたら、役を判定させる関数などは外部関数にする予定です。いまはとりあえず頭から書いています)
②長いプログラムを全部ここに乗せるのもあれなので、ワンペアの部分だけ取り出しています。
③カード5種類をp[j]=rand()%52としていますが、これだとカードがかぶるおそれがあるので、もしかぶった場合はやり直し、というプログラムを組んでいます。ただ、無限にやり直しをしてしまうと、プログラムが先に進まないので、2000回繰り返した場合(2000回連続で5種類のカードのうちいずれかが被った場合)自動的にプログラムが終了するようにしています。5種類取り出した場合、1回の試行で約0.18くらいの確率で数字がかぶってしまうので、2000回連続で数字がかぶる確率は(0.0324)^1000となりはほぼ0になるので、とりあえずはこれで放置しています。(計算は概算です。有効数字とか考えてないので、実際は結構異なると思います)以下プログラムです。
④役の判定は、カードを小さい順にソートをして、隣り合う数字をもとに判定しています。
---------------------
#include<stdio.h>
#include<stdlib.h>
#include<time.h>
typedef struct Poker{
int card[52];
char mark[52];
}Poker;
int main(void){
Poker num;
int i=0; //for文用
int j=0; //for文用
int k=0; //for文用
int l=0; //for文用
int m=0; //for文用
int n=0; //for文用
int tmp; //配列ソート用
int p[5]; //カード選択用
int max=1; //error防止用
int yaku=0; //カードの役ループ用
srand((unsigned)time(NULL));
for(i=0;i<13;i++){
num.card=i+1;
num.card[i+13]=i+1;
num.card[i+26]=i+1;
num.card[i+39]=i+1;
num.mark='s';
num.mark[i+13]='d';
num.mark[i+26]='h';
num.mark[i+39]='c';
}
for(j=0;j<5;j++){
p[j]=rand()%52;
max++; //for文無限回繰り返しを防ぐ
if(j==4){
if(p[0]==p[1]||p[0]==p[2]||p[0]==p[3]||p[0]==p[4]||p[1]==p[2]||p[1]==p[3]||p[1]==p[4]||p[2]==p[3]||p[2]==p[4]||p[3]==p[4]){
j=-1;//同じカードかあれば、j=0となりやりなおし(j=-1なのはループの最後にj++があるから)
}
}
if(max==10000)
break;
}
if(max!=10000){
for(k=0;k<5;k++){
printf("%c-%d\n",num.mark[p[k]],num.card[p[k]]);
}
for(l=0;l<4;l++){ //カードのソート
for(m=l;m<5;m++){
if((p[m]%13)<=(p[[/url]%13)){
tmp=p[m];
p[m]=p[[/url];
p[[/url]=tmp;
}
}
}//カードのソートを終了
if((yaku=0)&&(((p[0]%13)==(p[1]%13))||((p[1]%13)==(p[2]%13))||((p[2]%13)==(p[3]%13))||((p[3]%13)==(p[4]%13)))){
yaku=1;
printf("ワンペア\n");
}//ワンペア
} //if(max!=10000の終了)
return 0;
}
------------------------
質問としては
①なぜif文の中に入らないのか?
(あるいは入ってはいるが条件式などに誤りがある)
②はじめにカードを5種類だす際に、もっとうまいプログラムはないのか?(上のプログラムは無限ループを防止するための苦肉の策なので)
③5種類のカードがの中に同じものが含まれることが、そもそもずっと続くなどありえない(確率的にはありえるが、0に収束するので)無限ループを防止するプログラムなど書く必要がない?
他のプログラム等は全く見ないで挑戦していて、かなりへたくそなプログラムだとは思いますが、いろいろと教えてもらえるとうれしいです。
よろしくお願いいたします。
とりあえずジョーカーなし、交換なしでカードが出て、役を判定させるプログラムを作ったのですがうまく動作しません。(役を判定させるif文の中に入りません)
以下そのプログラムですが、プログラムを記載する前に注意点としていくつか述べておくと
①現状すべてmain関数の中に書いています。
(あとあと全体像ができてきたら、役を判定させる関数などは外部関数にする予定です。いまはとりあえず頭から書いています)
②長いプログラムを全部ここに乗せるのもあれなので、ワンペアの部分だけ取り出しています。
③カード5種類をp[j]=rand()%52としていますが、これだとカードがかぶるおそれがあるので、もしかぶった場合はやり直し、というプログラムを組んでいます。ただ、無限にやり直しをしてしまうと、プログラムが先に進まないので、2000回繰り返した場合(2000回連続で5種類のカードのうちいずれかが被った場合)自動的にプログラムが終了するようにしています。5種類取り出した場合、1回の試行で約0.18くらいの確率で数字がかぶってしまうので、2000回連続で数字がかぶる確率は(0.0324)^1000となりはほぼ0になるので、とりあえずはこれで放置しています。(計算は概算です。有効数字とか考えてないので、実際は結構異なると思います)以下プログラムです。
④役の判定は、カードを小さい順にソートをして、隣り合う数字をもとに判定しています。
---------------------
#include<stdio.h>
#include<stdlib.h>
#include<time.h>
typedef struct Poker{
int card[52];
char mark[52];
}Poker;
int main(void){
Poker num;
int i=0; //for文用
int j=0; //for文用
int k=0; //for文用
int l=0; //for文用
int m=0; //for文用
int n=0; //for文用
int tmp; //配列ソート用
int p[5]; //カード選択用
int max=1; //error防止用
int yaku=0; //カードの役ループ用
srand((unsigned)time(NULL));
for(i=0;i<13;i++){
num.card=i+1;
num.card[i+13]=i+1;
num.card[i+26]=i+1;
num.card[i+39]=i+1;
num.mark='s';
num.mark[i+13]='d';
num.mark[i+26]='h';
num.mark[i+39]='c';
}
for(j=0;j<5;j++){
p[j]=rand()%52;
max++; //for文無限回繰り返しを防ぐ
if(j==4){
if(p[0]==p[1]||p[0]==p[2]||p[0]==p[3]||p[0]==p[4]||p[1]==p[2]||p[1]==p[3]||p[1]==p[4]||p[2]==p[3]||p[2]==p[4]||p[3]==p[4]){
j=-1;//同じカードかあれば、j=0となりやりなおし(j=-1なのはループの最後にj++があるから)
}
}
if(max==10000)
break;
}
if(max!=10000){
for(k=0;k<5;k++){
printf("%c-%d\n",num.mark[p[k]],num.card[p[k]]);
}
for(l=0;l<4;l++){ //カードのソート
for(m=l;m<5;m++){
if((p[m]%13)<=(p[[/url]%13)){
tmp=p[m];
p[m]=p[[/url];
p[[/url]=tmp;
}
}
}//カードのソートを終了
if((yaku=0)&&(((p[0]%13)==(p[1]%13))||((p[1]%13)==(p[2]%13))||((p[2]%13)==(p[3]%13))||((p[3]%13)==(p[4]%13)))){
yaku=1;
printf("ワンペア\n");
}//ワンペア
} //if(max!=10000の終了)
return 0;
}
------------------------
質問としては
①なぜif文の中に入らないのか?
(あるいは入ってはいるが条件式などに誤りがある)
②はじめにカードを5種類だす際に、もっとうまいプログラムはないのか?(上のプログラムは無限ループを防止するための苦肉の策なので)
③5種類のカードがの中に同じものが含まれることが、そもそもずっと続くなどありえない(確率的にはありえるが、0に収束するので)無限ループを防止するプログラムなど書く必要がない?
他のプログラム等は全く見ないで挑戦していて、かなりへたくそなプログラムだとは思いますが、いろいろと教えてもらえるとうれしいです。
よろしくお願いいたします。