yopisan
@yopisan (kota)

Are you sure you want to delete the question?

If your question is resolved, you may close it.

Leaving a resolved question undeleted may help others!

We hope you find it useful!

ポーカーの役判定の表示②

Q&A

ポーカーの役判定にて以前の表示の件で以下の修正の件について解決はしましたが、うまく表示されません。今回は以下の通り

こちらは、不正になるのが正解です。
$cards = [
['suit'=>'heart', 'number'=>15],
['suit'=>'spade', 'number'=>15],
['suit'=>'joker', 'number'=>0],
['suit'=>'diamond', 'number'=>20],
['suit'=>'club', 'number'=>20],
];

発生している問題・エラー

不正の件について
 if($cards_num < 13 || $cards_num > 0){
           return "不正"; 
        }
コードを打ち込むことで解決はした。

しかしここからが問題になった。二つのコード組み込みテストをしたところ

こちらは、本来ストレートフラッシュが表示されていたところ不正と表示されるようになった。また他のロイヤルストレートフラッシュとファイブカードの条件の時まで不正と出るようになった。
$cards = [
  ['suit'=>'spade', 'number'=>9],
  ['suit'=>'joker', 'number'=>0],
  ['suit'=>'spade', 'number'=>10],
  ['suit'=>'spade', 'number'=>12],
  ['suit'=>'spade', 'number'=>13],
];

今回のポーカーの役の説明
// ジョーカー1枚のみ、suitをjoker、numberを0と表す。
// 上記以外は不正として処理してください。

// 追加された役
// 「フォーカード」+ジョーカーは「ファイブカード」

// 判定は強い役を優先してください。組み合わせの強さ順は以下とする。
// ロイヤルストレートフラッシュ > ストレートフラッシュ > ファイブカード > フォーカード > フルハウス > フラッシュ > ストレート > スリーカード > ツーペア > ワンペア
// ジョーカーが出た時点で最低でも「ワンペア」となること

該当するソースコード

//絵柄のjokerの不正
//  $cards = [
//    ['suit'=>'heart', 'number'=>12],
//    ['suit'=>'joker', 'number'=>0],
//    ['suit'=>'joker', 'number'=>1],
//    ['suit'=>'heart', 'number'=>10],
//    ['suit'=>'heart', 'number'=>13],
//  ];

//数字の0の不正
  // $cards = [
  //   ['suit'=>'heart', 'number'=>12],
  //   ['suit'=>'joker', 'number'=>0],
  //   ['suit'=>'heart', 'number'=>0],
  //   ['suit'=>'heart', 'number'=>10],
  //   ['suit'=>'heart', 'number'=>13],
  // ];

  //  $cards = [
  //    ['suit'=>'heart', 'number'=>15],
  //    ['suit'=>'spade', 'number'=>15],
  //    ['suit'=>'joker', 'number'=>0],
  //    ['suit'=>'diamond', 'number'=>20],
  //    ['suit'=>'club', 'number'=>20],
  //  ];

//ロイヤルストレートフラッシュ
   $cards = [
     ['suit'=>'heart', 'number'=>12],
     ['suit'=>'joker', 'number'=>0],
     ['suit'=>'heart', 'number'=>1],
     ['suit'=>'heart', 'number'=>10],
     ['suit'=>'heart', 'number'=>13],
   ];

// ストレートフラッシュ
    //  $cards = [
    //      ['suit'=>'heart', 'number'=>10],
    //      ['suit'=>'joker', 'number'=>0],
    //      ['suit'=>'heart', 'number'=>8],
    //      ['suit'=>'heart', 'number'=>9],
    //      ['suit'=>'heart', 'number'=>11],
    //  ];

//ファイブカード
  // $cards = [
  //     ['suit'=>'heart', 'number'=>12],
  //     ['suit'=>'joker', 'number'=>0],
  //     ['suit'=>'spade', 'number'=>12],
  //     ['suit'=>'diamond', 'number'=>12],
  //     ['suit'=>'club', 'number'=>12],
  // ];

//フォーカード
// $cards = [
//     ['suit'=>'heart', 'number'=>12],
//     ['suit'=>'joker', 'number'=>0],
//     ['suit'=>'spade', 'number'=>9],
//     ['suit'=>'diamond', 'number'=>12],
//     ['suit'=>'club', 'number'=>12],
// ];

//フルハウス
// $cards = [
//     ['suit'=>'heart', 'number'=>12],
//     ['suit'=>'joker', 'number'=>0],
//     ['suit'=>'spade', 'number'=>1],
//     ['suit'=>'diamond', 'number'=>12],
//     ['suit'=>'club', 'number'=>1],
// ];

//ストレート
// $cards = [
//     ['suit'=>'heart', 'number'=>9],
//     ['suit'=>'joker', 'number'=>0],
//     ['suit'=>'heart', 'number'=>10],
//     ['suit'=>'spade', 'number'=>13],
//     ['suit'=>'heart', 'number'=>12],
// ];

//フラッシュ
// $cards = [
//     ['suit'=>'heart', 'number'=>12],
//     ['suit'=>'joker', 'number'=>0],
//     ['suit'=>'heart', 'number'=>9],
//     ['suit'=>'heart', 'number'=>2],
//     ['suit'=>'heart', 'number'=>13],
// ];

//スリーカード
// $cards = [
//     ['suit'=>'heart', 'number'=>10],
//     ['suit'=>'joker', 'number'=>0],
//     ['suit'=>'heart', 'number'=>9],
//     ['suit'=>'spade', 'number'=>10],
//     ['suit'=>'club', 'number'=>12],
// ];

//ワンペア
// $cards = [
//     ['suit'=>'heart', 'number'=>10],
//     ['suit'=>'joker', 'number'=>0],
//     ['suit'=>'heart', 'number'=>9],
//     ['suit'=>'spade', 'number'=>1],
//     ['suit'=>'club', 'number'=>12],
// ];

  function judge($cards) {
    //絵札の枚数
    $cards_suit = array_column($cards,'suit');
    $count_suit = array_count_values($cards_suit);
  
    //ストレートの時の手札
    $cards_num = array_column($cards,'number');
    $num_min = $cards_num[2];
    $str_num = range($num_min , $num_min+4);
    $j_num_min = $cards_num[2];
    $j_str_num = [$j_num_min-1,$j_num_min,$j_num_min+1,$j_num_min+2,$j_num_min+3];
  
    //数字の枚数
    $count_num = array_count_values($cards_num);
  
    //ロイヤルストレートフラッシュの数字
    $royal = [1,10,11,12,13];
  
  
    // カードの不正チェック
        if($cards_num < 13 || $cards_num > 0){
           return "不正"; 
        }
    //  if($cards['suit'] !='heart' && $cards['suit'] !='spade'&& $cards['suit'] !='diamond'&& $cards['suit'] !='club'&& $cards['suit'] !='joker'){
    //    return "不正";
    //  }
      if (count(array_unique($cards,SORT_REGULAR)) < 5) {
        return "不正";
      }
      elseif ((count(array_keys($cards_suit,'joker'))) >= 2) {
        return "不正";
      }
      elseif ((count(array_keys($cards_num,0))) >= 2) {
        return "不正";
      }
    
    // カードの並び替え
    foreach( $cards as $value) {
      $suit_cards[] = $value['suit'];
      $number_cards[] = $value['number'];
    }
    array_multisort($number_cards, SORT_ASC, SORT_REGULAR, $cards);
  
//  判定
    if (in_array(['suit'=>'joker', 'number'=>0], $cards)){
      if ((count(array_intersect($royal,$cards_num)) == 4) && (count($count_suit) == 2)) {
        return "ロイヤルストレートフラッシュ";
      }
      elseif ((count(array_intersect($j_str_num,$cards_num)) == 4) && (count($count_suit) == 2)){
         return "ストレートフラッシュ";
        
      }
      elseif (count($count_num) == 2) {
        return "ファイブカード";
      }
      elseif ((count($count_num) == 3) && (max($count_num) == 3)) {
        return "フォーカード";
      }
      elseif (count($count_num) == 3) {
        return "フルハウス";
      }
      elseif (count($count_suit) == 1) {
        return "フラッシュ";
      }
      elseif (count(array_intersect($j_str_num,$cards_num)) == 5) {
        return "ストレート";
      }
      
      elseif (count($count_num) == 4) {
        return "スリーカード";
      }
      else {
        return "ワンペア";
      }
    }
    else {
    if (($cards_num == [1,10,11,12,13]) && (count(array_unique($cards_suit)) == 1)) {
        return "ロイヤルストレートフラッシュ";
      }
      elseif (($cards_num == $str_num) && (count(array_unique($cards_suit)) == 1)) {
        return "ストレートフラッシュ";
      }
      elseif (array_keys($count_num,4)) {
        return "フォーカード";
      }
      elseif (count($count_num) == 2) {
        return "フルハウス";
      }
      elseif (count($count_suit) == 1) {
        return "フラッシュ";
      }
      elseif ($cards_num == $str_num) {
        return "ストレート";
      }
      elseif ((count($count_num) == 3) && (array_keys($count_num,3))) {
        return "スリーカード";
      }
      elseif (count($count_num) == 3) {
        return "ツーペア";
      }
      elseif (count($count_num) == 4) {
        return "ワンペア";
      }
      else {
        return "なし";
      }
    }
  }
  
  ?>
  <!DOCTYPE html>
  <html lang="ja">
  <head>
    <meta charset="utf-8">
    <title>ポーカー役判定(ジョーカーあり)</title>
  </head>
  <body>
    <section>
      <p>手札は</p>
      <p><?php foreach($cards as $card): ?><?=$card['suit'].$card['number'] ?><?php endforeach; ?></p>
      <p>役は<?=judge($cards) ?>です。</p>
    </section>
  </body>
  </html>
  

自分で試したこと

自分が試したことは、不正表示のコードをコメントアウトしたら、ロイヤルストレートフラッシュ、ストレートフラッシュ、ファイブカードなどちゃんと表示されるようになることは確認はできたので、原因はカードの不正チェックの表示が悪いのかと推測。
ジョーカーは0でどの番号にもなり得るため。ただどうコードを変えれば全てうまくいくのかわからないのでどなたか教えてください。よろしくお願いいたします。

0

3Answer

先にデバッグの方法を勉強をされたほうが良いかと思います。
PHPのヘルプの見方もあわせて確認をされた方が良いかと思います。

「$cards_num」に設定された戻り値の型や値は何でしょうか?
「cards_num < 13 || $cards_num > 0」の判定は何がしたいのでしょうか?

1Like

質問者さんは一度ソースコードを紙にプリントアウトして一行ずつ処理中の変数の中身を手で計算してみるといいと思います。で、一行ずつ実行して変数の中身を表示して計算と合っているのか確認して見るのがいいとおもいます

冗談とか抜きにして。
それを何回か違うカードの組ですれば学びがあると思います。

すべてのプログラマーはこの作業を頭の中でやっています。スコープを小さくしろとよくいいますが、この脳内処理を簡単に行うためです。

0Like

Your answer might help someone💌