練習問題

Java【練習問題】~ポーカーの各役が出る確率を求める~

ここではポーカーで各役が出る確率を求めます。

 

ポーカーの役一覧

ポーカーの役はこちらです。

ロイヤルストレートフラッシュ
ストレートフラッシュ
フォーカード
フルハウス
フラッシュ
ストレート
スリーカード
ツーペア
ワンペア

上にいくほど強い役です。

これらの役が何%程度で出るのかを求めていきます。

 

ソースコード

import java.util.* ;

public class Poker {

public static void main(String[] args) {

Map<String, Integer> map = new HashMap<String, Integer>() ;

final int シミュレーション回数 = 1000000 ;

for( int i = 0 ; i < シミュレーション回数 ; ++i ) {

String 役 = ポーカーを1回実行() ;

map.put( 役, map.containsKey(役) ? map.get(役) + 1 : 1 ) ;

}

for( String 役 : map.keySet() ) {

System.out.printf( "%6.3f %% %s\n", 100.0 * map.get(役) / シミュレーション回数, 役 ) ;

}

}

public static String ポーカーを1回実行() {

カード[] カード = new カード [5] ;

トランプ トランプ = new トランプ() ;

for( int i=0 ; i<5 ; ++i )

カード[i] = トランプ.一枚取る() ;

return ポーカーの役判定.判定( カード ) ;

}

}

////////////////////

class トランプ {

ArrayList<カード> カード群 = new ArrayList<カード>() ;

トランプ() {

for( int i = 0 ; i < 52 ; ++i )

カード群.add( new カード( i ) ) ;

シャッフル() ;

}

public void シャッフル() { Collections.shuffle( カード群 ) ; }

public int 枚数() { return カード群.size() ; }

public カード 一枚取る() { return カード群.remove( 0 ) ; }

}

////////////////////

class カード {

private int ID ; // 0..51

private final String マーク[] = {"ハート","スペード","ダイヤ","クローバー"} ;

private final String 数字[] = {"0", "A","2","3","4","5","6","7","8","9","10","J","Q","K"} ;

// コンストラクタ

カード( int ID ) { this.ID = ID ; }

public int 数字を取得() { return ID % 13 + 1 ; }

public String マークを取得() { return マーク[ ID / 13 ] ; }

public String toString() { return マークを取得() + "の" + 数字[ 数字を取得() ] ; }

}

////////////////////

abstract class ポーカーの役判定 {

static String 判定( カード カード[] ) {

int[] X = 数字の集計( カード ) ;

if(ロイヤルストレートフラッシュの判定(カード)) return "ロイヤルストレートフラッシュ";

if(ストレートの判定(カード)) return フラッシュの判定(カード) ? "ストレートフラッシュ" : "ストレート";

if( X == 1 ) return "フォーカード" ;

if( X == 1 ) return X == 1 ? "フルハウス" : "スリーカード" ;

if(フラッシュの判定(カード)) return "フラッシュ";

if( X == 2 ) return "ツーペア" ;

if( X == 1 ) return "ワンペア" ;

return "役なし" ;

}

private static int[] 数字の集計( カード カード[] ) {

int[] 枚数 = new int[14] ;

int[] 集計 = new int[5] ;

for( カード c : カード ) ++枚数[ c.数字を取得() ] ;

for( int m : 枚数 ) ++集計[m] ;

return 集計 ;

}

private static boolean フラッシュの判定(カード カード[]) {

return

(カード[0].マークを取得() == カード.マークを取得()) &&

(カード[0].マークを取得() == カード.マークを取得()) &&

(カード[0].マークを取得() == カード.マークを取得()) &&

(カード[0].マークを取得() == カード.マークを取得()) ;

}

private static boolean ストレートの判定(カード カード[]) {

int[] X = new int[5] ;

for(int i=0; i<5; i++){

X[i] = カード[i].数字を取得() ;

}

for(int i=0; i<4; i++){

for(int j=0; j<4-i; j++){

if(X[j] > X[j+1]){

int temp=X[j];

X[j]=X[j+1];

X[j+1]=temp;

}

}

}

return

(X[0]==1 && X==10 && X==11 && X==12 && X==13) ||

(X == X[0]+1) &&

(X == X[0]+2) &&

(X == X[0]+3) &&

(X == X[0]+4);

}

private static boolean ロイヤルストレートフラッシュの判定(カード カード[]) {

int[] 枚数 =new int[14];

int[] 集計 =new int[5];

for( カード c : カード ) ++枚数[ c.数字を取得() ] ;

for( int m : 枚数 ) ++集計[m] ;

return

(フラッシュの判定(カード)==true) &&

(ストレートの判定(カード)==true) &&

(枚数[10]*枚数[11]*枚数[12]*枚数[13]*枚数==1);

}

}

 

スポンサーリンク


実行結果

C:\Users\Desktop\Java\jdk1.8.0_131\program>java Poker
42.175 % ワンペア
2.121 % スリーカード
0.000 % ロイヤルストレートフラッシュ
0.200 % フラッシュ
0.145 % フルハウス
4.762 % ツーペア
0.392 % ストレート
50.179 % 役なし
0.001 % ストレートフラッシュ
0.024 % フォーカード
この様にするとどの役がどの程度の確立で出現するか分かります。
 if(ストレートの判定(カード)) return フラッシュの判定(カード) ? "ストレートフラッシュ" : "ストレート";
この文はストレートの判定とフラッシュの判定の両方がtrueだった場合に
ストレートフラッシュだと判定し、ストレートのみtrueだった場合に
ストレートと判定するという意味です。
http://mittsu2017.com/%e3%82%b5%e3%82%a4%e3%83%88%e3%83%9e%e3%83%83%e3%83%97-2/