From df933034992c49a1cdef3410852d9b6cd387bb0a Mon Sep 17 00:00:00 2001 From: Correl Roush Date: Wed, 31 Mar 2010 19:48:53 +0000 Subject: [PATCH] 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 --- 054/poker.py | 28 ++++++++++++++++++++++++++++ 054/test.py | 37 +++++++++++++++++++++++++++++++++++++ 2 files changed, 65 insertions(+) diff --git a/054/poker.py b/054/poker.py index c43bf24..ce9f166 100644 --- a/054/poker.py +++ b/054/poker.py @@ -5,6 +5,15 @@ class InvalidCard(Exception): class InvalidHand(Exception): 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: values = {'T': 10, 'J': 11, 'Q': 12, 'K': 13, 'A': 14} def __init__(self, string): @@ -117,6 +126,25 @@ class Hand: self.rank() return self.__values @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): # Compare hand rankings result = cmp(a.rank(), b.rank()) diff --git a/054/test.py b/054/test.py index ce0dff5..321f71d 100644 --- a/054/test.py +++ b/054/test.py @@ -56,5 +56,42 @@ class TestFiveCardHands(unittest.TestCase): else: 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__': unittest.main() \ No newline at end of file