mirror of
https://github.com/correl/euler.git
synced 2024-11-27 19:19:50 +00:00
Modified the class to accept more than 5 cards. Currently brute-forces
to find the best possible hand. git-svn-id: file:///srv/svn/euler@8 e5f4c3ec-3c0c-11df-b522-21efaa4426b5
This commit is contained in:
parent
de333d0940
commit
df93303499
2 changed files with 65 additions and 0 deletions
28
054/poker.py
28
054/poker.py
|
@ -5,6 +5,15 @@ class InvalidCard(Exception):
|
||||||
class InvalidHand(Exception):
|
class InvalidHand(Exception):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
def unique_combinations(items, n):
|
||||||
|
if n==0: yield []
|
||||||
|
else:
|
||||||
|
for i in xrange(len(items)):
|
||||||
|
for cc in unique_combinations(items[i+1:],n-1):
|
||||||
|
yield [items[i]]+cc
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class Card:
|
class Card:
|
||||||
values = {'T': 10, 'J': 11, 'Q': 12, 'K': 13, 'A': 14}
|
values = {'T': 10, 'J': 11, 'Q': 12, 'K': 13, 'A': 14}
|
||||||
def __init__(self, string):
|
def __init__(self, string):
|
||||||
|
@ -117,6 +126,25 @@ class Hand:
|
||||||
self.rank()
|
self.rank()
|
||||||
return self.__values
|
return self.__values
|
||||||
@staticmethod
|
@staticmethod
|
||||||
|
def create_best_hand(cards):
|
||||||
|
if len(cards) == 5:
|
||||||
|
return Hand(cards)
|
||||||
|
elif len(cards) < 5:
|
||||||
|
raise InvalidHand
|
||||||
|
else:
|
||||||
|
return Hand.create_best_hand_bruteforce(cards)
|
||||||
|
return false
|
||||||
|
@staticmethod
|
||||||
|
def create_best_hand_bruteforce(cards):
|
||||||
|
combos = unique_combinations(cards, 5)
|
||||||
|
hands = [Hand(combo) for combo in combos]
|
||||||
|
hands = sorted(hands, cmp=Hand.compare, reverse=True)
|
||||||
|
return hands[0]
|
||||||
|
@staticmethod
|
||||||
|
def create_best_hand_smart(cards):
|
||||||
|
#TODO: Figure out a smarter algorithm for getting the best hand!
|
||||||
|
pass
|
||||||
|
@staticmethod
|
||||||
def compare(a, b):
|
def compare(a, b):
|
||||||
# Compare hand rankings
|
# Compare hand rankings
|
||||||
result = cmp(a.rank(), b.rank())
|
result = cmp(a.rank(), b.rank())
|
||||||
|
|
37
054/test.py
37
054/test.py
|
@ -56,5 +56,42 @@ class TestFiveCardHands(unittest.TestCase):
|
||||||
else:
|
else:
|
||||||
self.assertTrue(hand.rank() > hand2.rank(), '{0} > {1}'.format(poker.Hand.RANKS[rank], poker.Hand.RANKS[rank2]))
|
self.assertTrue(hand.rank() > hand2.rank(), '{0} > {1}'.format(poker.Hand.RANKS[rank], poker.Hand.RANKS[rank2]))
|
||||||
|
|
||||||
|
class TestSevenCardHands(unittest.TestCase):
|
||||||
|
def setUp(self):
|
||||||
|
self.rank_hands = {
|
||||||
|
poker.Hand.HIGH_CARD: poker.Hand.create_best_hand(['5D', '8C', '9S', 'JS', '4C', '3D', 'AC']),
|
||||||
|
poker.Hand.ONE_PAIR: poker.Hand.create_best_hand(['5H', 'JC', '6S', '7S', 'KD', '4C', '5C']),
|
||||||
|
poker.Hand.TWO_PAIRS: poker.Hand.create_best_hand(['2D', '3C', '2H', '7S', 'JC', '8H', '7H']),
|
||||||
|
poker.Hand.THREE_OF_A_KIND: poker.Hand.create_best_hand(['AS', '2D', 'TH', 'AH', 'JC', '8S', 'AC']),
|
||||||
|
poker.Hand.STRAIGHT: poker.Hand.create_best_hand(['9D', '5S', '7H', '8S', '2H', 'AC', '6S']),
|
||||||
|
poker.Hand.FLUSH: poker.Hand.create_best_hand(['7S', 'TS', 'KS', '3S', 'AC', '3H', 'JS']),
|
||||||
|
poker.Hand.FULL_HOUSE: poker.Hand.create_best_hand(['6S', '2D', '2H', '6D', '8C', '4S', '6H']),
|
||||||
|
poker.Hand.FOUR_OF_A_KIND: poker.Hand.create_best_hand(['7S', '7H', '7D', '2H', '8D', '9D', '7C']),
|
||||||
|
poker.Hand.STRAIGHT_FLUSH: poker.Hand.create_best_hand(['JS', '8S', 'QS', 'TS', '4D', '2S', '9S']),
|
||||||
|
poker.Hand.ROYAL_FLUSH: poker.Hand.create_best_hand(['QH', 'TH', 'JH', 'KH', '9H', '6S', 'AH']),
|
||||||
|
}
|
||||||
|
def test_hand_rankings(self):
|
||||||
|
for rank, hand in self.rank_hands.iteritems():
|
||||||
|
self.assertEqual(hand.rank(), rank, 'Ranking hand: {0}'.format(poker.Hand.RANKS[rank]))
|
||||||
|
def test_ace_high_straight(self):
|
||||||
|
hand = poker.Hand.create_best_hand(['AH', 'KS', 'QC', 'JS', '9S', '7D', 'TS'])
|
||||||
|
self.assertEqual([hand.rank(), hand.values()], [poker.Hand.STRAIGHT, [14, 13, 12, 11, 10]])
|
||||||
|
def test_ace_low_straight(self):
|
||||||
|
hand = poker.Hand.create_best_hand(['AH', '2S', '3C', '4S', '6D', '4C', '5S'])
|
||||||
|
self.assertEqual([hand.rank(), hand.values()], [poker.Hand.STRAIGHT, [14, 5, 4, 3, 2]])
|
||||||
|
def test_compare_ace_low_straight(self):
|
||||||
|
low = poker.Hand.create_best_hand(['AH', '2S', '3C', '4S', '6D', '4C', '5S'])
|
||||||
|
high = poker.Hand.create_best_hand(['2S', '3C', '4S', '5S', '8D', 'TC', '6S'])
|
||||||
|
self.assertTrue(low < high)
|
||||||
|
def test_compare_ranks(self):
|
||||||
|
for rank, hand in self.rank_hands.iteritems():
|
||||||
|
for rank2, hand2 in self.rank_hands.iteritems():
|
||||||
|
if (rank == rank2):
|
||||||
|
self.assertEqual(hand.rank(), hand2.rank(), '{0} == {1}'.format(poker.Hand.RANKS[rank], poker.Hand.RANKS[rank2]))
|
||||||
|
elif (rank < rank2):
|
||||||
|
self.assertTrue(hand.rank() < hand2.rank(), '{0} < {1}'.format(poker.Hand.RANKS[rank], poker.Hand.RANKS[rank2]))
|
||||||
|
else:
|
||||||
|
self.assertTrue(hand.rank() > hand2.rank(), '{0} > {1}'.format(poker.Hand.RANKS[rank], poker.Hand.RANKS[rank2]))
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
unittest.main()
|
unittest.main()
|
Loading…
Reference in a new issue