なんとなくポーカーの役を判定するコードを書いてみる。参考なし。最適化はしない。
<?php
define('SPADE', 0);
define('CLUB', 1);
define('HEART', 2);
define('DIAMOND', 3);
$suit = [SPADE, CLUB, HEART, DIAMOND];
// ランダムでカードを選択(重複は考慮しない)
$cards = array_map(fn() => [0 => array_rand($suit), 1 => random_int(0, 13)], range(1,5));
// 判定
$result = judge($cards);
// 出力
$mark = [SPADE=>"♠", CLUB=>"♣", HEART=>"♥", DIAMOND=>"♦"];
$c = array_map(fn($v) => $v[1]==0?'JOKER':$mark[$v[0]].$v[1], $cards);
echo implode(', ', $c) . " : ". $result . PHP_EOL;
function judge($cards) {
$joker = 0; // JOKERの枚数
foreach ($cards as $k => $card) {
if ($card[1]==1) {
$cards[$k][1] = 14; // 1 は 14 とする
} else if ($card[1]==0) {
// JOKERの場合、配列から削除
unset($cards[$k]);
$joker++;
}
}
if ($joker==5) return "ロイヤルストレートフラッシュ";
// スートと数字を分離
$suit = array_column($cards, 0);
$number = array_column($cards, 1);
$max = max($number);
$min = min($number);
// フラッシュ判定
$suit_count = array_count_values($suit); // スートの数
$isFlush = (count($suit_count)==1);
// 数字の数
$number_count = array_count_values($number);
// ペア数
$pair = [1=>0,2=>0,3=>0,4=>0,5=>0];
foreach ($number_count as $v) $pair[$v]++;
// ストレート判定(ペアがなく、最小値と最大値の差が4以下)
$isStraight = ($pair[1]==count($cards) && ($max - $min) <= 4);
// 強い順に判定
if ($isFlush && $isStraight && $min >= 10) {
// jokerの枚数に関わらず min≧10 で判定可能
return "ロイヤルストレートフラッシュ";
} else if ($isFlush && $isStraight) {
return "ストレートフラッシュ";
} else if ($pair[5] == 1 // イカサマ
|| $pair[4] == 1 && $joker == 1
|| $pair[3] == 1 && $joker == 2
|| $pair[2] == 1 && $joker == 3
|| $joker >= 4) {
return "ファイブカード";
} else if ($pair[4] == 1
|| $pair[3] == 1 && $joker == 1
|| $pair[2] == 1 && $joker == 2
|| $joker == 3) {
return "フォーカード";
} else if ($pair[2] == 1 && $pair[3] == 1
|| $pair[2] == 2 && $joker == 1
|| $pair[3] == 1 && $joker == 2) {
return "フルハウス";
} else if ($isFlush) {
return "フラッシュ";
} else if ($pair[1]==count($number) && $isStraight) {
return "ストレート";
} else if ($pair[3] == 1 || $pair[2] == 1 && $joker == 1 || $joker == 2) {
return "スリーカード";
} else if ($pair[2] == 2) {
return "ツーペア";
} else if ($pair[2] == 1 || $joker == 1) {
return "ワンペア";
} else {
return "役なし";
}
}
結果(何回か適当に)
♠1, ♦8, ♥8, ♠10, ♦11 : ワンペア
♣11, ♥10, ♥10, ♣10, ♥10 : フォーカード
JOKER, ♥1, ♥10, ♠1, ♣12 : スリーカード
♣10, ♠9, JOKER, ♣12, ♠10 : スリーカード
♥6, ♥7, ♣10, ♥8, JOKER : ストレート
♦4, ♥3, ♠6, ♠2, JOKER : ストレート
♠10, ♥11, ♠12, ♠13, JOKER : ストレート
♠9, ♠4, ♠11, ♠8, ♠2 : フラッシュ
♣11, ♠5, ♣5, JOKER, ♠11 : フルハウス
JOKER, JOKER, ♦13, JOKER, ♥3 : フォーカード
♠10, ♠11, ♠12, ♠13, ♠1 : ロイヤルストレートフラッシュ
JOKER, ♠11, ♠12, ♠13, ♠1 : ロイヤルストレートフラッシュ
♠9, ♠11, ♠12, ♠13, JOKER : ストレートフラッシュ