nekogamisong7
@nekogamisong7

Are you sure you want to delete the question?

Leaving a resolved question undeleted may help others!

PHPの複数の条件式について(and, orの複数の使用方法)

解決したいこと

PHPの複数の条件式について(and, orの複数の使用方法)

現在、PHPにてjoker一枚を加えたポーカーの役判定システムをコーディングしています。
その際、ロイヤルストレートフラッシュの役判定の条件式がうまく作動せず、ジョーカーを含んだ場合は全てロイヤルストレートフラッシュ判定になってしまいます。

原因

原因はおそらく、jokerを含んだロイヤルストレートフラッシュの役判定の条件式の書き方に問題があるのだと思います。
下記がその部分のコードです

 if (($number == ([0, 1, 10, 11, 12] || [0, 10, 11, 12, 13] || [0, 1, 11, 12, 13] || [0, 1, 10, 12, 13] || [0, 1, 10, 11, 13])) && ($b == [1, 4])) {
            return  "ロイヤルストレートフラッシュ";  //jokerがどれかに含まれるとき
        } 

自分で試したこと

条件式の区切りがはっきりしていないことが問題と思い、思いつくキーワードで検索してみたり、一つのまとまりを()で括ってみたりはしたのですが、うまく作動しませんでした。

検索でも答えが見つけられないような未熟者の質問ですが、ご回答いただけると幸いです。

以下、全体のコードです。

<?php

// 手札
$cards = [
    ['suit'=>'heart', 'number'=>9],
    ['suit'=>'joker', 'number'=>0],
    ['suit'=>'heart', 'number'=>7],
    ['suit'=>'heart', 'number'=>11],
    ['suit'=>'heart', 'number'=>12],
];

function judge($cards)
{

    // カードの不正チェック

    $c = array_unique($cards, SORT_REGULAR);     
    $count = count($c);                         

    foreach ($cards as $card) {
        if ($card["number"] > 13 || $card["number"] < 0) {   
            return "不正";
        } elseif ($card["suit"]  != "heart" && $card["suit"]  != "spade" && $card["suit"]  != "diamond" && $card["suit"]  != "club" && $card["suit"]  != "joker") {       
            return "不正";
        } elseif ($count < 5) {                 
            return "不正";
        } elseif ($card["suit"]  != "joker" && $card["number"] == 0) {
            return "不正";
        } elseif ($card["suit"]  == "joker" && $card["number"] != 0) {
            return "不正";
        }
    }


    // 役判定
    $number = array_column($cards, "number");       
    sort($number);                                 
    $a = array_count_values($number);            
    sort($a);                                      

    $suit = array_column($cards, "suit");           
    $b = array_count_values($suit);                
    sort($b);                                      

    $zero = $number[0];
    $sNumber = range($zero, $zero + 4);


    // 結果を返す
    if ($number[0] !== 0) {

        if ($number == [1, 10, 11, 12, 13] && $b == [5]) {
            return  "ロイヤルストレートフラッシュ";
        } elseif ($number == [$number[0], $number[0] + 1, $number[0] + 2, $number[0] + 3, $number[0] + 4] && $b == [5]) {
            return  "ストレートフラッシュ";
        } elseif ($a == [1, 4]) {
            return  "フォーカード";
        } elseif ($a == [2, 3]) {
            return  "フルハウス";
        } elseif ($b == [5]) {
            return  "フラッシュ";
        } elseif ($number == [$number[0], $number[0] + 1, $number[0] + 2, $number[0] + 3, $number[0] + 4]) {
            return  "ストレート";
        } elseif ($a == [1, 1, 3]) {
            return  "スリーカード";
        } elseif ($a == [1, 2, 2]) {
            return  "ツーペア";
        } elseif ($a == [1, 1, 1, 2]) {
            return  "ワンペア";
        } else {
            return  "なし";
        }
    } elseif ($number[0] === 0) {
        if (($number == ([0, 1, 10, 11, 12] || [0, 10, 11, 12, 13] || [0, 1, 11, 12, 13] || [0, 1, 10, 12, 13] || [0, 1, 10, 11, 13])) && ($b == [1, 4])) {
            return  "ロイヤルストレートフラッシュ";  //jokerがどれかに含まれるとき
        } elseif ($number == $sNumber && $b == [1, 4]) {
            return  "ストレートフラッシュ";
        } elseif ($a == [1, 4]) {
            return  "ファイブカード";
        } elseif ($a == [1, 1, 3] && $a == [1, 2, 2]) {
            return  "フルハウス";
        } elseif ($b == [1, 4]) {
            return  "フラッシュ";
        } elseif ($number == $sNumber) {
            return  "ストレート";
        } elseif ($a == [1, 1, 1, 2]) {
            return  "スリーカード";
        } elseif ($a == [1, 1, 1, 1, 1]) {
            return  "ワンペア";
        }
    }
}

?>

0

2Answer

and or xor not の論理演算より
正規表現の方が簡単な場合があります。ご参考にして下さい。(末行にあります)

1Like

Comments

  1. @nekogamisong7

    Questioner

    ご回答頂いておりましたのに返信が遅れてしまい申し訳ありません!!
    参考URL、非常にためになりました。こちらを常に確認できるようお気に入りさせて頂きました!

演算優先順位に応じた括弧を付け加えると以下のようになり、$number == で比較してるのは最初の配列とだけですね。

if ((($number == ([0, 1, 10, 11, 12]) ||
     ([0, 10, 11, 12, 13]) ||
     ([0, 1, 11, 12, 13]) ||
     ([0, 1, 10, 12, 13]) ||
     ([0, 1, 10, 11, 13]))
    ) && ($b == [1, 4])) {

全部の配列と $number == で比較する必要があります。

if (($number == [0, 1, 10, 11, 12] || 
     $number == [0, 10, 11, 12, 13] ||
     $number == [0, 1, 11, 12, 13] ||
     $number == [0, 1, 10, 12, 13] ||
     $number == [0, 1, 10, 11, 13] ||
    ) && ($b == [1, 4])) {

あるいは、in_array関数を使うといいでしょう。

if (in_array($number, [[0, 1, 10, 11, 12],
                       [0, 10, 11, 12, 13],
                       [0, 1, 11, 12, 13],
                       [0, 1, 10, 12, 13],
                       [0, 1, 10, 11, 13]]
            ) && ($b == [1, 4])) {
1Like

Comments

  1. @nekogamisong7

    Questioner

    ご回答頂いておりましたのに返信が遅れてしまい申し訳ありません!!
    自分でも$number == を毎回つけないといけないというところまでは気付けたのですが、in_array関数の使い方は目から鱗でした!
    これは非常に簡潔に書き直せますね...
    ためになるご回答ありがとうございます!!

Your answer might help someone💌