日本だんでぃ協会
Japan Dandy Association

中の人プロフィール
だんでぃ
web拍手作った人
プログラマーでミュージシャンだと言い張って聞かない37才

おこんてんつ
トップ
  プログラミング (12)
  音楽 (7)
  ポーカー (1)
  雑記 (1)

リンク
ろじっくぱらだいす
老舗のプログラム系テキストサイト。web拍手を思い付くきっかけをいただいたサイトです。ワタナベさんラヴ!
東京 de Poker
たまにお邪魔してます

■ポーカーの役判定 最終回

2017/06/04 22:48 作成
はい、では残ったストレートフラッシュとロイヤルフラッシュの判定を作りましょう!

どっちから作っていくか悩みどころですが、
ロイヤルフラッシュもストレートフラッシュの一つなので、
ストレートフラッシュの判定ができればついでにフォローできてしまうかもしれません。

ということで、ストレートフラッシュの判定を考えてみましょう。

ストレートフラッシュという役は、
「ストレートができている5枚が、さらにフラッシュにもなっている」
という状態の役です。

前回までにストレートの判定とフラッシュの判定は完成しているので、
こんなコードで判定できそうです。
function IsStraightFlush( targetCards ){

	//ストレートかつフラッシュが成立していたらストレートフラッシュ判定
	if( IsStraight( targetCards ) && IsFlush( targetCards ) ){
		return true;
	}

	//ここまで到達でストレートフラッシュは成立していない
	return false;
}
はい。

一見正しそうに見えますが、このコードはバグっています。

5枚のカードしか使わないポーカーならこのコードで問題ないのですが、
テキサスホールデムは7枚のカードを使用するので、

こんなカードの組み合わせになると、
「ストレートフラッシュ」は成立していませんが
「ストレート」と「フラッシュ」が成立しているため、
上のコードでは誤って「ストレートフラッシュ」判定をしてしまいます。

では、正しく判定するためにはどんなコードを組むと良いか考えてみましょう。

「ストレートが成立しているカードでフラッシュが成立しているか」
という考え方だと、先ほどのように6枚以上の長いストレートになったときに正しく判定できません。

では、逆に
「フラッシュが成立しているカードでストレートが成立しているか」
と考えるとどうでしょう。

例えば、さっきの7枚から「フラッシュが成立しているカード」を抜き出すと

この5枚になりますが、
この組み合わせだとストレートは成立していないので正しく判定できます。

実際にストレートフラッシュが成立している7枚のカードでも試してみましょう。

こんな組み合わせから「フラッシュが成立しているカード」を抜き出すと

この6枚になり、この組み合わせでストレートは成立しているので、
正しくストレートフラッシュ判定ができそうです。

では、実際に
「フラッシュが成立しているカードでストレートが成立しているか」
という考え方でコードを書いてみましょう。

こんな感じになりました。
function IsStraightFlush( targetCards ){

	//マークごとに仕分けする入れ物を準備
	var suits = { "Spade":[], "Heart":[], "Dia":[], "Club":[] };

	//引数として渡されたカードをマークごとに分ける
	for( var i=0; i<targetCards.length; i++ ){
		suits[targetCards[i]["Mark"]].push( targetCards[i] );
	}

	//ストレートフラッシュ判定用のフラグを準備
	var flag = false;

	//仕分けしたカードのデータを順に検証
	Object.keys(suits).forEach(function (key) {

		//そのマークのカードが5枚以上あって、かつストレートができていたら
		//ストレートフラッシュ成立。フラグをオンにする。
		if( suits[key].length>=5 && IsStraight( suits[key] ) ){
			flag = true;
		}
	});

	//検証結果をリターン
	return flag;
}

当然の事ながら、4種類あるマークの全てを検証しないといけないので
思いのほか複雑なコードになってしまいました。

あと、javascriptのforeachって初めて使ったので、
その周辺のコードがあまり美しくないかもです。

さて、これでストレートフラッシュの判定ができました!
残るはロイヤルフラッシュのみです。

ロイヤルフラッシュって、言ってしまえば
「10、J、Q、K、Aのストレートフラッシュ」なので、
さっき作ったストレートフラッシュの判定のコードが使えそうです。

考え方としては、
「対象となるカードから、10、J、Q、K、Aを抜き出して、ストレートフラッシュが成立しているか判定」
で良さそうです。

コードはこんな感じになりますね。
function IsRoyalFlush( targetCards ){

	//カードを仕分けする入れ物を準備
	var cards = [];

	//引数として渡されたカードから1、10、11、12、13の数字だけ抜き取る
	for( var i=0; i<targetCards.length; i++ ){

		//数字が9以下で、かつ1じゃなかったら対象外
		if( targetCards[i]["Number"]<=9 && targetCards[i]["Number"]!=1 ){ continue; }

		cards.push( targetCards[i] );
	}

	//仕分けしたカードがストレートフラッシュが成立していたらロイヤルフラッシュ成立
	if( IsStraightFlush( cards ) ){
		return true;
	}

	//ここまで到達でロイヤルフラッシュは成立していない
	return false;
}
はい。

ようやくこれでポーカーの全ての役判定が可能になりました!

あとは、役判定をしたいカードの組み合わせを、
強い役の順に判定していけば成立している役を調べることが可能です。


さて、複数回に渡って更新してきた「ポーカーの役判定プログラム講座」ですが、
今回でめでたく終了となります!

7枚のカードを使用するテキサスホールデムの役判定プログラムは
難易度的には「下の上」くらいだと思います。

何のヒントも無い状態から、一人でこのプログラムを完成させられれば
ようやくプログラマーとして初心者を抜けられたと言って良いのではないでしょうか。


僕は、プログラマーのスキルとして何よりも大事なのは、
「要求仕様をコードに落とし込める言葉に変換できるか」
だと考えています。

例えば、今回解説した「ストレートフラッシュ」の判定も、
「ストレートとフラッシュが同時に成立している」
から
「マークごとにカードのデータを別の変数に分け、
 それぞれがストレートとフラッシュが成立しているか調べる」

に変換できるか。

今回の講座を通して、プログラミングに興味のある方や、
これからプログラミングを学ぼうとしている方に
何かを伝える事ができていたら、こんなに嬉しいことはありません。


またそのうち、こんな感じのプログラミング解説講座をやろうと思っていますので、
その時はまたお付き合いください~♪


トランプの画像はこちらからお借りしました。
ありがとうございます♪
http://sozai.7gates.net/docs/trump/



前の記事 ポーカーの役判定 ストレート編

関連記事
ポーカーの役判定 最終回
ポーカーの役判定 ストレート編
ポーカーの役判定 ツーペア、フルハウス編
ポーカーの役判定 数字の重なり編
ポーカーの役判定プログラムを作ってみよう!

2017 日本だんでぃ協会 All Rights Reserved.