PHPのテキサスホールデム(ポーカー)での組み合わせの優先度の計算

この記事では、テキサスホールデム(2ポケットカードと5コモンのポーカー)での組み合わせの優先順位を計算する方法について説明します。 従来、この記事は、カードの配列の作成、ストリートの計算、フラッシュとストリートフラッシュの計算、ペアの組み合わせの計算、最​​終計算、表示の6つの部分に分割します。 コードを手続き型で記述します。



目的:プログラム出力で読み取り可能な結果を​​取得し、コードの作成段階でデバッグおよびデバッグに使用できるようにします。 この目標を達成するために、1e + 2(100)回の組み合わせの違いを作ります。



最後に何が出るかのおおよそのビュー。最後の2枚のカードポケットと最初の5枚の共通ポケットを考えます。





マップの配列を作成する



デッキには4つのスーツと13の利点があるので、[2-14、102-114、202-214、302-314]の範囲で7つの数字の配列を形成し、これらの数字を100(%100)で除算して残りを操作します。 もちろん、[2-14、22-34、42-54、62-74]の範囲の数値の配列を形成し、20で割った余りを比較することができます(%20)。 しかし、最初のオプションの読みやすさは、私の意見では顔にあるので、私はそれに焦点を当てます。



function cardsCreation() { $arrayCards = []; for ($i = 0; $i < 7; $i++) { $card = mt_rand(2, 14); //       2  14 $multiplier = mt_rand(0, 3); //    if (1 == $multiplier) { //   1,    100 $card = $card + 100; } else if (2 == $multiplier) { //   2,    200 $card = $card + 200; } else if (3 == $multiplier) { //   3,    300 $card = $card + 300; } if (!in_array($card, $arrayCards)) { //,      ,       $arrayCards = array_merge($arrayCards, [$card]); } else { //     ,  ,     $i--; } } return $arrayCards; }
      
      





ストレートの組み合わせの定義と計算



ストレートは、カードのメリットが順番に行われる組み合わせです。 したがって、この組み合わせを構成するすべてのカードを計算するときに考慮することは意味がありません。優先順位の最初のカードだけで十分です。



ストレートの組み合わせを決定および計算するためのいくつかのオプションがあります。 それらのほとんどは、元の配列のメンバーの除算の残りの部分を降順に並べ替えるタスクに要約され、その後、何らかの方法で組み合わせを構成する要素を強調表示すると思います(5枚以上のカードがストレートの場合、最大のものを選択する必要があります)。



ストレートを決定する私の方法の本質は、ソート後、最初に路上で最初の5枚のカードをチェックし、次に2番目と3番目のカードをチェックすることです。 また、エース、デュース、3、4、5もストレートを作ることを忘れないでください。 したがって、セットにエース(値14)が含まれる場合、8番目の要素を配列-1に追加します。したがって、この場合、4番目の5つのカードをチェックする必要があります。



 function straight(array $arrayCards) { $newArrayCards = []; $ace = false; foreach ($arrayCards as $arrayCard) { $newArrayCards = array_merge($newArrayCards, [$arrayCard % 100]); //       100 if(14 == $arrayCard % 100) { //     , 2, 3, 4, 5 $ace = true; } } if($ace == true) { $newArrayCards = array_merge($newArrayCards, [1]); //    ,    1 } rsort($newArrayCards); //       $count = 0; //,    1  ,         = 1 $length = 4; //,       $result = 0; //  $begin = 0; // ,      for($i = 1; $i <= $length; $i++) { if (-1 == ($newArrayCards[$i] - $newArrayCards[$i - 1])) { $count++; } if($length == $i) { if(4 == $count) { //$count == 4,   $result = $newArrayCards[$begin] * 1e+8; } else if($length < 6 or (6 == $length and $ace == true)) {//  ,      $length++; // ,     $begin++; // ,     $i = $begin; //   for  $i   1 ($i++  for) $count = 0; //  } } } return $result; }
      
      





フラッシュとストリートフラッシュの組み合わせの定義と計算



フラッシュ-同じスーツのカードの組み合わせ。 計算するとき、組み合わせを構成するすべてのカードを考慮する必要があります。



ストレートフラッシュを計算するとき、およびストレートを計算するときは、組み合わせの最も高いカードのみを考慮することができます。



フラッシュを決定するために、配列をループ処理します。 ループでは、4つの補助配列を(スーツの数だけ)作成します。 最初の配列では、最初のスーツのすべてのカードを、2番目の配列では-2番目などに配置します。 スーツがない場合、対応する配列は空になります。 配列の要素数が5以上の場合、このスーツはフラッシュを形成しています。



フラッシュはストレートよりも優先されるため、フラッシュ機能では、ストレートフラッシュが形成されたかどうかを確認するのが論理的です。 また、ストレートとフラッシュの両方をチェックする別個の関数を作成することは不便であることは明らかだと思います。 配列のフラッシュをチェックする関数を作成し、その関数でストリートのフラッシュをチェックする関数を呼び出すことをお勧めします。



フラッシュが真っ直ぐなフラッシュを形成しない場合、元の配列を100(%100)で除算して残りをソートします。 次に、結果の配列の最初の5つのメンバーに、それぞれ1e + 10、1e + 8、1e + 6、1e + 4、1e + 2を掛けます。



ストレートフラッシュ検出関数に基づいてストレートフラッシュ検出関数を作成します。唯一の違いは、関数が要素数が7未満の配列を受信できることです(フラッシュを形成するカードのみを送信します)。



フラッシュを決定する機能:



 function pokerFlush(array $arrayCards) { $suit1 = []; //  $suit2 = []; //  $suit3 = []; //  $suit4 = []; //  foreach ($arrayCards as $arrayCard) { // 4 ,      if($arrayCard >= 2 and $arrayCard <= 14) { $suit1 = array_merge($suit1, [$arrayCard]); } else if($arrayCard >= 102 and $arrayCard <= 114) { $suit2 = array_merge($suit2, [$arrayCard]); } else if($arrayCard >= 202 and $arrayCard <= 214) { $suit3 = array_merge($suit3, [$arrayCard]); } else { $suit4 = array_merge($suit4, [$arrayCard]); }} if(count($suit1) >= 5) { //        5 $result = straightFlush($suit1); //        if(0 == $result) {//    foreach ($suit1 as $key1 => $s1) {//     100 $suit1[$key1] = $s1 % 100; } rsort($suit1); //    $result = $suit1[0] * 1e+10 + $suit1[1] * 1e+8 + $suit1[2] * 1e+6 + $suit1[3] * 1e+4 + $suit1[4] * 1e+2; } } else if (count($suit2) >= 5) { //        5 $result = straightFlush($suit2); if(0 == $result) { foreach ($suit2 as $key2 => $s2) { $suit2[$key2] = $s2 % 100; } rsort($suit2); $result = $suit2[0] * 1e+10 + $suit2[1] * 1e+8 + $suit2[2] * 1e+6 + $suit2[3] * 1e+4 + $suit2[4] * 1e+2; } } else if (count($suit3) >= 5) { //        5 $result = straightFlush($suit3); if(0 == $result) { foreach ($suit3 as $key3 => $s3) { $suit3[$key3] = $s3 % 100; } rsort($suit3); $result = $suit3[0] * 1e+10 + $suit3[1] * 1e+8 + $suit3[2] * 1e+6 + $suit3[3] * 1e+4 + $suit3[4] * 1e+2; } } else if (count($suit4) >= 5) { //        5 $result = straightFlush($suit4); if(0 == $result) { foreach ($suit4 as $key4 => $s4) { $suit4[$key4] = $s4 % 100; } rsort($suit4); $result = $suit4[0] * 1e+10 + $suit4[1] * 1e+8 + $suit4[2] * 1e+6 + $suit4[3] * 1e+4 + $suit4[4] * 1e+2; } } else { $result = 0; } return $result; }
      
      





Street Flushを決定する関数(Streetと同様、配列内の要素の数は7だけでなく、5、6でもあり、この関数の返される結果は大きくなければならないことを考慮する必要があります):



 function straightFlush(array $arrayCards) { $newArrayCards = []; $ace = false; foreach ($arrayCards as $arrayCard) { $newArrayCards = array_merge($newArrayCards, [$arrayCard % 100]); if (14 == $arrayCard % 100) { $ace = true; } } if ($ace == true) { $newArrayCards = array_merge($newArrayCards, [1]); } rsort($newArrayCards); $count = 0; $length = 4; $result = 0; $begin = 0; for ($i = 1; $i <= $length; $i++) { if (-1 == ($newArrayCards[$i] - $newArrayCards[$i - 1])) { $count++; } if ($length == $i) { if (4 == $count) { $result = $newArrayCards[$begin] * 1e+16; } else if ((7 == count($arrayCards) and ($length < 6 or (6 == $length and $ace == true))) or (6 == count($arrayCards) and ($length < 5 or (5 == $length and $ace == true))) or //     = 6 (5 == count($arrayCards) and (5 == $length and $ace == true))) { //     = 5 $length++; $begin++; $i = $begin; $count = 0; } } } return $result; }
      
      





ペアの組み合わせの定義と計算



5つのペアの組み合わせがあります:4種類(同じ値の4枚のカード)、フルハウス(同じ値の3枚のカードと他の値の2枚のカード)、3(同じ値の3枚のカード)、2ペア(同じ値の2枚のカードと他の値の2枚のカード)、ペア(同じ値の2枚のカード)。



完全な家の組み合わせでは、主なものは3枚のカードの組み合わせであり、2枚の2枚目のカードの組み合わせであることを覚えておくことが重要です。たとえば、3の2と2ダースの組み合わせは3 * 1e + 12 +と見なされます10 * 1e + 10、カードの価値ではありません。



また、ペアの組み合わせを計算するときは、問題を考慮する必要があります。



1. 5枚以上のカードが組み合わせを形成するという事実。

2.複数の組み合わせがある状況があるかもしれないという事実。



カードの一致を計算するには、デッキ内のペアのカードをカウントする3つのカウンターを使用します。 カウンターが1-2枚の場合、カウンターは2-3枚、3-4枚の場合です。



可能なすべてのカウンターの組み合わせを検討してください。



100-ペア

110-2ペア

111-3ペア(タイプ110(2ペア)に変換する必要があります)

200-3

210-フルハウス

120-フルハウス(タイプ210(フルハウス)に変換する必要があります)

211(121、112)-フルハウス+カップル(タイプ210(フルハウス)に変換する必要があります)

220-2トリプルまたはフルハウス+ 1カード(タイプ210(フルハウス)に変換する必要があります)

300-正方形

310(130)-正方形+ペア(タイプ300(正方形)に変換する必要があります)

320(230)-正方形+ 3(タイプ300(正方形)に変換する必要があります)

次に、ペアの組み合わせの最終計算を行います。



 function couple(array $arrayCards) { $newArrayCards = []; foreach ($arrayCards as $arrayCard) { $newArrayCards = array_merge($newArrayCards, [$arrayCard % 100]); //       100 } rsort($newArrayCards); //       $count1 = 0; //    $count2 = 0; //    $count3 = 0; //    $match1 = 0; //     $match2 = 0; //     $match3 = 0; //     for($i = 1; $i < count($newArrayCards); $i++) { if ($newArrayCards[$i] == $match1 or $match1 == 0) { //   if ($newArrayCards[$i] == $newArrayCards[$i - 1]) { $match1 = $newArrayCards[$i]; $count1++; } } else if ($newArrayCards[$i] == $match2 or $match2 == 0) { //   if ($newArrayCards[$i] == $newArrayCards[$i - 1]) { $match2 = $newArrayCards[$i]; $count2++; } } else if ($newArrayCards[$i] == $match3 or $match3 == 0) { //   if ($newArrayCards[$i] == $newArrayCards[$i - 1]) { $match3 = $newArrayCards[$i]; $count3++; } } } //   111  110 (2 )  211  210 ( ) if(($count1 == 1 or $count1 == 2) and $count2 == 1 and $count3 == 1) { $count3 = 0; } //   121   211   ,    210 ( ) else if($count2 == 2 and $count1 == 1 and $count3 == 1) { $support = $match2; $match2 = $match1; $match1 = $support; $count1 = 2; $count2 = 1; $count3 = 0; } //   112   211   ,    210 ( ) else if($count3 == 2 and $count1 == 1 and $count2 == 1) { $support = $match3; $match2 = $match1; $match1 = $support; $count1 = 2; $count3 = 0; } //   220  210 ( ) else if($count1 == 2 and $count2 == 2 and $count3 == 0) { $count2 = 1; } //   120  210 ( ) else if ($count1 == 1 and $count2 == 2 and $count3 == 0) { $support = $match1; $match1 = $match2; $match2 = $support; $count1 = 2; $count2 = 1; } //320  300  310  300 else if($count1 == 3 and ($count2 == 2 or $count2 == 1)) { $count2 = 0; } //230  320    300  130  310    300 else if($count2 == 3 and($count1 == 2 or $count1 == 1)) { $support = $match2; $match2 = $match1; $match1 = $support; $count1 = 3; $count2 = 0; } // if ($count1 == 3) { $count1 = 1e+14; } //  else if ($count1 == 2 and $count2 == 1) { $count1 = 1e+12; $count2 = 1e+10; } // else if ($count1 == 2 and $count2 == 0) { $count1 = 1e+6; } //2  else if ($count1 == 1 and $count2 == 1) { $count1 = 1e+4; $count2 = 1e+2; } // else if ($count1 == 1 and $count2 == 0) { $count1 = 1e+2; } $result = $match1 * $count1 + $match2 * $count2;// $match1  $match2   0,     return $result; }
      
      





最終決済



これで、ストレート、フラッシュ、ストレートフラッシュ、ペアの組み合わせについてカードの配列をチェックする関数ができました。 それらを一緒に呼び出して最終結果を計算し、最高のカードを計算することも覚えています。



高いカード計算:



1.最高優先順位と最低優先順位のポケットカードを決定します。 これを行うには、100による除算の残りの部分と比較します(%100)。

2.最高の優先度のマップに、最低の優先度を100で割った値を追加します。



 function priority(array $arrayCards) { //     if($arrayCards[5] % 100 > $arrayCards[6] % 100) { //,      -  $highCard1 = $arrayCards[5] % 100; $highCard2 = $arrayCards[6] % 100; } else { $highCard1 = $arrayCards[6] % 100; $highCard2 = $arrayCards[5] % 100; } $flush = pokerFlush($arrayCards); //     $straight = straight($arrayCards); //     $couple = couple($arrayCards); //     //      if($flush >= 1e+16) { $result = $flush; //  } else if($couple >= 1e+14 and $couple < 1e+16) { $result = $couple; // } else if($couple >= 1e+12 and $couple < 1e+14) { $result = $couple; //  } else if($flush >= 1e+10) { $result = $flush; // } else if($straight >= 1e+8 and $straight < 1e+10) { $result = $straight; // } else if($couple >= 1e+6 and $couple < 1e+8) { $result = $couple; // } else if($couple >= 1e+4 and $couple < 1e+6) { $result = $couple; //  } else if($couple >= 1e+2 and $couple < 1e+4) { $result = $couple; // } else { $result = $highCard1 + $highCard2 * 1e-2; //  } return $result; }
      
      





画面出力について



divの背景画像として、このようなスプライトを使用して結果をブラウザーに出力しました(サイトから写真を撮影しました: fondhristianin.ru/?p = 2941 )。







divの幅と高さは、1つのマップのサイズに等しく設定されました。 画像サイズが572px * 328px(この場合)で、カード数の幅が13である場合、高さは5、幅と高さは44px * 65.6pxに設定されました。 次に、以前に作成したマップ配列を考慮して、背景の位置を変更しました。



x軸に沿ったdivのバックグラウンド位置の計算:



 100/12 * ($arrayCards[$i] % 100 - 2)
      
      





ここで、$ arrayCardsは以前に形成された配列です。

$ iはカードのシリアル番号です。



計算の説明:

行には13枚のカードがあり、1枚目のカードの始まりは0%、13枚目のカードの始まりは100%です。したがって、位置の差は100%/ 12(13ではありません)です。 カードの数を[2-14、102-114、202-214、302-314]の形式から[0-12]にします。 これを行うには、カード番号の残りを取り、残り2から減算します。結果の番号に位置の差を掛けます。



y軸に沿ったdivのバックグラウンド位置の計算:



 100/4 * floor($arrayCards[$i] / 100)
      
      





計算の説明:

1枚目のカードの始まり-0%、5枚目のカードの始まり-100%の5枚のカードがあるため、位置の差は100%/ 4(5ではない)です。 カードの数を[2-14、102-114、202-214、302-314]の形式から[0-3]にします。 これを行うには、カードの番号を100で割り、切り捨てます(単純な丸め操作を使用できます。同じように機能します)。 結果の数値に位置の差を掛けます。



All Articles