開発環境
- macOS Sierra - Apple (OS)
- Emacs (Text Editor)
- Python 3.5 (プログラミング言語)
Think Python (Allen B. Downey (著)、 O'Reilly Media)のChapter 18.(Inheritance)のExercises 18-3-6.(No. 4220)を取り組んでみる。
Exercises 18-3-6.(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 = {
'straight flush': has_straight_flush,
'four of a kind': has_four_of_kind,
'full house': has_full_house,
'flush': has_flush,
'straight': has_straight,
'three of a kind': has_three_of_kind,
'two pair': has_twopair,
'pair': has_pair,
}
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__':
count = {}
n = 10000
for _ in range(n):
classifications = deal(5, 10)
for label in classifications:
count[label] = count.get(label, 0) + 1
s = sum(count.values())
for k, v in sorted(count.items(), key=lambda x: x[1]):
if k == '':
continue
print('{0:15}: {1:10.5f}%'.format(k, v / s * 100))
入出力結果(Terminal, IPython)
$ ./PokerHand.py four of a kind : 0.73400% three of a kind: 3.83600% straight flush : 6.53600% flush : 13.36600% straight : 17.14400% full house : 17.57400% pair : 40.56000% $
0 コメント:
コメントを投稿