mirror of
https://github.com/correl/euler.git
synced 2024-12-27 11:07:34 +00:00
Documentation for the poker classes
git-svn-id: file:///srv/svn/euler@14 e5f4c3ec-3c0c-11df-b522-21efaa4426b5
This commit is contained in:
parent
519824caee
commit
e2d55968e3
1 changed files with 63 additions and 3 deletions
66
054/poker.py
66
054/poker.py
|
@ -1,8 +1,16 @@
|
||||||
import operator
|
import operator
|
||||||
|
|
||||||
class InvalidCard(Exception):
|
class InvalidCard(Exception):
|
||||||
|
"""Invalid Card Exception
|
||||||
|
|
||||||
|
Thrown if an invalid face value or suit is supplied for a card
|
||||||
|
"""
|
||||||
pass
|
pass
|
||||||
class InvalidHand(Exception):
|
class InvalidHand(Exception):
|
||||||
|
"""Invalid Hand Exception
|
||||||
|
|
||||||
|
Thrown if the hand being created includes zero or more than 5 cards
|
||||||
|
"""
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def unique_combinations(items, n):
|
def unique_combinations(items, n):
|
||||||
|
@ -15,6 +23,8 @@ def unique_combinations(items, n):
|
||||||
|
|
||||||
|
|
||||||
class Card:
|
class Card:
|
||||||
|
"""Represents a single poker playing card"""
|
||||||
|
|
||||||
VALUES = {'T': 10, 'J': 11, 'Q': 12, 'K': 13, 'A': 14}
|
VALUES = {'T': 10, 'J': 11, 'Q': 12, 'K': 13, 'A': 14}
|
||||||
SUITS = {'Hearts': 'H', 'Diamonds': 'D', 'Clubs': 'C', 'Spades': 'S'}
|
SUITS = {'Hearts': 'H', 'Diamonds': 'D', 'Clubs': 'C', 'Spades': 'S'}
|
||||||
def __init__(self, string):
|
def __init__(self, string):
|
||||||
|
@ -30,8 +40,14 @@ class Card:
|
||||||
if not self.suit in Card.SUITS.values():
|
if not self.suit in Card.SUITS.values():
|
||||||
raise InvalidCard('Invalid suit: {0}'.format(string))
|
raise InvalidCard('Invalid suit: {0}'.format(string))
|
||||||
def __cmp__(self, other):
|
def __cmp__(self, other):
|
||||||
|
"""Compare hand values
|
||||||
|
|
||||||
|
Compares this card's value with another. Used for sorting.
|
||||||
|
"""
|
||||||
|
|
||||||
return cmp(self.value, other.value)
|
return cmp(self.value, other.value)
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
|
"""Builds a string representation of the hand"""
|
||||||
val = self.value
|
val = self.value
|
||||||
for k, v in Card.VALUES.iteritems():
|
for k, v in Card.VALUES.iteritems():
|
||||||
if self.value == v:
|
if self.value == v:
|
||||||
|
@ -69,11 +85,18 @@ class Hand:
|
||||||
self.__values = []
|
self.__values = []
|
||||||
self.rank()
|
self.rank()
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
|
"""Builds a string representation of the hand"""
|
||||||
return str.format("Cards: {0} Rank: '{1}' Values: {2}",
|
return str.format("Cards: {0} Rank: '{1}' Values: {2}",
|
||||||
[str(c.value) + c.suit for c in self.__cards],
|
[str(c.value) + c.suit for c in self.__cards],
|
||||||
Hand.RANKS[self.rank()],
|
Hand.RANKS[self.rank()],
|
||||||
self.values())
|
self.values())
|
||||||
def rank(self):
|
def rank(self):
|
||||||
|
"""Get the hand rank
|
||||||
|
|
||||||
|
Determines the rank of the poker hand if it has not already been
|
||||||
|
computed, and returns it.
|
||||||
|
"""
|
||||||
|
|
||||||
if self.__rank:
|
if self.__rank:
|
||||||
return self.__rank
|
return self.__rank
|
||||||
flush = True
|
flush = True
|
||||||
|
@ -129,11 +152,35 @@ class Hand:
|
||||||
|
|
||||||
return self.__rank
|
return self.__rank
|
||||||
def values(self):
|
def values(self):
|
||||||
|
"""Returns a list of card values for the hand
|
||||||
|
|
||||||
|
Values for sets are provided first in order of importance and descending
|
||||||
|
strength, followed by all additional card values in order of descending
|
||||||
|
strength. Used for comparison and sorting.
|
||||||
|
|
||||||
|
Examples:
|
||||||
|
Full House ['5S', '5D', '5H', '8S', '8C']
|
||||||
|
Values = [5, 8]
|
||||||
|
|
||||||
|
Two Pair ['9D', '9S', '5H', '5C', 'KH']
|
||||||
|
Values = [9, 5, 13]
|
||||||
|
|
||||||
|
Straight ['AS', '2H', '3C', '4C', '5H']
|
||||||
|
Values = [5, 4, 3, 2, 1]
|
||||||
|
"""
|
||||||
if not self.__values:
|
if not self.__values:
|
||||||
self.rank()
|
self.rank()
|
||||||
return self.__values
|
return self.__values
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def create_best_hand(cards):
|
def create_best_hand(cards):
|
||||||
|
"""Create the strongest possible poker hand
|
||||||
|
|
||||||
|
Using the supplied cards, this will build the strongest possible five-
|
||||||
|
card poker hand.
|
||||||
|
|
||||||
|
Uses smart hand creation if more than five cards are specified.
|
||||||
|
"""
|
||||||
|
|
||||||
if len(cards) == 5:
|
if len(cards) == 5:
|
||||||
return Hand(cards)
|
return Hand(cards)
|
||||||
elif len(cards) < 5:
|
elif len(cards) < 5:
|
||||||
|
@ -143,14 +190,22 @@ class Hand:
|
||||||
return false
|
return false
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def create_best_hand_bruteforce(cards):
|
def create_best_hand_bruteforce(cards):
|
||||||
|
"""Create the strongest possible poker hand
|
||||||
|
|
||||||
|
Builds every possible poker hand from the supplied set of cards, and
|
||||||
|
returns the strongest result.
|
||||||
|
"""
|
||||||
|
|
||||||
combos = unique_combinations(cards, 5)
|
combos = unique_combinations(cards, 5)
|
||||||
hands = [Hand(combo) for combo in combos]
|
hands = [Hand(combo) for combo in combos]
|
||||||
hands = sorted(hands, reverse=True)
|
hands = sorted(hands, reverse=True)
|
||||||
return hands[0]
|
return hands[0]
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def create_best_hand_smart(cards):
|
def create_best_hand_smart(cards):
|
||||||
"""
|
"""Create the strongest possible poker hand
|
||||||
TODO: Implement the following logic (or something better):
|
|
||||||
|
Intelligently seeks out the strongest possible poker hand from the
|
||||||
|
supplied set of cards using the following steps:
|
||||||
|
|
||||||
* Find all flushes
|
* Find all flushes
|
||||||
* Find all straights
|
* Find all straights
|
||||||
|
@ -240,7 +295,12 @@ class Hand:
|
||||||
# High card, send the top 5 reverse-sorted cards
|
# High card, send the top 5 reverse-sorted cards
|
||||||
return Hand([str(c) for c in cards[:5]])
|
return Hand([str(c) for c in cards[:5]])
|
||||||
def __cmp__(self, other):
|
def __cmp__(self, other):
|
||||||
# Compare hand rankings
|
"""Compare hand rankings
|
||||||
|
|
||||||
|
Compares this hand with another by first checking rank, and if they are
|
||||||
|
equal in that regard, by their card values. Used for sorting.
|
||||||
|
"""
|
||||||
|
|
||||||
result = cmp(self.rank(), other.rank())
|
result = cmp(self.rank(), other.rank())
|
||||||
if (result == 0):
|
if (result == 0):
|
||||||
# Compare hand values
|
# Compare hand values
|
||||||
|
|
Loading…
Reference in a new issue