ポーカープログラム

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
o-guchi

ポーカープログラム

#1

投稿記事 by o-guchi » 9年前

大変恐縮ではありますが、期限が今度の日曜日までなので早めにお願いします。

トランプのポーカーゲームを作成せよ。という課題が出たのですが、ワンペア、ツーペア、スリーカード、フルハウス、フォーカードはswitch文を使って表示することはできたのですが、フラッシュ、ストレート、ストレートフラッシュ、ロイヤルストレートフラッシュ、ノーペアの表示がうまくできません。また、ペアについてもたまに2個役が出てしまうことがあります。

以下にポーカーの役判定の部分のプログラムを載せておきます。

rankは1~13、suitcodeは0をハート、1をダイヤ、2をクラブ、3をスペードを意味しています。
また、このコードの前にシャッフルしたカードの中から選んだ5枚のカードの数字を小さい順に並べ替えています。

コード:

n = 0;
for(i=0; i<4; i++)
{
	for(j=i+1; j<5; j++)
	{
		if(card[i].rank == card[j].rank)
		{
		  n++;
		  switch( n )
		  {    
		        case 1:        
			printf("ワンペア\n");        
			break;    
			case 2:        
			printf("ツーペア\n");        
			break;    
			case 3:        
			printf("スリーカード\n");        
			break;    
			case 4:        
			printf("フルハウス\n");        
			break;    
			case 6:        
			printf("フォーカード\n");        
			break;    
			default:
			printf("ノーペア\n");
			break;			
		}
	      }
        }
}

for(i = 0; i < 5; i++)
{
if(max < card[i].rank)
{
max = card[i].rank;
}
if(min > card[i].rank)
{
min = card[i].rank;
}
}

if(max - min <= 4)
{
if(card[0].suit_code == card[1].suit_code == card[2].suit_code == card[3].suit_code == card[4].suit_code)
{
printf("ストレートフラッシュ\n");
}
else
{
printf("ストレート\n");
}
}
if((card[0].suit_code) == (card[1].suit_code) == (card[2].suit_code) == (card[3].suit_code) == (card[4].suit_code))
{
printf("フラッシュ\n");
}
if((card[0].rank == 1) && (card[1].rank == 10) && (card[2].rank == 11) && (card[3].rank == 12) && (card[4].rank == 13))
{	
printf("ロイヤルストレートフラッシュ\n");
}
現状のプログラムを実行した結果も3パターン載せておきます。

D6 CJ DJ H5 D5
ワンペア ←これいらないですよね?
ツーペア

SK CA C9 H3 S5
フラッシュ ←フラッシュじゃなくて、ノーペアですよね?

D4 C10 C4 H8 S2
ワンペア
フラッシュ ←これいらないですよね?

お手数をおかけしますが、助けてください。お願いします。

アバター
みけCAT
記事: 6734
登録日時: 14年前
住所: 千葉県
連絡を取る:

Re: ポーカープログラム

#2

投稿記事 by みけCAT » 9年前

テストはしていません。

まずはインデントを整えるべきでしょう。
o-guchi さんが書きました:D6 CJ DJ H5 D5
ワンペア ←これいらないですよね?
ツーペア
switch文で判定して役を出力する処理をループの中ではなく、ループの外(32行目の下)にすると改善しそうです。
o-guchi さんが書きました:SK CA C9 H3 S5
フラッシュ ←フラッシュじゃなくて、ノーペアですよね?

D4 C10 C4 H8 S2
ワンペア
フラッシュ ←これいらないですよね?
C言語でA == B == Cという式は、A == B (AとBが等しければ1、そうでなければ0)とCが等しければ1、等しくなければ0になり、「AとBとCが全て等しい」という意味にはなりません。
5個の式を比較する場合も同様です。

また、役を判定したらすぐに出力するのではなく、一旦変数に格納し、判定処理が全て終わった後に出力するようにするといいでしょう。
こうすると、「どの役にも当てはまっていなかったらノーペア」という判定もできます。
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

o-guchi

Re: ポーカープログラム

#3

投稿記事 by o-guchi » 9年前

みけCATさん、
早速のご返答ありがとうございます。
switch文の方はずらしたら2重でペアが出ることはなくなりました。
ありがとうございます。

5個の式を比較する方はこんな感じでは駄目でしょうか?

コード:

if((card[0].suit_code == card[1].suit_code) && (card[1].suit_code == card[2].suit_code) && (card[2].suit_code == card[3].suit_code)&& (card[3].suit_code == card[4].suit_code))
2回実行したらこうなりました。

D9 CQ C3 H9 C9
スリーカード ←○?

H5 C6 D6 S5 C4
ツーペア
ストレート ←役が2個出るのは駄目ですし、そもそもこれはストレートなのでしょうか?

アバター
みけCAT
記事: 6734
登録日時: 14年前
住所: 千葉県
連絡を取る:

Re: ポーカープログラム

#4

投稿記事 by みけCAT » 9年前

o-guchi さんが書きました:5個の式を比較する方はこんな感じでは駄目でしょうか?

コード:

if((card[0].suit_code == card[1].suit_code) && (card[1].suit_code == card[2].suit_code) && (card[2].suit_code == card[3].suit_code)&& (card[3].suit_code == card[4].suit_code))
良さそうだと思います。
o-guchi さんが書きました:D9 CQ C3 H9 C9
スリーカード ←○?
合ってそうだと思います。
o-guchi さんが書きました:H5 C6 D6 S5 C4
ツーペア
ストレート ←役が2個出るのは駄目ですし、そもそもこれはストレートなのでしょうか?
違いますね。
単に範囲を見るのではなく、きちんと「数字が連なっている」(1ずつ増える)ことを確認しないとダメですね。
また、ロイヤルストレートフラッシュはストレートフラッシュの条件を満たすはずなのに、その判定が入っていないようです。

ポーカーの役の種類
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

o-guchi

Re: ポーカープログラム

#5

投稿記事 by o-guchi » 9年前

直せるところを直してみました。(今回はチェックをしてません)

あと、maxとminのところはいらないでしょうか?

コード:

n = 0;
for(i=0; i<4; i++)
{
	for(j=i+1; j<5; j++)
	{
		if(card[i].rank == card[j].rank)
		{
		n++;
		}
	}
}
switch( n )
{    
case 1:        
printf("ワンペア\n");        
break;    
case 2:        
printf("ツーペア\n");        
break;    
case 3:        
printf("スリーカード\n");        
break;    
case 4:        
printf("フルハウス\n");        
break;    
case 6:        
printf("フォーカード\n");        
break;    
default:
printf("ノーペア\n");
break;			
}
for(i = 0; i < 5; i++)
{
if(max < card[i].rank)
{
max = card[i].rank;
}
if(min > card[i].rank)
{
min = card[i].rank;
}
}
if(max - min <= 4)
{
if((card[0].suit_code == card[1].suit_code)
&& (card[1].suit_code == card[2].suit_code)
&& (card[2].suit_code == card[3].suit_code)
&& (card[3].suit_code == card[4].suit_code))
{
printf("ストレートフラッシュ\n");
}
else if((card[0].rank == 1)
&& (card[1].rank == 10)
&& (card[2].rank == 11)
&& (card[3].rank == 12)
&& (card[4].rank == 13))
{	
printf("ロイヤルストレートフラッシュ\n");
}
else if((card[1].rank == card[0].rank + 1)
&& (card[2].rank == card[1].rank + 1)
&& (card[3].rank == card[2].rank + 1)
&& (card[4].rank == card[3].rank + 1))
{
printf("ストレート\n");
}
}
if((card[0].suit_code == card[1].suit_code)
&& (card[1].suit_code == card[2].suit_code)
&& (card[2].suit_code == card[3].suit_code)
&& (card[3].suit_code == card[4].suit_code))
{
printf("フラッシュ\n");
}

アバター
みけCAT
記事: 6734
登録日時: 14年前
住所: 千葉県
連絡を取る:

Re: ポーカープログラム

#6

投稿記事 by みけCAT » 9年前

o-guchi さんが書きました:直せるところを直してみました。
どうしてインデントは直せないのですか?
o-guchi さんが書きました:(今回はチェックをしてません)
してください。
少なくとも、ロイヤルストレートフラッシュの判定が更に劣化しています。
o-guchi さんが書きました:あと、maxとminのところはいらないでしょうか?
使わないのであればいらないでしょう。
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

o-guchi

Re: ポーカープログラム

#7

投稿記事 by o-guchi » 9年前

インデントを直しました。

コード:

	n = 0;
	for(i=0; i<4; i++)
	{
		for(j=i+1; j<5; j++)
		{
			if(card[i].rank == card[j].rank)
			{
				n++;
			}
		}
	}

	switch( n )
	{    
		case 1:        
			printf("ワンペア\n");        
			break;    
		case 2:        
			printf("ツーペア\n");        
			break;    
		case 3:        
			printf("スリーカード\n");        
			break;    
		case 4:        
			printf("フルハウス\n");        
			break;    
		case 6:        
			printf("フォーカード\n");        
			break;    
		default:
			printf("ノーペア\n");
			break;			
	}

	if((card[0].suit_code == card[1].suit_code)
		&& (card[1].suit_code == card[2].suit_code)
		&& (card[2].suit_code == card[3].suit_code)
		&& (card[3].suit_code == card[4].suit_code))
	{
		printf("ストレートフラッシュ\n");
	}

	else if((card[0].rank == 1)
			 && (card[1].rank == 10)
			 && (card[2].rank == 11)
			 && (card[3].rank == 12)
			 && (card[4].rank == 13))
	{	
		printf("ロイヤルストレートフラッシュ\n");
	}

	else if((card[1].rank == card[0].rank + 1)
			 && (card[2].rank == card[1].rank + 1)
			 && (card[3].rank == card[2].rank + 1)
			 && (card[4].rank == card[3].rank + 1))
	{
		printf("ストレート\n");
	}

	if((card[0].suit_code == card[1].suit_code)
		&& (card[1].suit_code == card[2].suit_code)
		&& (card[2].suit_code == card[3].suit_code)
		&& (card[3].suit_code == card[4].suit_code))
	{
		printf("フラッシュ\n");
	}
複数チェックした中から正常なもの1つとおかしいもの2つを厳選しました。

D2 DJ D10 D3 DA
ノーペア
ストレートフラッシュ
フラッシュ

CQ C2 C6 C7 C5
ノーペア
ストレートフラッシュ
フラッシュ

S6 SA H10 C8 H5
ノーペア

ロイヤルストレートフラッシュはA 10 J Q Kのみなので、5枚のカードの番号が1 10 11 12 13の時みたいな感じで考えたのですが、、、

アバター
みけCAT
記事: 6734
登録日時: 14年前
住所: 千葉県
連絡を取る:

Re: ポーカープログラム

#8

投稿記事 by みけCAT » 9年前

みけCAT さんが書きました:また、役を判定したらすぐに出力するのではなく、一旦変数に格納し、判定処理が全て終わった後に出力するようにするといいでしょう。
こうすると、「どの役にも当てはまっていなかったらノーペア」という判定もできます。
という案は採用していただけないのですか?
1. 上の判定でとりあえず役を決める
2. 下の判定で、上の判定で出た役より強い役に当てはまっていたら更新する
3. その判定も終わったあとで結果を出力する
とするといいと思うのですが…
o-guchi さんが書きました:D2 DJ D10 D3 DA
ノーペア
ストレートフラッシュ
フラッシュ

CQ C2 C6 C7 C5
ノーペア
ストレートフラッシュ
フラッシュ
現状のコードでは、ストレートフラッシュの条件とフラッシュの条件が完全に同じになってしまっています。
これは明らかにおかしいですね。
最初は無理に条件式を減らそうとせず、1個のif文の中にそれぞれの役の条件を全部書いてもいいかもしれません。
その後で、まとめられる場所をまとめましょう。
o-guchi さんが書きました:ロイヤルストレートフラッシュはA 10 J Q Kのみなので、5枚のカードの番号が1 10 11 12 13の時みたいな感じで考えたのですが、、、
A 10 J Q Kであることはロイヤルストレートフラッシュであることの必要条件ではあるが、十分条件ではありません。
ロイヤルストレートフラッシュはストレートフラッシュの条件を満たすはずなのに、
現状のコードはストレートフラッシュではなくある条件を満たす場合にロイヤルストレートフラッシュと判定しているので、明らかにおかしいです。
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

o-guchi

Re: ポーカープログラム

#9

投稿記事 by o-guchi » 9年前

また、役を判定したらすぐに出力するのではなく、一旦変数に格納し、判定処理が全て終わった後に出力するようにするといいでしょう。
こうすると、「どの役にも当てはまっていなかったらノーペア」という判定もできます。

という案は採用していただけないのですか?
1. 上の判定でとりあえず役を決める
2. 下の判定で、上の判定で出た役より強い役に当てはまっていたら更新する
3. その判定も終わったあとで結果を出力する
とするといいと思うのですが…

この条件をもとに作り直したプログラムです。

コード:

	n = 0;
	for(i=0; i<4; i++)
	{
		for(j=i+1; j<5; j++)
		{
			if(card[i].rank == card[j].rank)
			{
				n++;
			}
		}
	}

	switch( n )
	{    
		case 1:        
			jadge = 1;       
			break;    
		case 2:        
			jadge  = 2;        
			break;    
		case 3:        
			jadge = 3;        
			break;    
		case 4:        
			jadge = 6;        
			break;    
		case 6:        
			jadge = 7;        
			break;    
	}

	if((card[0].suit_code == card[1].suit_code)
		&& (card[1].suit_code == card[2].suit_code)
		&& (card[2].suit_code == card[3].suit_code)
		&& (card[3].suit_code == card[4].suit_code))
	{
		jadge = 8;
	}

	if((card[0].rank == 1)
			 && (card[1].rank == 10)
			 && (card[2].rank == 11)
			 && (card[3].rank == 12)
			 && (card[4].rank == 13))
	{	
		jadge = 9;
	}

	else if((card[1].rank == card[0].rank + 1)
			 && (card[2].rank == card[1].rank + 1)
			 && (card[3].rank == card[2].rank + 1)
			 && (card[4].rank == card[3].rank + 1))
	{
		jadge = 4;
	}

	if((card[0].suit_code == card[1].suit_code)
		&& (card[1].suit_code == card[2].suit_code)
		&& (card[2].suit_code == card[3].suit_code)
		&& (card[3].suit_code == card[4].suit_code))
	{
		jadge = 5;
	}

	if(jadge_max > jadge)
	{
		jadge_max = jadge;
	}

	if(jadge_max == 9)
	{
		printf("ロイヤルストレートフラッシュ\n");
	}

	else if(jadge_max == 8)
	{
		printf("ストレートフラッシュ\n");
	}

	else if(jadge_max == 7)
	{
		printf("フォーカード\n");
	}

	else if(jadge_max == 6)
	{
		printf("フルハウス\n");
	}

	else if(jadge_max == 5)
	{
		printf("フラッシュ\n");
	}

	else if(jadge_max == 4)
	{
		printf("ストレート\n");
	}

	else if(jadge_max == 3)
	{
		printf("スリーカード\n");
	}

	else if(jadge_max == 2)
	{
		printf("ツーペア\n");
	}

	else if(jadge_max == 1)
	{
		printf("ワンペア\n");
	}

	else
	{
		printf("ノーペア\n");
	}
実行例
C8 CK H5 CA S2
ノーペア

HA D5 C2 D3 C4
ストレート

switch文にある役はかなりの確率で出てきますが、ストレートは50回ほど実行しないと出ませんでした。

ストレートフラッシュとストレートの条件が同じなのはわかりますが、
最初は無理に条件式を減らそうとせず、1個のif文の中にそれぞれの役の条件を全部書いてもいいかもしれません。
その後で、まとめられる場所をまとめましょう。
←このようにするやり方が分かりません。(ロイヤルストレートフラッシュの方も同じです)

o-guchi

Re: ポーカープログラム

#10

投稿記事 by o-guchi » 9年前

jadgeの初期値を0、jadge_maxの初期値を9にしています。

アバター
みけCAT
記事: 6734
登録日時: 14年前
住所: 千葉県
連絡を取る:

Re: ポーカープログラム

#11

投稿記事 by みけCAT » 9年前

引用部分は引用部分であるとわかりやすくしてください。
o-guchi さんが書きました:また、役を判定したらすぐに出力するのではなく、一旦変数に格納し、判定処理が全て終わった後に出力するようにするといいでしょう。
こうすると、「どの役にも当てはまっていなかったらノーペア」という判定もできます。

という案は採用していただけないのですか?
1. 上の判定でとりあえず役を決める
2. 下の判定で、上の判定で出た役より強い役に当てはまっていたら更新する
3. その判定も終わったあとで結果を出力する
とするといいと思うのですが…

この条件をもとに作り直したプログラムです。
すいません。
ジョーカーが無い場合、ストレートまたはフラッシュの場合は定義より同じ数字のカードは無いはずなので、上で判定している役は成立しないはずです。
したがって、「上の判定で出た役より強い役に当てはまっていたら」という判定をせずに下で更新すればいいでしょう。
また、現状全く役に立っていないjadge_maxは消して、直接jadgeの値をもとに出力すればいいでしょう。
オフトピック
judgeじゃないのか…
o-guchi さんが書きました:switch文にある役はかなりの確率で出てきますが、ストレートは50回ほど実行しないと出ませんでした。
乱数を入力しているのですか?
手動で任意の有効な入力をできるようにし、単体テストを行ってください。
o-guchi さんが書きました:ストレートフラッシュとストレートの条件が同じなのはわかりますが、
最初は無理に条件式を減らそうとせず、1個のif文の中にそれぞれの役の条件を全部書いてもいいかもしれません。
その後で、まとめられる場所をまとめましょう。
←このようにするやり方が分かりません。(ロイヤルストレートフラッシュの方も同じです)
(擬似コード)

コード:

if(数字が連なっている && 同種札が5枚 && 数字がA,K,Q,J,10) {
    役 = ロイヤルストレートフラッシュ;
} else if(数字が連なっている && 同種札が5枚) {
    役 = ストレートフラッシュ;
} else if(同種札が5枚) {
    役 = フラッシュ;
} else if(数字が連なっている) {
    役 = ストレート;
}
というロジックになるようにコードを編集し、コンパイルすればいいでしょう。
「数字が連なっている」「同種札が5枚」の判定は同じ処理を何度を書かず、判定結果をフラグ変数に入れるといいでしょう。
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

o-guchi

Re: ポーカープログラム

#12

投稿記事 by o-guchi » 9年前

このように変えたら、ロイヤルストレートフラッシュ以外は出るようになりましたが、以下のように指定してもフラッシュとされてしまいます。

コード:

		for(i = 0; i < 5; i++)
		{
			card[i].suit_code = '2';
		}

		card[0].rank = 1;
		card[1].rank = 10;
		card[2].rank = 11;
		card[3].rank = 12;
		card[4].rank = 13;

	if((card[1].rank == card[0].rank + 1)
		&& (card[2].rank == card[1].rank + 1)
		&& (card[3].rank == card[2].rank + 1)
		&& (card[4].rank == card[3].rank + 1)
			&& ((card[0].suit_code == card[1].suit_code)
			&& (card[1].suit_code == card[2].suit_code)
			&& (card[2].suit_code == card[3].suit_code)
			&& (card[3].suit_code == card[4].suit_code))
				&& ((card[0].rank == 1)
				&& (card[1].rank == 10)
				&& (card[2].rank == 11)
				&& (card[3].rank == 12)
				&& (card[4].rank == 13)))
	{
		jadge = 9;
	}

	else if((card[1].rank == card[0].rank + 1)
			&& (card[2].rank == card[1].rank + 1)
			&& (card[3].rank == card[2].rank + 1)
			&& (card[4].rank == card[3].rank + 1)
				&& ((card[0].suit_code == card[1].suit_code)
				&& (card[1].suit_code == card[2].suit_code)
				&& (card[2].suit_code == card[3].suit_code)
				&& (card[3].suit_code == card[4].suit_code)))
	{
		jadge = 8;
	}

	else if ((card[0].suit_code == card[1].suit_code)
			 && (card[1].suit_code == card[2].suit_code)
			 && (card[2].suit_code == card[3].suit_code)
			 && (card[3].suit_code == card[4].suit_code))
	{
		jadge = 5;
	}

	else if((card[1].rank == card[0].rank + 1)
		&& (card[2].rank == card[1].rank + 1)
		&& (card[3].rank == card[2].rank + 1)
		&& (card[4].rank == card[3].rank + 1))
	{
		jadge = 4;
	}

	if(jadge == 9)
	{
		printf("ロイヤルストレートフラッシュ\n");
	}

	else if(jadge == 8)
	{
		printf("ストレートフラッシュ\n");
	}

	else if(jadge == 7)
	{
		printf("フォーカード\n");
	}

	else if(jadge == 6)
	{
		printf("フルハウス\n");
	}

	else if(jadge == 5)
	{
		printf("フラッシュ\n");
	}

	else if(jadge == 4)
	{
		printf("ストレート\n");
	}

	else if(jadge == 3)
	{
		printf("スリーカード\n");
	}

	else if(jadge == 2)
	{
		printf("ツーペア\n");
	}

	else if(jadge == 1)
	{
		printf("ワンペア\n");
	}

	else
	{
		printf("ノーペア\n");
	}
jagdeはただのスペルミスです。

アバター
みけCAT
記事: 6734
登録日時: 14年前
住所: 千葉県
連絡を取る:

Re: ポーカープログラム

#13

投稿記事 by みけCAT » 9年前

ストレートとは?-近代ポーカー情報
ストレートの判定の時点でAが一番上になるケースがうまく判定されないバグがあり、そのせいで同じ条件を使ったロイヤルストレートフラッシュの判定もうまくいかないようですね。

そもそも、入力のカードの数字が昇順になっている保証はあるのですか?
オフトピック
なんで役の出力にswitch文とputs関数を使わないのだろう…?
(この場合switch文より配列の方がいいと思うけど)
(むしろこの程度のプログラムなら役を判定した時に数値じゃなくて役の名前を直接代入してもいいと思うけど)
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

o-guchi

Re: ポーカープログラム

#14

投稿記事 by o-guchi » 9年前

カードのrankは、昇順ソートをしてるので昇順になっているはずですが、、、

役を判定した時に直接役名を代入する方法がわからないですし、このプログラムとは別に複数回ポーカーをしてそれぞれの役の出現回数を出力するプログラムを作らないといけないので、数字の方がいいかと思いこうしました。

アバター
みけCAT
記事: 6734
登録日時: 14年前
住所: 千葉県
連絡を取る:

Re: ポーカープログラム

#15

投稿記事 by みけCAT » 9年前

o-guchi さんが書きました:カードのrankは、昇順ソートをしてるので昇順になっているはずですが、、、
ソートのプログラムが貼られていないですし、昇順ソートをしているなんていう前提も今まで書かれていなかったようなのでわかりませんでした。
ソートの処理がわからない以上、バグがある可能性も否定できませんね。
o-guchi さんが書きました:このプログラムとは別に複数回ポーカーをしてそれぞれの役の出現回数を出力するプログラムを作らないといけないので、数字の方がいいかと思いこうしました。
それなら名前を直接入れるより連番の方が良さそうですね。
マジックナンバーではなく、

コード:

enum {
  NO_PAIR = 0,
  ONE_PAIR,
  /* 省略 */
};
のような定義をして使うと良さそうですね。
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

アバター
usao
記事: 1889
登録日時: 12年前
連絡を取る:

Re: ポーカープログラム

#16

投稿記事 by usao » 9年前

オフトピック
ソートではなく,カードの数字のヒストグラムを作るとかすれば
判定が楽だったりしませんかね.

コード:

int Histogram[14] = { 0 }; //※[13]と[0]を共にA用にすればストレート系の判定が楽かな

for( int i=0; i<5; ++i )
{
  ++Histogram[  card[i].rank - 1  ];
}
Histogram[ 13 ] = Histogram[ 0 ];
オフトピック
これでどうだろう…?

コード:

#include <iostream>

enum SUIT{ S,H,D,C };

struct card
{
	SUIT suit;
	int rank;
};

//
void Judge( const card (&Cards)[5] )
{
	//フラッシュたり得るか?
	bool bFlush = true;
	for( int i=1; i<5; ++i )
	{
		if( Cards[i].suit != Cards[0].suit )
		{	bFlush = false;	break;	}
	}

	//カードのランク情報をあつめる
	unsigned int RankHist[15] = { 0 };	//どのランクが何枚あるか : [0]は使わない, [14]は[1]と同じ内容にする
	for( int i=0; i<5; ++i ){	++RankHist[Cards[i].rank];	}
	RankHist[14] = RankHist[1];

	unsigned int SameCardHist[6] = { 0 };	//[i] : 同じランクのカードがi枚あるパターンの個数
	for( int i=1; i<=13; ++i )
	{	++SameCardHist[ RankHist[i] ];	}

	//ストレートたり得るか?
	bool bStraight = false;
	if( SameCardHist[ 1 ] == 5 )	//ストレートである可能性があるのはカードのランクが全部ばらばらな時だけ
	{
		//ランク13のカードがあるかどうかでランク1のカードの扱いを変える
		const int RangeMin = ( RankHist[13]==0 ? 1 : 2 );
		const int RangeMax = ( RankHist[13]==0 ? 13 : 14 );
		//ランクの最大値と最小値との差が4ならばストレートな形
		int min_rank = 20, max_rank = 0;
		for( int i=RangeMin; i<=RangeMax; ++i )
		{
			if( RankHist[i]>0 )
			{
				if( i<min_rank )min_rank = i;
				if( max_rank<i )max_rank = i;
			}
		}
		bStraight = ( max_rank - min_rank == 4 );
	}

	//結果表示
	if( bStraight && bFlush )
	{
		if( RankHist[1]==1 && RankHist[2]==0 )std::cout << "ロイヤル";
		std::cout << "ストレートフラッシュ";
	}
	else if( SameCardHist[4]>0 ){	std::cout << "フォーカード";	}
	else if( SameCardHist[3] && SameCardHist[2] ){	std::cout << "フルハウス";	}
	else if( bFlush ){	std::cout << "フラッシュ";	}
	else if( bStraight ){	std::cout << "ストレート";	}
	else if( SameCardHist[3] ){	std::cout << "スリーカード";	}
	else if( SameCardHist[2]==2 ){	std::cout << "ツーペア";	}
	else if( SameCardHist[2]==1 ){	std::cout << "ワンペア";	}
	else {	std::cout << "ノーペア";	}
}

//
int main(void)
{
	const int N = 10;
	card Cards[N][5] = { 
		{ {H,1}, {H,12}, {H,11}, {H,13}, {H,10} },	//ロイヤルストレートフラッシュ
		{ {S,1}, {S,2}, {S,3}, {S,4}, {S,5} },	//ストレートフラッシュ
		{ {S,8}, {D,8}, {H,8}, {C,4}, {C,8} },	//フォーカード
		{ {D,1}, {S,1}, {H,1}, {H,11}, {S,11} },	//フルハウス
		{ {C,1}, {C,8}, {C,13}, {C,4}, {C,9} },	//フラッシュ
		{ {H,11}, {H,9}, {S,12}, {D,10}, {H,8} },	//ストレート
		{ {C,1}, {S,8}, {D,6}, {C,6}, {S,6} },	//スリーカード
		{ {C,1}, {D,1}, {H,13}, {C,4}, {C,13} },	//ツーペア
		{ {C,2}, {D,1}, {H,13}, {C,4}, {C,13} },	//ワンペア
		{ {C,2}, {D,1}, {H,13}, {C,4}, {C,12} }	//ノーペア
	};

	const char SuitChar[] = "SHDC";

	for( int sel=0; sel<N; ++sel )
	{
		for( int i=0; i<5; ++i )
		{	std::cout << SuitChar[Cards[sel][i].suit] << Cards[sel][i].rank << ' ';	}

		std::cout << "    ";
		Judge( Cards[sel] );
		std::cout << std::endl;
	}

	//
	std::cin.ignore();
	return 0;
}
最後に編集したユーザー usao on 2016年1月27日(水) 18:27 [ 編集 1 回目 ]

o-guchi

Re: ポーカープログラム

#17

投稿記事 by o-guchi » 9年前

みけCATさん
昇順ソートはこの位置でこんな感じで作りました。

コード:

		for(i = 0; i < 5; i++)
		{
			card[i].suit_code = '2';
		}

		card[0].rank = 1;
		card[1].rank = 10;
		card[2].rank = 11;
		card[3].rank = 12;
		card[4].rank = 13;


		for(i = 0; i < 5; i++)
		{
			for(j = i + 1; j < 5; j++)
			{
				if(card[i].rank > card[j].rank)
				{
					sort = card[i].rank;
					card[i].rank = card[j].rank;
					card[j].rank = sort;
				}
			}
		}
みけCAT さんが書きました: それなら名前を直接入れるより連番の方が良さそうですね。
マジックナンバーではなく、

コード:

enum {
NO_PAIR = 0,
ONE_PAIR,
/* 省略 */
};
のような定義をして使うと良さそうですね。
この定義はどこで使えばいいですか?また、この定義はどういう意味でしょうか。

アバター
みけCAT
記事: 6734
登録日時: 14年前
住所: 千葉県
連絡を取る:

Re: ポーカープログラム

#18

投稿記事 by みけCAT » 9年前

o-guchi さんが書きました:昇順ソートはこの位置でこんな感じで作りました。
選択ソートですね。
大丈夫でしょう。
o-guchi さんが書きました:この定義はどこで使えばいいですか?
役を表すために代入している数値を定義した識別子で置き換えればいいです。
定義はそれを使うより前に置きましょう。
o-guchi さんが書きました:また、この定義はどういう意味でしょうか。
NO_PAIRを0、ONE_PAIRをNO_PAIR+1 (=1)というint型の値をもつ定数とするという意味です。
この中でONE_PAIRの後に定義する識別子は、明示的に指定しなければそれぞれ直前の識別子の値+1というint型の値を持つ定数になります。
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

o-guchi

Re: ポーカープログラム

#19

投稿記事 by o-guchi » 9年前

こんな感じで直したのですが、エラーがでてしまいました。

コード:

	enum
	{
		no_pair = 0,
		one_pair,
		two_pair,
		three_card,
		straight,
		flash,
		fullhouse,
		four_card,
		straight_flash,
		royal_straight_flash
	};


	switch( n )
	{    
		case 1:        
			jadge = one_pair;       
			break;    
		case 2:        
			jadge = two_pair;        
			break;    
		case 3:        
			jadge = three_card;        
			break;    
		case 4:        
			jadge = fullhouse;        
			break;    
		case 6:        
			jadge = four_card;        
			break;    
	}

	if((card[1].rank == card[0].rank + 1)
		&& (card[2].rank == card[1].rank + 1)
		&& (card[3].rank == card[2].rank + 1)
		&& (card[4].rank == card[3].rank + 1)
			&& ((card[0].suit_code == card[1].suit_code)
			&& (card[1].suit_code == card[2].suit_code)
			&& (card[2].suit_code == card[3].suit_code)
			&& (card[3].suit_code == card[4].suit_code))
				&& ((card[0].rank == 1)
				&& (card[1].rank == 10)
				&& (card[2].rank == 11)
				&& (card[3].rank == 12)
				&& (card[4].rank == 13)))
	{
		jadge = royal_straight_flash;
	}

	else if((card[1].rank == card[0].rank + 1)
			&& (card[2].rank == card[1].rank + 1)
			&& (card[3].rank == card[2].rank + 1)
			&& (card[4].rank == card[3].rank + 1)
				&& ((card[0].suit_code == card[1].suit_code)
				&& (card[1].suit_code == card[2].suit_code)
				&& (card[2].suit_code == card[3].suit_code)
				&& (card[3].suit_code == card[4].suit_code)))
	{
		jadge = straight_flash;
	}

	else if ((card[0].suit_code == card[1].suit_code)
			 && (card[1].suit_code == card[2].suit_code)
			 && (card[2].suit_code == card[3].suit_code)
			 && (card[3].suit_code == card[4].suit_code))
	{
		jadge = flash;
	}

	else if((card[1].rank == card[0].rank + 1)
		&& (card[2].rank == card[1].rank + 1)
		&& (card[3].rank == card[2].rank + 1)
		&& (card[4].rank == card[3].rank + 1))
	{
		jadge = straight;
	}

	if(jadge == royal_straight_flash)
	{
		printf("ロイヤルストレートフラッシュ\n");
	}

	else if(jadge == straight_flash)
	{
		printf("ストレートフラッシュ\n");
	}

	else if(jadge == four_card)
	{
		printf("フォーカード\n");
	}

	else if(jadge == fullhouse)
	{
		printf("フルハウス\n");
	}

	else if(jadge == flash)
	{
		printf("フラッシュ\n");
	}

	else if(jadge == straight)
	{
		printf("ストレート\n");
	}

	else if(jadge == three_card)
	{
		printf("スリーカード\n");
	}

	else if(jadge == two_pair)
	{
		printf("ツーペア\n");
	}

	else if(jadge == one_pair)
	{
		printf("ワンペア\n");
	}

	else if(jadge == no_pair)
	{
		printf("ノーペア\n");
	}

アバター
みけCAT
記事: 6734
登録日時: 14年前
住所: 千葉県
連絡を取る:

Re: ポーカープログラム

#20

投稿記事 by みけCAT » 9年前

o-guchi さんが書きました:こんな感じで直したのですが、エラーがでてしまいました。
じゃあ直せばいいでしょう。
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

o-guchi

Re: ポーカープログラム

#21

投稿記事 by o-guchi » 9年前

みけCAT さんが書きました: じゃあ直せばいいでしょう。
enumを使わない状態に直せばいいということでしょうか?

o-guchi

Re: ポーカープログラム

#22

投稿記事 by o-guchi » 9年前

みけCAT さんが書きました: じゃあ直せばいいでしょう。
enumを使わない状態に直せばいいということでしょうか?

アバター
みけCAT
記事: 6734
登録日時: 14年前
住所: 千葉県
連絡を取る:

Re: ポーカープログラム

#23

投稿記事 by みけCAT » 9年前

o-guchi さんが書きました:enumを使わない状態に直せばいいということでしょうか?
いいえ。
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

o-guchi

Re: ポーカープログラム

#24

投稿記事 by o-guchi » 9年前

error C2143: 構文エラー : ';' が '型' の前にありません。
error C2143: 構文エラー : ';' が 'enum [tag]' の前にありません。
error C2065: 'one_pair' : 定義されていない識別子です。
error C2065: 'two_pair' : 定義されていない識別子です。
error C2065: 'three_card' : 定義されていない識別子です。
error C2065: 'fullhouse' : 定義されていない識別子です。
error C2065: 'four_card' : 定義されていない識別子です。
error C2065: 'royal_straight_flash' : 定義されていない識別子です。
error C2065: 'flash' : 定義されていない識別子です。
error C2065: 'straight' : 定義されていない識別子です。
error C2065: 'royal_straight_flash' : 定義されていない識別子です。
error C2065: 'straight_flash' : 定義されていない識別子です。
error C2065: 'four_card' : 定義されていない識別子です。
error C2065: 'fullhouse' : 定義されていない識別子です。
error C2065: 'straight' : 定義されていない識別子です。
error C2065: 'three_card' : 定義されていない識別子です。
error C2065: 'two_pair' : 定義されていない識別子です。
error C2065: 'one_pair' : 定義されていない識別子です。
error C2065: 'no_pair' : 定義されていない識別子です。

これだけのエラーが出てしまったのですが、どこをどう直したらよいでしょうか?

o-guchi

Re: ポーカープログラム

#25

投稿記事 by o-guchi » 9年前

error C2143: 構文エラー : ';' が '型' の前にありません。
error C2143: 構文エラー : ';' が 'enum [tag]' の前にありません。
error C2065: 'one_pair' : 定義されていない識別子です。
error C2065: 'two_pair' : 定義されていない識別子です。
error C2065: 'three_card' : 定義されていない識別子です。
error C2065: 'fullhouse' : 定義されていない識別子です。
error C2065: 'four_card' : 定義されていない識別子です。
error C2065: 'royal_straight_flash' : 定義されていない識別子です。
error C2065: 'flash' : 定義されていない識別子です。
error C2065: 'straight' : 定義されていない識別子です。
error C2065: 'royal_straight_flash' : 定義されていない識別子です。
error C2065: 'straight_flash' : 定義されていない識別子です。
error C2065: 'four_card' : 定義されていない識別子です。
error C2065: 'fullhouse' : 定義されていない識別子です。
error C2065: 'straight' : 定義されていない識別子です。
error C2065: 'three_card' : 定義されていない識別子です。
error C2065: 'two_pair' : 定義されていない識別子です。
error C2065: 'one_pair' : 定義されていない識別子です。
error C2065: 'no_pair' : 定義されていない識別子です。

これだけのエラーが出てしまったのですが、どこをどう直したらよいでしょうか?

アバター
みけCAT
記事: 6734
登録日時: 14年前
住所: 千葉県
連絡を取る:

Re: ポーカープログラム

#26

投稿記事 by みけCAT » 9年前

同じことを2回以上連続で書き込まないようにしてください。
o-guchi さんが書きました:error C2143: 構文エラー : ';' が '型' の前にありません。
error C2143: 構文エラー : ';' が 'enum [tag]' の前にありません。
多分どこかにセミコロンを足せばいいと思います。
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

o-guchi

Re: ポーカープログラム

#27

投稿記事 by o-guchi » 9年前

みけCAT さんが書きました:同じことを2回以上連続で書き込まないようにしてください。
すみません、送信時にエラーが起きてしまい、2回書き込んでいる状態になっていました。

どこにセミコロンをつけたらいいかわかりません。
つけ忘れなどは特に見当たらないのですが?

ちなみにエラーがさしている行は、enumの行と、enumの最後の};がある行です。

コード:

		for(i = 0; i < 5; i++)
		{
			card[i].suit_code = '2';
		}

		card[0].rank = 1;
		card[1].rank = 10;
		card[2].rank = 11;
		card[3].rank = 12;
		card[4].rank = 13;


		for(i = 0; i < 5; i++)
		{
			for(j = i + 1; j < 5; j++)
			{
				if(card[i].rank > card[j].rank)
				{
					sort = card[i].rank;
					card[i].rank = card[j].rank;
					card[j].rank = sort;
				}
			}
		}

	n = 0;
	for(i=0; i<4; i++)
	{
		for(j=i+1; j<5; j++)
		{
			if(card[i].rank == card[j].rank)
			{
				n++;
			}
		}
	}

	enum
	{
		no_pair,
		one_pair,
		two_pair,
		three_card,
		straight,
		flash,
		fullhouse,
		four_card,
		straight_flash,
		royal_straight_flash
	};

o-guchi

Re: ポーカープログラム

#28

投稿記事 by o-guchi » 9年前

コード貼り付け失敗したため、貼り直します。

コード:

		for(i = 0; i < 5; i++)
		{
			card[i].suit_code = '2';
		}

		card[0].rank = 1;
		card[1].rank = 10;
		card[2].rank = 11;
		card[3].rank = 12;
		card[4].rank = 13;


		for(i = 0; i < 5; i++)
		{
			for(j = i + 1; j < 5; j++)
			{
				if(card[i].rank > card[j].rank)
				{
					sort = card[i].rank;
					card[i].rank = card[j].rank;
					card[j].rank = sort;
				}
			}
		}

	n = 0;
	for(i=0; i<4; i++)
	{
		for(j=i+1; j<5; j++)
		{
			if(card[i].rank == card[j].rank)
			{
				n++;
			}
		}
	}

	enum
	{
		no_pair,
		one_pair,
		two_pair,
		three_card,
		straight,
		flash,
		fullhouse,
		four_card,
		straight_flash,
		royal_straight_flash
	};

アバター
みけCAT
記事: 6734
登録日時: 14年前
住所: 千葉県
連絡を取る:

Re: ポーカープログラム

#29

投稿記事 by みけCAT » 9年前

o-guchi さんが書きました:どこにセミコロンをつけたらいいかわかりません。
つけ忘れなどは特に見当たらないのですが?
問題は見当たらないですね。
enumの宣言の位置を変数宣言と同じ場所にしてみてください。
o-guchi さんが書きました:昇順ソートはこの位置でこんな感じで作りました。

コード:

		for(i = 0; i < 5; i++)
		{
			card[i].suit_code = '2';
		}

		card[0].rank = 1;
		card[1].rank = 10;
		card[2].rank = 11;
		card[3].rank = 12;
		card[4].rank = 13;


		for(i = 0; i < 5; i++)
		{
			for(j = i + 1; j < 5; j++)
			{
				if(card[i].rank > card[j].rank)
				{
					sort = card[i].rank;
					card[i].rank = card[j].rank;
					card[j].rank = sort;
				}
			}
		}
申し訳ありません、バグを見落としていました。
このプログラムはsuit_codeメンバや、もしあればその他のrank以外のメンバが交換されないので良くないですね。
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

o-guchi

Re: ポーカープログラム

#30

投稿記事 by o-guchi » 9年前

みけCAT さんが書きました: 問題は見当たらないですね。
enumの宣言の位置を変数宣言と同じ場所にしてみてください。
変数宣言とenumを同じ場所にしたところ、エラーが消えました。
ありがとうございます。

ソートの所はこんな感じに書き換えたら以下の結果になりました。

コード:

		for(i = 0; i < 5; i++)
		{
			card[i].suit_code = '2';
		}

		card[0].rank = 1;
		card[1].rank = 10;
		card[2].rank = 11;
		card[3].rank = 12;
		card[4].rank = 13;

	n = 0;
	for(i=0; i<4; i++)
	{
		for(j=i+1; j<5; j++)
		{
			if(card[i].rank == card[j].rank)
			{
				n++;
			}
		}
	}

	switch( n )
	{    
		case 1:        
			jadge = one_pair;       
			break;    
		case 2:        
			jadge = two_pair;        
			break;    
		case 3:        
			jadge = three_card;        
			break;    
		case 4:        
			jadge = fullhouse;        
			break;    
		case 6:        
			jadge = four_card;        
			break;    
	}

	if((card[1].rank == card[0].rank + 1)
		&& (card[2].rank == card[1].rank + 1)
		&& (card[3].rank == card[2].rank + 1)
		&& (card[4].rank == card[3].rank + 1)
			&& ((card[0].suit_code == card[1].suit_code)
			&& (card[1].suit_code == card[2].suit_code)
			&& (card[2].suit_code == card[3].suit_code)
			&& (card[3].suit_code == card[4].suit_code))
				&& ((card[0].rank == 1)
				&& (card[1].rank == 10)
				&& (card[2].rank == 11)
				&& (card[3].rank == 12)
				&& (card[4].rank == 13)))
	{
		jadge = royal_straight_flash;
	}

	else if((card[1].rank == card[0].rank + 1)
			&& (card[2].rank == card[1].rank + 1)
			&& (card[3].rank == card[2].rank + 1)
			&& (card[4].rank == card[3].rank + 1)
				&& ((card[0].suit_code == card[1].suit_code)
				&& (card[1].suit_code == card[2].suit_code)
				&& (card[2].suit_code == card[3].suit_code)
				&& (card[3].suit_code == card[4].suit_code)))
	{
		jadge = straight_flash;
	}

	else if ((card[0].suit_code == card[1].suit_code)
			 && (card[1].suit_code == card[2].suit_code)
			 && (card[2].suit_code == card[3].suit_code)
			 && (card[3].suit_code == card[4].suit_code))
	{
		jadge = flash;
	}

	else if((card[1].rank == card[0].rank + 1)
		&& (card[2].rank == card[1].rank + 1)
		&& (card[3].rank == card[2].rank + 1)
		&& (card[4].rank == card[3].rank + 1))
	{
		jadge = straight;
	}

	if(jadge == royal_straight_flash)
	{
		printf("ロイヤルストレートフラッシュ\n");
	}

	else if(jadge == straight_flash)
	{
		printf("ストレートフラッシュ\n");
	}

	else if(jadge == four_card)
	{
		printf("フォーカード\n");
	}

	else if(jadge == fullhouse)
	{
		printf("フルハウス\n");
	}

	else if(jadge == flash)
	{
		printf("フラッシュ\n");
	}

	else if(jadge == straight)
	{
		printf("ストレート\n");
	}

	else if(jadge == three_card)
	{
		printf("スリーカード\n");
	}

	else if(jadge == two_pair)
	{
		printf("ツーペア\n");
	}

	else if(jadge == one_pair)
	{
		printf("ワンペア\n");
	}

	else if(jadge == no_pair)
	{
		printf("ノーペア\n");
	}
H2 S8 D2 DA D4
フラッシュ

コード上で設定したsuit_codeは役判定では反映されていますが、ランクの方は反映されてないため、何回やってもフラッシュとなってしまうようです。
また、カードの表示の方はこのコードの前にprintfで出力してしまっているので、結果上はこのようになっていますが、プログラム上では
CA C10 CJ CQ CK
となるはずなのですがうまくできません。

今回は確認のためにわざとロイヤルストレートフラッシュが出るように改変していますが、実際のポーカープログラムとしてはこれで完成なのでしょうか?

アバター
みけCAT
記事: 6734
登録日時: 14年前
住所: 千葉県
連絡を取る:

Re: ポーカープログラム

#31

投稿記事 by みけCAT » 9年前

o-guchi さんが書きました:ソートの所はこんな感じに書き換えたら以下の結果になりました。
ソートの処理を消したということですか?
o-guchi さんが書きました:コード上で設定したsuit_codeは役判定では反映されていますが、ランクの方は反映されてないため、何回やってもフラッシュとなってしまうようです。
本当に反映されていないのですか?
きちんとデバッガや設定するランクを変えてみるなどの方法で反映されていないことを確認しましたか?
o-guchi さんが書きました:また、カードの表示の方はこのコードの前にprintfで出力してしまっているので、結果上はこのようになっていますが、プログラム上では
CA C10 CJ CQ CK
となるはずなのですがうまくできません。
「うまくできません」では意味がよくわかりません。
  • 何が
  • どうなって欲しいのに
  • どうなってしまう
のですか?
o-guchi さんが書きました:今回は確認のためにわざとロイヤルストレートフラッシュが出るように改変していますが、実際のポーカープログラムとしてはこれで完成なのでしょうか?
「実際のポーカープログラム」の仕様によるでしょう。
一口に「ポーカープログラム」と言っても、
  • ポーカーのゲーム全体をシミュレーションする
  • ポーカーの役を判定する
  • ポーカーでの戦略の決定を支援する
など、いろいろな候補があります。

また、No: 13で指摘したストレートの判定のバグが直っていないようですが、
ここで扱っているのが独自のルールの「ポーカー」なのであればこういう仕様でもいいかもしれません。
まあ、明らかに条件式が矛盾していてロイヤルストレートフラッシュが絶対に出ないという仕様は不自然だとは思いますが。

ところで、「わざとロイヤルストレートフラッシュが出るように改変」したはずなのにロイヤルストレートフラッシュが出ないというのは、明らかにおかしいのではないですか?
私の日本語、もしくは名状しがたい日本語のような文字列の解釈の方がおかしいのでしょうか?
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

o-guchi

Re: ポーカープログラム

#32

投稿記事 by o-guchi » 9年前

カード自体のシャッフルを消し、結果にロイヤルストレートフラッシュが必ず出るように変えてみました。

コード:

		for(i = 0; i < 5; i++)
		{
			card[i].suit_code = '2';
		}

		card[0].symbol[1] = 'A';
		card[0].symbol[2] = '\0';
		card[1].symbol[1] = '1';
		card[1].symbol[2] = '0';
		card[1].symbol[3] = '\0';
		card[2].symbol[1] = 'J';
		card[2].symbol[2] = '\0';
		card[3].symbol[1] = 'Q';
		card[3].symbol[2] = '\0';
		card[4].symbol[1] = 'K';
		card[4].symbol[2] = '\0';


		for(i = 0; i < 5; i++)
		{
			printf("%4s", card[i].symbol);
		}
		printf("\n");

	n = 0;
	for(i=0; i<4; i++)
	{
		for(j=i+1; j<5; j++)
		{
			if(card[i].rank == card[j].rank)
			{
				n++;
			}
		}
	}

	switch( n )
	{    
		case 1:        
			jadge = one_pair;       
			break;    
		case 2:        
			jadge = two_pair;        
			break;    
		case 3:        
			jadge = three_card;        
			break;    
		case 4:        
			jadge = fullhouse;        
			break;    
		case 6:        
			jadge = four_card;        
			break;    
	}

	if((card[1].rank == card[0].rank + 1)
		&& (card[2].rank == card[1].rank + 1)
		&& (card[3].rank == card[2].rank + 1)
		&& (card[4].rank == card[3].rank + 1)
			&& ((card[0].suit_code == card[1].suit_code)
			&& (card[1].suit_code == card[2].suit_code)
			&& (card[2].suit_code == card[3].suit_code)
			&& (card[3].suit_code == card[4].suit_code))
				&& ((card[0].rank == 1)
				&& (card[1].rank == 10)
				&& (card[2].rank == 11)
				&& (card[3].rank == 12)
				&& (card[4].rank == 13)))
	{
		jadge = royal_straight_flash;
	}

	else if((card[1].rank == card[0].rank + 1)
			&& (card[2].rank == card[1].rank + 1)
			&& (card[3].rank == card[2].rank + 1)
			&& (card[4].rank == card[3].rank + 1)
				&& ((card[0].suit_code == card[1].suit_code)
				&& (card[1].suit_code == card[2].suit_code)
				&& (card[2].suit_code == card[3].suit_code)
				&& (card[3].suit_code == card[4].suit_code)))
	{
		jadge = straight_flash;
	}

	else if ((card[0].suit_code == card[1].suit_code)
			 && (card[1].suit_code == card[2].suit_code)
			 && (card[2].suit_code == card[3].suit_code)
			 && (card[3].suit_code == card[4].suit_code))
	{
		jadge = flash;
	}

	else if((card[1].rank == card[0].rank + 1)
		&& (card[2].rank == card[1].rank + 1)
		&& (card[3].rank == card[2].rank + 1)
		&& (card[4].rank == card[3].rank + 1))
	{
		jadge = straight;
	}

	if(jadge == royal_straight_flash)
	{
		printf("ロイヤルストレートフラッシュ\n");
	}

	else if(jadge == straight_flash)
	{
		printf("ストレートフラッシュ\n");
	}

	else if(jadge == four_card)
	{
		printf("フォーカード\n");
	}

	else if(jadge == fullhouse)
	{
		printf("フルハウス\n");
	}

	else if(jadge == flash)
	{
		printf("フラッシュ\n");
	}

	else if(jadge == straight)
	{
		printf("ストレート\n");
	}

	else if(jadge == three_card)
	{
		printf("スリーカード\n");
	}

	else if(jadge == two_pair)
	{
		printf("ツーペア\n");
	}

	else if(jadge == one_pair)
	{
		printf("ワンペア\n");
	}

	else if(jadge == no_pair)
	{
		printf("ノーペア\n");
	}
結果はこうなりました。

CA C10 CJ CQ CK
ストレートフラッシュ

カードの方はきちんとロイヤルストレートフラッシュとなるように出力できましたが、ストレートフラッシュとなってしまいました。

[quote="みけCAT" id=3,17652#postingbox,136396]
また、No: 13で指摘したストレートの判定のバグが直っていないようですが、
ここで扱っているのが独自のルールの「ポーカー」なのであればこういう仕様でもいいかもしれません。
まあ、明らかに条件式が矛盾していてロイヤルストレートフラッシュが絶対に出ないという仕様は不自然だとは思いますが。

ところで、「わざとロイヤルストレートフラッシュが出るように改変」したはずなのにロイヤルストレートフラッシュが出ないというのは、明らかにおかしいのではないですか?
[/quote]

ストレートの判定のバグはどうしたら直るのかを教えてほしいです。

独自のルールというか、単に5枚のカードによってポーカーの役を判定してそれを出力するというものなのですが、、、

明らかにおかしいからどうしたらその明らかにおかしいところが直るのかを教えてほしいです。

アバター
みけCAT
記事: 6734
登録日時: 14年前
住所: 千葉県
連絡を取る:

Re: ポーカープログラム

#33

投稿記事 by みけCAT » 9年前

o-guchi さんが書きました:ストレートの判定のバグはどうしたら直るのかを教えてほしいです。
適切にコードを修正してコンパイルすれば直ります。

↓自明な例

コード:

if(((card[1].rank == card[0].rank + 1)
		&& (card[2].rank == card[1].rank + 1)
		&& (card[3].rank == card[2].rank + 1)
		&& (card[4].rank == card[3].rank + 1))
		|| ((card[0].rank == 1)
			&& (card[1].rank == 10)
			&& (card[2].rank == 11)
			&& (card[3].rank == 12)
			&& (card[4].rank == 13)))
	{
		jadge = straight;
	}
この条件を使っている他の部分も同様に。
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

o-guchi

Re: ポーカープログラム

#34

投稿記事 by o-guchi » 9年前

こういうことでしょうか?

コード:

	if((card[1].rank == card[0].rank + 1)
		&& (card[2].rank == card[1].rank + 1)
		&& (card[3].rank == card[2].rank + 1)
		&& (card[4].rank == card[3].rank + 1)
			&& ((card[0].suit_code == card[1].suit_code)
			&& (card[1].suit_code == card[2].suit_code)
			&& (card[2].suit_code == card[3].suit_code)
			&& (card[3].suit_code == card[4].suit_code))
				&& ((card[0].rank == 1)
				&& (card[1].rank == 10)
				&& (card[2].rank == 11)
				&& (card[3].rank == 12)
				&& (card[4].rank == 13)))
	{
		jadge = royal_straight_flash;
	}

	else if(((card[0].suit_code == card[1].suit_code)
				&& (card[1].suit_code == card[2].suit_code)
				&& (card[2].suit_code == card[3].suit_code)
				&& (card[3].suit_code == card[4].suit_code))
					&& (card[1].rank == card[0].rank + 1)
					&& (card[2].rank == card[1].rank + 1)
					&& (card[3].rank == card[2].rank + 1)
					&& (card[4].rank == card[3].rank + 1)
					|| ((card[0].rank == 1)
							&& (card[1].rank == 10)
							&& (card[2].rank == 11)
							&& (card[3].rank == 12)
							&& (card[4].rank == 13)))

	{
		jadge = straight_flash;
	}

	else if ((card[0].suit_code == card[1].suit_code)
			 && (card[1].suit_code == card[2].suit_code)
			 && (card[2].suit_code == card[3].suit_code)
			 && (card[3].suit_code == card[4].suit_code))
	{
		jadge = flash;
	}

	else if(((card[1].rank == card[0].rank + 1)
		&& (card[2].rank == card[1].rank + 1)
		&& (card[3].rank == card[2].rank + 1)
		&& (card[4].rank == card[3].rank + 1))
		|| ((card[0].rank == 1)
				&& (card[1].rank == 10)
				&& (card[2].rank == 11)
				&& (card[3].rank == 12)
				&& (card[4].rank == 13)))

	{
		jadge = straight;
	}

	if(jadge == royal_straight_flash)
	{
		printf("ロイヤルストレートフラッシュ\n");
	}

	else if(jadge == straight_flash)
	{
		printf("ストレートフラッシュ\n");
	}

	else if(jadge == four_card)
	{
		printf("フォーカード\n");
	}

	else if(jadge == fullhouse)
	{
		printf("フルハウス\n");
	}

	else if(jadge == flash)
	{
		printf("フラッシュ\n");
	}

	else if(jadge == straight)
	{
		printf("ストレート\n");
	}

	else if(jadge == three_card)
	{
		printf("スリーカード\n");
	}

	else if(jadge == two_pair)
	{
		printf("ツーペア\n");
	}

	else if(jadge == one_pair)
	{
		printf("ワンペア\n");
	}

	else if(jadge == no_pair)
	{
		printf("ノーペア\n");
	}
この状態で実行しても結果は先程と変わりませんでした。

かずま

Re: ポーカープログラム

#35

投稿記事 by かずま » 9年前

判定を個別の関数にすれば、すっきりするのではありませんか?

コード:

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

typedef struct Card {
    int suit_code;  // 0 .. 3
    int rank;       // 1 .. 13
} Card;

int flush(const Card card[5])
{
    int i;
    for (i = 1; i < 5 && card[i].suit_code == card[0].suit_code; i++) ;
    return i == 5;
}

int straight(const Card card[5])
{
    int i;
    for (i = 1; i < 5 && card[i-1].rank+1 == card[i].rank; i++) ; 
    return i == 5;
}

int four(const Card card[5])
{
    if (card[1].rank!=card[2].rank || card[2].rank!=card[3].rank) return 0;
    if (card[0].rank==card[1].rank || card[3].rank==card[4].rank) return 1;
    return 0;
}

int full_house(const Card card[5])
{
    if (card[0].rank != card[1].rank || card[3].rank != card[4].rank) return 0;
    if (card[1].rank == card[2].rank || card[2].rank == card[3].rank) return 1;
    return 0;
}

int try(const Card card[3])
{
    return card[0].rank == card[1].rank && card[1].rank == card[2].rank;
}

int three(const Card card[5])
{
    return try(card) || try(card + 1) || try(card + 2);
}

int pair(const Card card[2])
{
    return card[0].rank == card[1].rank;
}

int two_pair(const Card card[5])
{
    return pair(card) && pair(card+2) || pair(card) && pair(card+3)
        || pair(card+1) && pair(card+3);
}

int one_pair(const Card card[5])
{
    int i;
    for (i = 0; i < 4 && !pair(card+i); i++) ;
    return i < 4;
}

int royal(const Card card[5])
{
    return card[0].rank==1 && card[1].rank==10 && card[2].rank==11
        && card[3].rank==12 && card[4].rank==13 && flush(card);
}

void print(const Card card[5], const char *hand)
{
    int i;
    for (i = 0; i < 5; i++)
        printf("%c%.2s ", "SHCD"[card[i].suit_code],
            "0 A 2 3 4 5 6 7 8 9 10J Q K "+card[i].rank*2);
    puts(hand);
}

void judge(const Card card[5])
{
    if (royal(card))
        print(card, "ロイアルストレートフラッシュ");
    else if (straight(card) && flush(card))
        print(card, "ストレートフラッシュ");
    else if (four(card))
        print(card, "フォーカード");
    else if (full_house(card))
        print(card, "フルハウス");
    else if (flush(card))
        print(card, "フラッシュ");
    else if (straight(card))
        print(card, "ストレート");
    else if (three(card))
        print(card, "スリーカード");
    else if (two_pair(card))
        print(card, "ツーペア");
    else if (one_pair(card))
        print(card, "ワンペア");
    else
        print(card, "ノーペア");
}

int comp(const void *a, const void *b)
{
    return ((Card *)a)->rank - ((Card *)b)->rank;
}

int main(void)
{
    static Card card[10][5] = {
        { {0,10}, {0,11}, {0,12}, {0,13}, {0, 1} },  // royal straight flush
        { {1, 3}, {1, 4}, {1, 5}, {1, 6}, {1, 7} },  // straight flush
        { {0, 7}, {2, 5}, {1, 7}, {2, 7}, {3, 7} },  // four 
        { {0, 7}, {1, 4}, {1, 7}, {2, 4}, {3, 7} },  // full house
        { {3, 4}, {3, 9}, {3, 7}, {3, 8}, {3, 5} },  // flush
        { {0, 3}, {1, 6}, {2, 5}, {3, 4}, {0, 7} },  // straight
        { {1, 3}, {2, 4}, {0, 7}, {2, 7}, {3, 7} },  // three card
        { {0, 4}, {3, 4}, {1, 7}, {2, 8}, {3, 8} },  // two pairs
        { {1, 4}, {2, 5}, {0, 7}, {3, 7}, {0, 9} },  // one pairs
        { {0, 3}, {0, 4}, {1, 7}, {2, 8}, {3, 9} },  // no pairs
    };
    int i;
    for (i = 0; i < 10; i++) {
        qsort(card[i], 5, sizeof(Card), comp);
        judge(card[i]);
    }
    return 0;
}

アバター
みけCAT
記事: 6734
登録日時: 14年前
住所: 千葉県
連絡を取る:

Re: ポーカープログラム

#36

投稿記事 by みけCAT » 9年前

o-guchi さんが書きました:こういうことでしょうか?
  • 条件式の変更が反映されておらず、ロイヤルストレートフラッシュの判定が間違っています。
  • 演算子の優先順位の関係で、ストレートフラッシュの判定が間違っています。
みけCAT さんが書きました:「数字が連なっている」「同種札が5枚」の判定は同じ処理を何度を書かず、判定結果をフラグ変数に入れるといいでしょう。
この案を採用していただけていれば、こんなバグは出なかったかもしれないのに…。
かずま さんが書きました:

コード:

int straight(const Card card[5])
{
    int i;
    for (i = 1; i < 5 && card[i-1].rank+1 == card[i].rank; i++) ; 
    return i == 5;
}
これだと、

コード:

{ {1,10}, {0,11}, {0,12}, {0,13}, {0, 1} }
がストレートではなくノーペアと判定されてしまいますね。
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

o-guchi

Re: ポーカープログラム

#37

投稿記事 by o-guchi » 9年前

みけCAT さんが書きました: 条件式の変更が反映されておらず、ロイヤルストレートフラッシュの判定が間違っています。
演算子の優先順位の関係で、ストレートフラッシュの判定が間違っています。
どうやったらロイヤルストレートフラッシュとストレートフラッシュの判定が正しくできるのかをできればソースコードを使って教えてください。
みけCAT さんが書きました:「数字が連なっている」「同種札が5枚」の判定は同じ処理を何度を書かず、判定結果をフラグ変数に入れるといいでしょう。
この案を採用していただけていれば、こんなバグは出なかったかもしれないのに…。
判定結果をフラグ変数に入れるとはどういうことをすれば良いのでしょうか?やり方を教えてください。

アバター
みけCAT
記事: 6734
登録日時: 14年前
住所: 千葉県
連絡を取る:

Re: ポーカープログラム

#38

投稿記事 by みけCAT » 9年前

o-guchi さんが書きました:どうやったらロイヤルストレートフラッシュとストレートフラッシュの判定が正しくできるのかをできればソースコードを使って教えてください。
o-guchi さんが書きました:判定結果をフラグ変数に入れるとはどういうことをすれば良いのでしょうか?やり方を教えてください。

コード:

	/* フラグ変数 */
	int is_suit_onazi, is_rank_turanaru;

	/* 判定結果をフラグ変数に入れる */
	is_suit_onazi = (card[0].suit_code == card[1].suit_code)
		&& (card[1].suit_code == card[2].suit_code)
		&& (card[2].suit_code == card[3].suit_code)
		&& (card[3].suit_code == card[4].suit_code);
	is_rank_turanaru = ((card[1].rank == card[0].rank + 1)
		&& (card[2].rank == card[1].rank + 1)
		&& (card[3].rank == card[2].rank + 1)
		&& (card[4].rank == card[3].rank + 1))
		|| ((card[0].rank == 1)
			&& (card[1].rank == 10)
			&& (card[2].rank == 11)
			&& (card[3].rank == 12)
			&& (card[4].rank == 13));

	if(is_rank_turanaru
		&& is_suit_onazi
		&& ((card[0].rank == 1)
		&& (card[1].rank == 10)
		&& (card[2].rank == 11)
		&& (card[3].rank == 12)
		&& (card[4].rank == 13)))
	{
		jadge = royal_straight_flash;
	}

	else if(is_rank_turanaru
		&& is_suit_onazi)

	{
		jadge = straight_flash;
	}

	else if (is_suit_onazi)
	{
		jadge = flash;
	}

	else if(is_rank_turanaru)

	{
		jadge = straight;
	}
ついでにもう少しまとめると

コード:

	/* フラグ変数 */
	int is_suit_onazi, is_rank_turanaru;

	/* 判定結果をフラグ変数に入れる */
	is_suit_onazi = (card[0].suit_code == card[1].suit_code)
		&& (card[1].suit_code == card[2].suit_code)
		&& (card[2].suit_code == card[3].suit_code)
		&& (card[3].suit_code == card[4].suit_code);
	is_rank_turanaru = ((card[1].rank == card[0].rank + 1)
		&& (card[2].rank == card[1].rank + 1)
		&& (card[3].rank == card[2].rank + 1)
		&& (card[4].rank == card[3].rank + 1))
		|| ((card[0].rank == 1)
			&& (card[1].rank == 10)
			&& (card[2].rank == 11)
			&& (card[3].rank == 12)
			&& (card[4].rank == 13));

	if(is_rank_turanaru)
	{
		if(is_suit_onazi)
		{
			if((card[0].rank == 1)
				&& (card[1].rank == 10)
				&& (card[2].rank == 11)
				&& (card[3].rank == 12)
				&& (card[4].rank == 13))
			{
				jadge = royal_straight_flash;
			}
			else
			{
				jadge = straight_flash;
			}
		}
		else
		{
			jadge = straight;
		}
	}
	else if (is_suit_onazi)
	{
		jadge = flash;
	}
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

o-guchi

Re: ポーカープログラム

#39

投稿記事 by o-guchi » 9年前

先程教えていただいたソースコードを使ってプログラムを作ってみました。(ロイヤルストレートフラッシュなどの確認のために、100000回実行してみました。)

コード:

		printf("試行回数:");
		scanf("%d", &sikoukaisu);
		for(sikoucount = 0; sikoucount < sikoukaisu; sikoucount++)
		{
			srand((unsigned)time(NULL));

			for(i = 0; i < 10000; i++)
			{
				a = i % 52;
				b = rand()%52;

				while(a == b)
				{
					b = rand()%52;
				}

				temp = card[a];
				card[a] = card[b];
				card[b] = temp;
			}
			for(i = 0; i < 5; i++)
			{
				card[i].symbol;
			}

			for(i = 0; i < 5; i++)
			{
				for(j = i + 1; j < 5; j++)
				{
					if(card[i].rank > card[j].rank)
					{
						sort = card[i].rank;
						card[i].rank = card[j].rank;
						card[j].rank = sort;
					}
				}
			}
		n = 0;
		for(i=0; i<4; i++)
		{
			for(j=i+1; j<5; j++)
			{
				if(card[i].rank == card[j].rank)
				{
					n++;
				}
			}
		}
		switch( n )
		{    
			case 1:        
				jadge = one_pair;
				break;    
			case 2:        
				jadge = two_pair;
				break;    
			case 3:        
				jadge = three_card;
				break;    
			case 4:        
				jadge = fullhouse;
				break;    
			case 6:        
				jadge = four_card;
				break;    
		}
		is_suit_onazi = (card[0].suit_code == card[1].suit_code)
			&& (card[1].suit_code == card[2].suit_code)
			&& (card[2].suit_code == card[3].suit_code)
			&& (card[3].suit_code == card[4].suit_code);
		is_rank_turanaru = ((card[1].rank == card[0].rank + 1)
			&& (card[2].rank == card[1].rank + 1)
			&& (card[3].rank == card[2].rank + 1)
			&& (card[4].rank == card[3].rank + 1))
			|| ((card[0].rank == 1)
				&& (card[1].rank == 10)
				&& (card[2].rank == 11)
				&& (card[3].rank == 12)
				&& (card[4].rank == 13));
		if(is_rank_turanaru)
		{
			if(is_suit_onazi)
			{
				if((card[0].rank == 1)
					&& (card[1].rank == 10)
					&& (card[2].rank == 11)
					&& (card[3].rank == 12)
					&& (card[4].rank == 13))
				{
					jadge = royal_straight_flash;
				}
				else
				{
					jadge = straight_flash;
				}
			}
			else
			{
				jadge = straight;
			}
		}
		else if (is_suit_onazi)
		{
			jadge = flash;
		}
		if(jadge == royal_straight_flash)
		{
			royalstraightflashcount++;
		}
		else if(jadge == straight_flash)
		{
			straightflashcount++;
		}
		else if(jadge == four_card)
		{
			fourcardcount++;
		}
		else if(jadge == fullhouse)
		{
			fullhousecount++;
		}
		else if(jadge == flash)
		{
			flashcount++;
		}
		else if(jadge == straight)
		{
			straightcount++;
		}
		else if(jadge == three_card)
		{
			threecardcount++;
		}
		else if(jadge == two_pair)
		{
			twopaircount++;
		}
		else if(jadge == one_pair)
		{
			onepaircount++;
		}
		else if(jadge == 0)
		{
			nopaircount++;
		}
	}
	printf("出現頻度\n");
	printf("%d\n", nopaircount);
	printf("%d\n", onepaircount);
	printf("%d\n", twopaircount);
	printf("%d\n", threecardcount);
	printf("%d\n", fourcardcount);
	printf("%d\n", fullhousecount);
	printf("%d\n", flashcount);
	printf("%d\n", straightcount);
	printf("%d\n", straightflashcount);
	printf("%d\n", royalstraightflashcount);
実行結果です。

試行回数:100000
出現頻度
6
89764
5050
2814
13
75
927
1351
0
0

10万回もやっているのにノーペアが6回、ストレートフラッシュとロイヤルストレートフラッシュが共に0回というのは正常なのでしょうか?
もしくはプログラムがおかしいのでしょうか?プログラムがおかしいならば直してもらえませんか?

(nopaircountなどの役カウント変数は初期値0にしてあります。また、sikoukaisuとsikoucountも初期値0で、is_suit_onaziとis_rank_turanaruはほかの変数が定義されているところにまとめて書いてある状態です。)

(この後、もう一回実行してみたところ、ノーペア4回、ストレートフラッシュ0回、ロイヤルストレートフラッシュ2回となりました。)

かずま

Re: ポーカープログラム

#40

投稿記事 by かずま » 9年前

o-guchi さんが書きました: 10万回もやっているのにノーペアが6回、ストレートフラッシュとロイヤルストレートフラッシュが共に0回というのは正常なのでしょうか?
もしくはプログラムがおかしいのでしょうか?プログラムがおかしいならば直してもらえませんか?
どこを直したらよいか指摘できなくて申し訳ありませんが、
ノーペアがそんなに少ないことはありません。

コード:

#include <stdio.h>   // printf
#include <stdlib.h>  // srand, rand, qsort
#include <time.h>    // time
 
typedef struct {
    int suit_code;  // 0 .. 3
    int rank;       // 1 .. 13
} Card;
 
#define S(i) (card[i].suit_code)
#define R(i) (card[i].rank)

int flush(const Card card[5])
{
    return S(0)==S(1) && S(1)==S(2) && S(2)==S(3) && S(3)==S(4);
}
 
int straight(const Card card[5])
{
    return R(4) == R(3)+1 && R(3) == R(2)+1 && R(2) == R(1)+1
        && (R(1) == R(0)+1 || R(1) == R(0)+9);
}
 
int four(const Card card[5])
{
    if (R(1) != R(2) || R(2) != R(3)) return 0;
    return R(0) == R(1) || R(3) == R(4);
}
 
int full_house(const Card card[5])
{
    if (R(0) != R(1) || R(3) != R(4)) return 0;
    return R(1) == R(2) || R(2) == R(3);
}
 
int try(const Card card[3])
{
    return R(0) == R(1) && R(1) == R(2);
}
 
int three(const Card card[5])
{
    return try(card) || try(card + 1) || try(card + 2);
}
 
int pair(const Card card[2])
{
    return R(0) == R(1);
}
 
int two_pair(const Card card[5])
{
    if (pair(card) && (pair(card+2) || pair(card+3))) return 1;
    return pair(card+1) && pair(card+3);
}
 
int one_pair(const Card card[5])
{
    return pair(card) || pair(card + 1) || pair(card + 2) || pair(card + 3);
}
 
int royal(const Card card[5])
{
    return R(0)==1 && R(4)==13 && straight(card) && flush(card);
}
 
void judge(const Card card[5], int count[10])
{
    if (royal(card))           count[0]++;
    else if (straight(card) && flush(card)) count[1]++;
    else if (four(card))       count[2]++;
    else if (full_house(card)) count[3]++;
    else if (flush(card))      count[4]++;
    else if (straight(card))   count[5]++;
    else if (three(card))      count[6]++;
    else if (two_pair(card))   count[7]++;
    else if (one_pair(card))   count[8]++;
    else                       count[9]++;
}
 
int comp(const void *a, const void *b)
{
    return ((Card *)a)->rank - ((Card *)b)->rank;
}

void shuffle(Card all[52])
{
    int i, j;
    Card t;
    for (i = 0; i < 52; i++)
        j = rand() % 52, t = all[i], all[i] = all[j], all[j] = t;
}
 
int main(void)
{
    int i, n = 1000000, count[10] = { 0 };
    Card all[52];
    static const char *hand[] = {
        "royal straight flush", "straight flush", "four card", "full house",
        "flush", "straight", "three card", "tow pair", "one pair", "no pair"
    };

    for (i = 0; i < 52; i++) {
        all[i].suit_code = i / 13;
        all[i].rank = i % 13 + 1;
    }
    srand(time(0));
    for (i = 0; i < n; i++) {
        Card card[5];
        shuffle(all);
        memcpy(card, all, sizeof card);
        qsort(card, 5, sizeof(Card), comp);
        judge(card, count);
    }
    for (i = 0; i < 10; i++)
        printf("%8d  %s\n", count[i], hand[i]);
    return 0;
}
実行結果

コード:

       2  royal straight flush
      13  straight flush
     232  four card
    1413  full house
    1958  flush
    3963  straight
   21182  three card
   47566  tow pair
  422719  one pair
  500952  no pair

アバター
みけCAT
記事: 6734
登録日時: 14年前
住所: 千葉県
連絡を取る:

Re: ポーカープログラム

#41

投稿記事 by みけCAT » 9年前

o-guchi さんが書きました:先程教えていただいたソースコードを使ってプログラムを作ってみました。
どうして完全なプログラムを貼らないのですか?
ページの容量が削減できるメリットは少なく、無駄にテストの手間が増えると思うのですが…
o-guchi さんが書きました:10万回もやっているのにノーペアが6回、ストレートフラッシュとロイヤルストレートフラッシュが共に0回というのは正常なのでしょうか?
それぞれの役の確率をもとに、カイ自乗検定かなんかで判断できるでしょう。
[search=google]ポーカー 確率[/search]
o-guchi さんが書きました:もしくはプログラムがおかしいのでしょうか?
とりあえずざっと見てわかる範囲では、
  • 各試行でjadgeを初期化するべきなのにしていない
  • 各試行で毎回srand((unsigned)time(NULL));を呼び出している
という点がおかしいですね。
o-guchi さんが書きました:プログラムがおかしいならば直してもらえませんか?
自分で直そうと努力してもらえませんか?
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

o-guchi

Re: ポーカープログラム

#42

投稿記事 by o-guchi » 9年前

みけCAT さんが書きました: とりあえずざっと見てわかる範囲では、
各試行でjadgeを初期化するべきなのにしていない
各試行で毎回srand((unsigned)time(NULL));を呼び出しているという点がおかしいですね。
これをもとに直してみましたが、うまくjadgeを初期化できません。

また、完全なソースコードを載せなかったのは、課題上ネット上にプログラムを載せることは禁止とされていたからです。

自力で直したくてもプログラミングの知識が足りず、直せなかったため、教えてほしいのです。

コード:

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <time.h>

typedef struct card
{ 
	int id; /* 通し番号(0-51) */ 
	int suit_code; /*0:ハート, 1:ダイヤ, 2:スペード, 3:クラブ*/ 
	int rank; /*カードの数字 1- 13*/ 
	char symbol[10]; /*  (例:"SA ","S10","SJ ","SQ ","SK ") */ 
}CARD;

int main(void)
{
	CARD card[52];
	int i, j, a, b, sort, n;
	int jadge = 0;
    int is_suit_onazi, is_rank_turanaru;
	int count0 = 0;
	int count1 = 0;
	int count2 = 0;
	int count3 = 0;
	int count4 = 0;
	int count5 = 0;
	int count6 = 0;
	int count7 = 0;
	int count8 = 0;
	int count9 = 0;
	int sikoucount = 0;
	int sikoukaisu = 0;
	CARD temp;

	enum
	{
		no_pair,
		one_pair,
		two_pair,
		three_card,
		straight,
		flash,
		fullhouse,
		four_card,
		straight_flash,
		royal_straight_flash
	};


	for(i = 0; i < 52; i++)
	{
		card[i].id = i;
	}

		for(i = 0; i < 13; i++)
		{
			card[i].suit_code = 0;
			card[i + 13].suit_code = 1;
			card[i + 26].suit_code = 2;
			card[i + 39].suit_code = 3;
		}

		for(i = 0; i < 13; i++)
		{
			card[i].rank = i + 1;
			card[i + 13].rank = i + 1;
			card[i + 26].rank = i + 1;
			card[i + 39].rank = i + 1;
		}

		for(i = 0; i < 52; i++)
		{
			switch(card[i].suit_code)
			{
				case 0:
					card[i].symbol[0] = 'S';
					break;

				case 1:
					card[i].symbol[0] = 'H';
					break;

				case 2:
					card[i].symbol[0] = 'D';
					break;
	
				case 3:
					card[i].symbol[0] = 'C';
					break;
			}
		}

		for(i = 0; i < 52; i++)
		{
			switch(card[i].rank)
			{
				case 1:
					card[i].symbol[1] = 'A';
					break;

				case 2:
					card[i].symbol[1] = '2';
					break;

				case 3:
					card[i].symbol[1] = '3';
					break;

				case 4:
					card[i].symbol[1] = '4';
					break;

				case 5:
					card[i].symbol[1] = '5';
					break;

				case 6:
					card[i].symbol[1] = '6';
					break;

				case 7:
					card[i].symbol[1] = '7';
					break;

				case 8:
					card[i].symbol[1] = '8';
					break;

				case 9:
					card[i].symbol[1] = '9';
					break;

				case 10:
					card[i].symbol[1] = '1';
					card[i].symbol[2] = '0';
					break;

				case 11:
					card[i].symbol[1] = 'J';
					break;

				case 12:
					card[i].symbol[1] = 'Q';
					break;

				case 13:
					card[i].symbol[1] = 'K';
					break;
			}

			if(card[i].rank != 10)
			{
				card[i].symbol[2] = '\0';
			}

			if(card[i].rank == 10)
			{
				card[i].symbol[3] = '\0';
			}
		}

		srand((unsigned)time(NULL));

		printf("試行回数:");
		scanf("%d", &sikoukaisu);

		for(sikoucount = 0; sikoucount < sikoukaisu; sikoucount++)
		{
			for(i = 0; i < 10000; i++)
			{
				a = i % 52;
				b = rand()%52;

				while(a == b)
				{
					b = rand()%52;
				}

				temp = card[a];
				card[a] = card[b];
				card[b] = temp;
			}

			for(i = 0; i < 5; i++)
			{
				card[i].symbol;
			}

			for(i = 0; i < 5; i++)
			{
				for(j = i + 1; j < 5; j++)
				{
					if(card[i].rank > card[j].rank)
					{
						sort = card[i].rank;
						card[i].rank = card[j].rank;
						card[j].rank = sort;
					}
				}
			}

		n = 0;
		for(i=0; i<4; i++)
		{
			for(j=i+1; j<5; j++)
			{
				if(card[i].rank == card[j].rank)
				{
					n++;
				}
			}
		}

		switch( n )
		{    
			case 1:        
				jadge = one_pair;
				break;    
			case 2:        
				jadge = two_pair;
				break;    
			case 3:        
				jadge = three_card;
				break;    
			case 4:        
				jadge = fullhouse;
				break;    
			case 6:        
				jadge = four_card;
				break;    
		}

		is_suit_onazi = (card[0].suit_code == card[1].suit_code)
			&& (card[1].suit_code == card[2].suit_code)
			&& (card[2].suit_code == card[3].suit_code)
			&& (card[3].suit_code == card[4].suit_code);
		is_rank_turanaru = ((card[1].rank == card[0].rank + 1)
			&& (card[2].rank == card[1].rank + 1)
			&& (card[3].rank == card[2].rank + 1)
			&& (card[4].rank == card[3].rank + 1))
			|| ((card[0].rank == 1)
				&& (card[1].rank == 10)
				&& (card[2].rank == 11)
				&& (card[3].rank == 12)
				&& (card[4].rank == 13));
 
		if(is_rank_turanaru)
		{
			if(is_suit_onazi)
			{
				if((card[0].rank == 1)
					&& (card[1].rank == 10)
					&& (card[2].rank == 11)
					&& (card[3].rank == 12)
					&& (card[4].rank == 13))
				{
					jadge = royal_straight_flash;
				}
				else
				{
					jadge = straight_flash;
				}
			}
			else
			{
				jadge = straight;
			}
		}
		else if (is_suit_onazi)
		{
			jadge = flash;
		}


		if(jadge == royal_straight_flash)
		{
			count9++;
		}

		else if(jadge == straight_flash)
		{
			count8++;
		}

		else if(jadge == four_card)
		{
			count7++;
		}

		else if(jadge == fullhouse)
		{
			count6++;
		}

		else if(jadge == flash)
		{
			count5++;
		}

		else if(jadge == straight)
		{
			count4++;
		}

		else if(jadge == three_card)
		{
			count3++;
		}

		else if(jadge == two_pair)
		{
			count2++;
		}

		else if(jadge == one_pair)
		{
			count1++;
		}

		else if(jadge == 0)
		{
			count0++;
		}
		jadge == 0;
	}

	printf("出現頻度\n");
	printf("%d\n", count0);
	printf("%d\n", count1);
	printf("%d\n", count2);
	printf("%d\n", count3);
	printf("%d\n", count7);
	printf("%d\n", count6);
	printf("%d\n", count5);
	printf("%d\n", count4);
	printf("%d\n", count8);
	printf("%d\n", count9);

	return 0;
}
[/count]

アバター
みけCAT
記事: 6734
登録日時: 14年前
住所: 千葉県
連絡を取る:

Re: ポーカープログラム

#43

投稿記事 by みけCAT » 9年前

修正前

コード:

		for(sikoucount = 0; sikoucount < sikoukaisu; sikoucount++)
		{

修正後

コード:

		for(sikoucount = 0; sikoucount < sikoukaisu; sikoucount++)
		{
			jadge = 0;
修正前

コード:

			for(i = 0; i < 5; i++)
			{
				for(j = i + 1; j < 5; j++)
				{
					if(card[i].rank > card[j].rank)
					{
						sort = card[i].rank;
						card[i].rank = card[j].rank;
						card[j].rank = sort;
					}
				}
			}

修正後

コード:

			for(i = 0; i < 5; i++)
			{
				for(j = i + 1; j < 5; j++)
				{
					if(card[i].rank > card[j].rank)
					{
						CARD temp = card[i];
						card[i] = card[j];
						card[j] = temp;
					}
				}
			}
オフトピック
実質何もしない文があるが、もううまく動けばいいや…
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

閉鎖

“C言語何でも質問掲示板” へ戻る