PHPで書くjokerを含むポーカーでの役判定アルゴリズム。
解決したいこと
役判定のロジックの書き方に行き詰まっています。
jokerがあってもなくても役判定されません。
役判定のロジックの書き方を教えてください。
手札は
heart13 club1 club2 diamond1 club13
役はなしです
該当するソースコード
<?php
// 手札
$cards = [
['suit'=>'heart', 'number'=>13],
['suit'=>'club', 'number'=>1],
['suit'=>'club', 'number'=>2],
['suit'=>'diamond', 'number'=>1],
['suit'=>'club', 'number'=>13],
];
// 絵柄の種類
$suits = ['heart', 'diamond', 'spade', 'club'];
// ワイルドカードの joker を定義
$joker = ['suit'=>'joker', 'number'=>0];
function judge($cards, $suits) {
// ワイルドカードの役判定用フラグ
$wildcard_used = false;
foreach ($cards as $card) {
if ($card['number'] == 0) {
$wildcard_used = true;
break;
}
}
// ワイルドカードが手札にある場合
if ($wildcard_used) {
// ワイルドカードを含めた役判定
// ここでは各役の条件を優先度順に判定しています
// 条件に合致する役が見つかった場合、それ以上の役判定は行いません
if (onePairWithWildcard($cards, $suits)) {
return "役はワンペアです";
} elseif (threeCard($cards, $suits)) {
return "役はスリーカードです";
} elseif (straight($cards, $suits)) {
return "役はストレートです";
} elseif (isFlush($cards, $suits)) {
return "役はフラッシュです";
} elseif (fullHouse($cards, $suits)) {
return "役はフルハウスです";
} elseif (fourCard($cards, $suits)) {
return "役はフォーカードです";
} elseif (straightFlush($cards, $suits)) {
return "役はストレートフラッシュです";
} elseif (royalStraightFlush($cards, $suits)) {
return "役はロイヤルストレートフラッシュです";
} else {
return "役はなしです";
}
} else {
// ワイルドカードがない場合の役判定
if (onePair($cards, $suits)) {
return "役はワンペアです";
} elseif (twoPair($cards, $suits)) {
return "役はツーペアです";
} elseif (threeCard($cards, $suits)) {
return "役はスリーカードです";
} elseif (straight($cards, $suits)) {
return "役はストレートです";
} elseif (isFlush($cards, $suits)) {
return "役はフラッシュです";
} elseif (fullHouse($cards, $suits)) {
return "役はフルハウスです";
} elseif (fourCard($cards, $suits)) {
return "役はフォーカードです";
} elseif (straightFlush($cards, $suits)) {
return "役はストレートフラッシュです";
} elseif (royalStraightFlush($cards, $suits)) {
return "役はロイヤルストレートフラッシュです";
} else {
return "役はなしです";
}
}
}
// ワンペアの判定
function onePair($cards, $suits) {
$count = array_count_values(array_column($cards, 'number'));
return count(array_filter($count, function($value) { return $value == 2; })) == 1 && count(array_unique(array_column($cards, 'suit'))) <= count($suits) - 1;
}
// ワイルドカードを含めたワンペアの判定
function onePairWithWildcard($cards, $suits) {
$count = array_count_values(array_column($cards, 'number'));
return count(array_filter($count, function($value) { return $value == 2 || $value == 1; })) == 2;
}
// ツーペアの判定(ワンペアと同じ条件なので、ツーペア=スリーカードとなる)
function twoPair($cards, $suits) {
return onePair($cards, $suits);
}
// スリーカードの判定
function threeCard($cards, $suits) {
$count = array_count_values(array_column($cards, 'number'));
return in_array(3, $count) && count(array_unique(array_column($cards, 'suit'))) <= count($suits) - 1;
}
// ストレートの判定
function straight($cards, $suits) {
$numbers = array_column($cards, 'number');
sort($numbers);
return max($numbers) - min($numbers) == 4 && count(array_unique($numbers)) == 5;
}
// フラッシュの判定
function isFlush($cards, $suits) {
$suitsInHand = array_unique(array_column($cards, 'suit'));
return count($suitsInHand) == 1 && count(array_diff($suitsInHand, $suits)) == 0;
}
// フルハウスの判定
function fullHouse($cards, $suits) {
$count = array_count_values(array_column($cards, 'number'));
return in_array(3, $count) && in_array(2, $count);
}
// フォーカードの判定
function fourCard($cards, $suits) {
$count = array_count_values(array_column($cards, 'number'));
return in_array(4, $count);
}
// ストレートフラッシュの判定
function straightFlush($cards, $suits) {
return straight($cards, $suits) && isFlush($cards, $suits);
}
// ロイヤルストレートフラッシュの判定
function royalStraightFlush($cards, $suits) {
$royal_numbers = [1, 10, 11, 12, 13];
$numbers = array_column($cards, 'number');
sort($numbers);
return $numbers == $royal_numbers && isFlush($cards, $suits);
}
// 関数「judge」を呼び出して結果を表示する
echo "手札は\n";
foreach ($cards as $card) {
echo "{$card['suit']}{$card['number']} ";
}
echo "\n";
echo judge($cards, $suits);
?>
自分で試したこと
ここに問題・エラーに対して試したことを記載してください。
var_dumpで出力してみましたが原因がよくわかりませんでした。