質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.45%
PHP

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

Q&A

解決済

2回答

4170閲覧

【PHP】ポーカーの役判定で「ワンペア ジョーカー」がうまく表示できない

suzuki-gogo1195

総合スコア2

PHP

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

0グッド

1クリップ

投稿2022/11/17 09:19

実現したいこと

PHPを使ってポーカーの役を判定するプログラムを作成中です。
大半の役判定プログラムは完成したのですが、「(ジョーカーを含む)ワンペア」の判定だけがうまくいきません。

手持ちのカードが以下の場合、

$cards = [ ['suit' => 'heart', 'number' => 10], ['suit' => 'joker', 'number' => 0], ['suit' => 'spade', 'number' => 1], ['suit' => 'diamond', 'number' => 13], ['suit' => 'club', 'number' => 9], ];

実行すると、

手札は heart10joker0spade1diamond13club9 役はストレートです。

と表示されてしまいます。

本来は「ワンペア」と表示されたい。

該当のソースコード

PHP

1<?php 2$cards = [ 3 ['suit' => 'heart', 'number' => 10], 4 ['suit' => 'joker', 'number' => 0], 5 ['suit' => 'spade', 'number' => 1], 6 ['suit' => 'diamond', 'number' => 13], 7 ['suit' => 'club', 'number' => 9], 8]; 9 10function judge($cards) 11{ 12 $joker = 0; 13 14 if (count($cards) != 5) { 15 exit('不正です'); 16 } 17 $card_numbers = array_column($cards, 'number'); 18 $suit_count = array_count_values(array_column($cards, 'suit')); 19 $number_count = array_count_values($card_numbers); 20 $unique_hands = array_unique($cards, SORT_REGULAR); 21 $hands = count($unique_hands); 22 if ($hands < 5) { 23 exit('不正です'); 24 } 25 26 $suits = ['heart', 'spade', 'diamond', 'club', 'joker']; 27 foreach ($cards as $key => $val) { 28 if (!(in_array($val['suit'], $suits))) { 29 exit('不正です'); 30 } 31 } 32 33 foreach ($cards as $key => $val) { 34 if ($val['number'] >= 14 || $val['suit'] != "joker" && $val['number'] < 1) { 35 exit('不正です'); 36 } elseif ($val['number'] == 0) { 37 $joker++; 38 } 39 } 40 foreach ($cards as $card) { 41 if ($card["suit"] == "joker") { 42 if ($card["number"] != 0) { 43 exit('不正です'); 44 } 45 } 46 } 47 48 array_multisort($card_numbers, SORT_ASC, $cards); 49 $max = max($card_numbers); 50 $min = min($card_numbers); 51 52 //フラッシュ 53 $Flush = (count($suit_count) == 1); 54 $Flush_j = (count($suit_count) == 2); 55 56 //ペア 57 $pair = [1 => 0, 2 => 0, 3 => 0, 4 => 0, 5 => 0]; 58 foreach ($number_count as $v) { 59 $pair[$v]++; 60 } 61 62 //ストレート 63 $straight = ($pair[1] == count($cards) && ($max - $min) <= 4); 64 $straight_j = ($pair[1] == count($cards) && ($max - $min) <= 13); 65 66 //ロイヤル 67 $roy = ($card_numbers[0] == 1 && $card_numbers[1] == 10 && $card_numbers[2] == 11 && $card_numbers[3] == 12 && $card_numbers[4] == 13); 68 69 if ($Flush && $roy) { 70 return "ロイヤルストレートフラッシュ"; 71 } elseif ($Flush && $straight) { 72 return "ストレートフラッシュ"; 73 } elseif ($pair[5] == 1 || $pair[4] == 1 && $joker == 1 || $pair[3] == 1 && $joker == 2 || $pair[2] == 1 && $joker == 3 || $joker >= 4) { 74 return "ファイブカード"; 75 } elseif ($pair[4] == 1 || $pair[3] == 1 && $joker == 1 || $pair[2] == 1 && $joker == 2 || $joker == 3) { 76 return "フォーカード"; 77 } elseif ($pair[2] == 1 && $pair[3] == 1 || $pair[2] == 2 && $joker == 1 || $pair[3] == 1 && $joker == 2) { 78 return "フルハウス"; 79 } elseif ($Flush || $Flush_j && $joker == 1) { 80 return "フラッシュ"; 81 } elseif ($roy || $straight || $straight_j && $joker == 1) { 82 return "ストレート"; 83 } elseif ($pair[3] == 1 || $pair[2] == 1 && $joker == 1 || $joker == 1) { 84 return "スリーカード"; 85 } elseif ($pair[2] == 2) { 86 return "ツーペア"; 87 } elseif ($pair[2] == 1 || $joker == 1) { 88 return "ワンペア"; 89 } else { 90 return "なし"; 91 } 92} 93 94?> 95<!DOCTYPE html> 96<html lang="ja"> 97 98<head> 99 <meta charset="utf-8"> 100 <title>ポーカー役判定</title> 101</head> 102 103<body> 104 <p>手札は</p> 105 <p><?php foreach ($cards as $card) : ?><?= $card['suit'] . $card['number'] ?><?php endforeach; ?></p> 106 <p>役は<?= judge($cards) ?>です。</p> 107</body> 108 109</html>

ご教授いただけると幸いです。よろしくお願い致します。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

(1)カードをnumberでソートし0番目の要素が0の場合はジョーカーを含む処理になります。
(2)ジョーカーをふくまなければ、ペアが1つだけの場合はかならずワンペアです
(3)ジョーカーを含むなら、ペアががあると3カードになるのでそれを弾きます
(4)1番目のnumberと4番目のnumberの差が4もしくは53もしくは4のときはストレートになりますのでそれを弾きます
(5)13と1がつながるならその処理をいれます

投稿2022/11/17 09:59

編集2022/11/18 00:18
yambejp

総合スコア115053

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

suzuki-gogo1195

2022/11/17 13:18

ご回答いただきありがとうございます。 (1)と(2)の部分は理解できたのですが、それ以降が未だ理解できていません。 もし可能であれば、もう少し深く解説をいただくことは可能でしょうか? よろしくお願い致します。
yambejp

2022/11/18 00:23

(3)4枚のうちどれか1組でもペアがあればジョーカーがあれば3カードになりますよね? (4)(3)でペアがない判定、よって5番目から2番目を引くだけでストレートかどうか判定できます ストレート=ジョーカーがない場合は5番目-1番目=4の場合です。 (5)は条件付の問題なのでストレートの際にどのつながりならOKかを定義してくださいということ 10=X、11=J、12=Q、13=K、エース=Aとして XJQKAはストレート計算ですよね? A2345はOKですか?QKA23はOKですか?ローカルルールによるので判断がわかれます
guest

0

ベストアンサー

ジョーカーが存在する場合と存在しない場合で役判定を変えるのが筋かと思います。
ジョーカーが存在する場合、数字順に並び替えて
・10,J,Q,K,A のうち4枚が含まれ、かつ同一数字がないならロイヤルストレート確定
・同じ数字が4つあったらファイブカード確定
・同じ数字が3つあったらフォーカード確定
・同じ数字が2つが二組であればフルハウス確定 (※3つ+1つだとフォーカードを取るのでフルハウスにならない)
・同じ数字が2つが一組あればスリーカード確定
・最も小さいカードと最も大きいカードの差が4、かつ同一数字がないならストレート確定
・最も小さいカードと最も大きいカードの差が5、かつ同一数字がないならストレート確定(穴埋め)
・同じ数字が一つもなく、ストレートにならないならワンペア確定
で、これとは別にスイートが4枚同一であればフラッシュが確定。
あとはフラッシュとの複合役(ストレートフラッシュなど)が成立するかどうかですね。
※ジョーカーを含む時点でツーペアはありえない(フルハウスかスリーカードになるため)

投稿2022/11/17 14:55

tacsheaven

総合スコア13703

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.45%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問