ホームページ >バックエンド開発 >Python チュートリアル >インデックスとポーカー ゲーム
Mohammad S. Anwar は毎週、毎週 2 つのタスクに対する解決策を全員が考え出すチャンスであるウィークリー チャレンジを送信します。私のソリューションは最初に Python で書かれ、次に Perl に変換されます。これは、私たち全員がコーディングを練習するのに最適な方法です。
挑戦、私の解決策
整数の配列 @ints が与えられます。
左端の中間インデックス (MI)、つまり可能なすべてのインデックスの中で最小のものを見つけるスクリプトを作成します。
中間インデックスは、ints[0] ints[1] … ints[MI-1] == ints[MI 1] ints[MI 2] … ints[ints.length-1] のインデックスです。
これは比較的簡単です。 0 から入力の長さより 1 小さい位置までループします。各位置で条件が満たされているかどうかを確認します。
def middle_index(ints: list) -> int: for i in range(len(ints)): if sum(ints[:i]) == sum(ints[i + 1:]): # It is, so return this position return i return -1
$ ./ch-1.py 2 3 -1 8 4 3 $ ./ch-1.py 1 -1 4 2 $ ./ch-1.py 2 5 -1
ドロー ポーカー ハンドは、52 枚のパックから引き出された 5 枚のカードで構成されます。ジョーカーやワイルド カードは含まれません。エースは上位または下位にランク付けされます。
次の 3 つのことを決定するスクリプトを作成します。
長い投稿になるので、最後までお付き合いください。また、入力を必要としないタスクも久しぶりです。私がクリアしたチャレンジの中で、最後のチャレンジは #177 でした。
最初の質問に答えると、配られるカードの組み合わせは 311,875,200 通りあります (52 × 51 × 50 × 49 × 48)。ただし、カードの順序は関係ありません。引いた5枚のカードは、5×4×3×2×1の120通りの配置が可能です。したがって、2,598,960 通りの一意の組み合わせが存在します。
まず、トランプのデッキを作成します。このために、1 から 13 までのランク (カード番号) を持っています。1 はエース、2 から 10 は数字、11 はジャック、12 はクイーン、キングは 13 です。また、スーツ s、c、d もあります。および h (それぞれスペア、クラブ、ダイヤモンド、ハート)。ダブル for ループを使用して、52 枚すべてのカード (ランクとスートのタプル) を生成し、これをデッキと呼ばれるリストに保存します。
次に、デッキの 5 枚のカードの組み合わせをそれぞれループして、どのハンドを持っているかを決定します。最後に結果を印刷します。
def middle_index(ints: list) -> int: for i in range(len(ints)): if sum(ints[:i]) == sum(ints[i + 1:]): # It is, so return this position return i return -1
それは簡単です:)
get_hands 関数では、ランク (カード上の数字) とスート (カード上のシンボル) でソートされたリストの辞書を作成することから始めます。ハンドを決定するためによく使用されるため、ランクの頻度もカウントします。
$ ./ch-1.py 2 3 -1 8 4 3 $ ./ch-1.py 1 -1 4 2 $ ./ch-1.py 2 5 -1
したがって、カード 10s、10h、9d、8h、2d の場合、次のように設定されます:
次に、私がどの手を握っているかを判断します。まずはストレートフラッシュとフラッシュから始めます。これらはカードのスーツを考慮する唯一のハンドであり、ファイブのカードはすべて同じスーツです。これは、cards_by_suit dict に値が 1 つだけある場合に決定されます。
ストレート フラッシュかどうかを判断するために、カードを番号順 (1 ~ 13) に並べます。最初のカードが 1 (エース) で、最後のカードが 13 (キング) の場合、最初のカードを削除し、リストの最後に 14 を追加します。これにより、10、ジャック、クイーン、キング、エースがストレート フラッシュとみなされるようになります。最初のカードの番号と最後のカードの番号の差が 4 の場合、ストレート フラッシュが発生します。
from collections import Counter, defaultdict from itertools import combinations def main(): deck = [(rank, suit) for rank in range(1, 14) for suit in ('s', 'c', 'd', 'h')] hands = defaultdict(int) for cards in combinations(deck, 5): hand = get_hand(cards) hands[hand] += 1 display_results(hands)
フォー カード ハンド (1 つのランクの 4 枚とランダムな最後のカード) とフルハウス (1 つのランクの 3 枚、異なるランクの 2 枚) の場合、count_by_rank dict を使用してハンドが一致するかどうかを確認できます。指定された基準。
def get_hand(cards): cards_by_rank = defaultdict(list) cards_by_suit = defaultdict(list) for card in cards: number, suit = card cards_by_rank[number].append(card[1]) cards_by_suit[suit].append(card[0]) count_by_rank = Counter(len(cards_by_rank[r]) for r in cards_by_rank)
ハンドがストレートかどうかを判断するために、ストレート フラッシュと同様のロジックを使用します。まず、固有のランク (カード番号) が 5 つあることを確認し、それらを順序付け、必要に応じてエースを移動し、高位と低位の差が 4 であるかどうかを確認します。
if len(cards_by_suit) == 1: cards = sorted(cards_by_rank) if cards[0] == 1 and cards[4] == 13: cards.pop(0) cards.append(14) if cards[4] - cards[0] == 4: return 'Straight flush' return 'Flush'
スリー カード (同じランクのカード 3 枚、異なるランクのカード 2 枚)、2 ペア (同じランクのカード 2 枚、異なるランクのカード 2 枚、ランダムな最後のカード)、1 ペア (1 つのランクのカード 2 枚)ランク、それぞれ異なるランクの 3 枚のカード) はすべて count_by_rank dict を使用して計算できます。
if count_by_rank[4]: return 'Four of a kind' if count_by_rank[3] and count_by_rank[2]: return 'Full house'
最後に、何も一致しない場合は、「ハイ カード」を返します。このハンドを持っているなら、間違いなく自分のハウスを賭けたくないでしょう :)
if len(cards_by_rank) == 5: # Get the card ranks in the possible flush cards = sorted(cards_by_rank) if cards[0] == 1 and cards[4] == 13: cards.pop(0) cards.append(14) if cards[4] - cards[0] == 4: return 'Straight'
display_results 関数は、結果を (ランク順に) 統一されたレイアウトで表示するだけです。冒頭で述べたように、各組み合わせには 120 の順列があり、カードを注文できます。
if count_by_rank[3]: return 'Three of a kind' if count_by_rank[2] == 2: return 'Two pair' if count_by_rank[2]: return 'One pair'
return 'High card'
これを自宅の PC で実行するのに約 15 秒かかりました。
下の行からわかるように、2,598,960 の組み合わせと 311,875,200 の順列があります。これは、出力に表示されると予想されるものと一致します。
以上がインデックスとポーカー ゲームの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。