2016年11月6日日曜日

開発環境

Think Python (Allen B. Downey (著)、 O'Reilly Media)のChapter 18.(Inheritance)のExercises 18-3-5.(No. 4220)を取り組んでみる。

Exercises 18-3-5.(No. 4220)

コード(Emacs)

#!/usr/bin/env python3
# -*- coding: utf-8 -*-

from Card import Hand, Deck, Card


class PokerHand(Hand):
    size = 5

    def suit_hist(self):
        """Builds a histogram of the suits that appear in the hand.

        Stores the result in attribute suits.
        """
        self.suits = {}
        for card in self.cards:
            self.suits[card.suit] = self.suits.get(card.suit, 0) + 1

    def rank_hist(self):
        self.ranks = {}
        for card in self.cards:
            self.ranks[card.rank] = self.ranks.get(card.rank, 0) + 1

    def has_flush(self):
        """Returns True if the hand has a flush, False otherwise.

        Note that this works correctly for hands with more than 5 cards.
        """
        self.suit_hist()
        for val in self.suits.values():
            if val >= 5:
                return True
        return False

    def has_pair(self):
        self.rank_hist()
        for val in self.ranks.values():
            if val == 2:
                return True
        return False

    def has_twopair(self):
        self.rank_hist()
        count = 0
        for val in self.ranks.values():
            if val == 2:
                if count == 0:
                    count = 1
                else:
                    return True
        return False

    def has_three_of_kind(self):
        self.rank_hist()
        for val in self.ranks.values():
            if val == 3:
                return True
        return False

    def has_straight(self):
        self.rank_hist()
        ks = self.ranks.keys()
        start = 1
        stop = 13 - (PokerHand.size - 1) + 1
        for n in range(start, stop):
            for m in range(n, n + PokerHand.size):
                if m not in ks:
                    break
            else:
                return True
        if 1 in ks:
            start = 13 - (PokerHand.size - 1) + 1
            stop = start + PokerHand.size - 1
            for n in range(start, stop):
                if n not in ks:
                    return False
            return True
        return False

    def has_full_house(self):
        return self.has_pair() and self.has_three_of_kind()

    def has_four_of_kind(self):
        self.rank_hist()
        for val in self.ranks.values():
            if val == 4:
                return True
        return False

    def has_straight_flush(self):
        return self.has_straight() and self.has_flush()

    labels = {
        'pair': has_pair,
        'two pair': has_twopair,
        'three of a kind': has_three_of_kind,
        'straight': has_straight,
        'flush': has_flush,
        'full house': has_full_house,
        'four of a kind': has_four_of_kind,
        'straight flush': has_straight_flush
    }

    def classify(self):
        for k, v in PokerHand.labels.items():
            if v(self):
                self.label = k


def deal(hand_n, card_n):
    deck = Deck()
    deck.shuffle()
    hands = []
    for _ in range(hand_n):
        hand = PokerHand()
        deck.move_cards(hand, card_n)
        hands.append(hand)
    classifications = []
    for hand in hands:
        hand.classify()
        classifications.append(hand.label)
    return classifications


if __name__ == '__main__':
    for _ in range(20):
        classifications = deal(5, 10)
        count = {}
        for label in classifications:
            count[label] = count.get(label, 0) + 1
        print(count)

入出力結果(Terminal, IPython)

$ ./PokerHand.py
{'pair': 2, 'three of a kind': 3}
{'pair': 2, 'three of a kind': 1, 'straight': 2}
{'pair': 4, 'straight': 1}
{'pair': 4, 'three of a kind': 1}
{'pair': 2, 'three of a kind': 3}
{'pair': 5}
{'pair': 1, 'three of a kind': 3, 'straight': 1}
{'pair': 3, 'straight': 2}
{'pair': 1, 'three of a kind': 3, 'straight': 1}
{'': 1, 'pair': 1, 'three of a kind': 3}
{'pair': 2, 'three of a kind': 3}
{'pair': 2, 'three of a kind': 1, 'straight': 1, 'four of a kind': 1}
{'pair': 4, 'straight': 1}
{'': 1, 'pair': 1, 'three of a kind': 1, 'straight': 2}
{'pair': 1, 'three of a kind': 2, 'straight': 2}
{'pair': 3, 'three of a kind': 1, 'straight': 1}
{'pair': 2, 'three of a kind': 1, 'straight': 2}
{'pair': 3, 'straight': 2}
{'pair': 5}
{'': 1, 'pair': 3, 'straight': 1}
$ ./PokerHand.py
{'straight flush': 1, 'two pair': 4}
{'two pair': 5}
{'full house': 1, 'flush': 1, 'two pair': 3}
{'pair': 1, 'two pair': 4}
{'full house': 1, 'two pair': 4}
{'straight': 2, 'straight flush': 1, 'two pair': 2}
{'straight': 1, 'two pair': 4}
{'full house': 1, 'straight': 1, 'three of a kind': 1, 'two pair': 2}
{'two pair': 5}
{'pair': 1, 'two pair': 4}
{'full house': 1, 'straight': 1, 'two pair': 3}
{'pair': 1, 'straight flush': 1, 'two pair': 3}
{'full house': 1, 'two pair': 4}
{'pair': 1, 'three of a kind': 1, 'two pair': 3}
{'three of a kind': 1, 'two pair': 4}
{'flush': 1, 'two pair': 4}
{'straight': 1, 'two pair': 4}
{'full house': 2, 'flush': 1, 'two pair': 2}
{'pair': 2, 'straight flush': 1, 'two pair': 2}
{'full house': 1, 'three of a kind': 1, 'two pair': 3}
$ 

0 コメント:

コメントを投稿