Updated class comparisons to use the magic __cmp__ method. Fixed ace low

straight values. Fixed broken comparison tests.


git-svn-id: file:///srv/svn/euler@9 e5f4c3ec-3c0c-11df-b522-21efaa4426b5
This commit is contained in:
Correl Roush 2010-03-31 20:14:47 +00:00
parent df93303499
commit b882ba3c8d
2 changed files with 19 additions and 22 deletions

View file

@ -28,14 +28,8 @@ class Card:
self.suit = string[1] self.suit = string[1]
if not self.suit in ['H', 'C', 'S', 'D']: if not self.suit in ['H', 'C', 'S', 'D']:
raise InvalidCard raise InvalidCard
@staticmethod def __cmp__(self, other):
def compare(a, b): return cmp(self.value, other.value)
if a.value > b.value:
return 1
elif a.value == b.value:
return 0
else:
return -1
class Hand: class Hand:
HIGH_CARD = 0 HIGH_CARD = 0
@ -62,7 +56,7 @@ class Hand:
] ]
def __init__(self, cards): def __init__(self, cards):
self.__rank = None self.__rank = None
self.__cards = sorted([Card(c) for c in cards], cmp=Card.compare, reverse=True) self.__cards = sorted([Card(c) for c in cards], reverse=True)
self.__values = [] self.__values = []
self.rank() self.rank()
def __str__(self): def __str__(self):
@ -88,9 +82,13 @@ class Hand:
merged[c.value] = 1 merged[c.value] = 1
if (len(merged)) == 5: if (len(merged)) == 5:
# All unique cards, check for a straight # All unique cards, check for a straight
if self.__cards[0].value - self.__cards[4].value == 4 or \ if self.__cards[0].value - self.__cards[4].value == 4:
(self.__cards[4].value == 2 and self.__cards[1].value == 5 and self.__cards[0].value == 14):
straight = True straight = True
if self.__cards[4].value == 2 and self.__cards[1].value == 5 and self.__cards[0].value == 14:
straight = True
# Set the value of the ace to 1 and resort so hand comparisons work correctly
self.__cards[0].value = 1
self.__cards = sorted(self.__cards, reverse=True)
if straight and flush: if straight and flush:
if self.__cards[0].value == 14: if self.__cards[0].value == 14:
self.__rank = Hand.ROYAL_FLUSH self.__rank = Hand.ROYAL_FLUSH
@ -138,20 +136,19 @@ class Hand:
def create_best_hand_bruteforce(cards): def create_best_hand_bruteforce(cards):
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, cmp=Hand.compare, 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):
#TODO: Figure out a smarter algorithm for getting the best hand! #TODO: Figure out a smarter algorithm for getting the best hand!
pass pass
@staticmethod def __cmp__(self, other):
def compare(a, b):
# Compare hand rankings # Compare hand rankings
result = cmp(a.rank(), b.rank()) result = cmp(self.rank(), other.rank())
if (result == 0): if (result == 0):
# Compare hand values # Compare hand values
for i in range(len(a.values())): for i in range(len(self.values())):
result = cmp(a.values()[i], b.values()[i]) result = cmp(self.values()[i], other.values()[i])
if (result != 0): if (result != 0):
return result return result
return result return result

View file

@ -16,7 +16,7 @@ class TestCards(unittest.TestCase):
self.assertRaises(poker.InvalidCard, poker.Card, '9Z') self.assertRaises(poker.InvalidCard, poker.Card, '9Z')
def test_compare(self): def test_compare(self):
cards = ['QH', '9D', 'JS'] cards = ['QH', '9D', 'JS']
cards_sorted = sorted([poker.Card(c) for c in cards], cmp=poker.Card.compare, reverse=True) cards_sorted = sorted([poker.Card(c) for c in cards], reverse=True)
self.assertEqual([c.value for c in cards_sorted], [12, 11, 9]) self.assertEqual([c.value for c in cards_sorted], [12, 11, 9])
class TestFiveCardHands(unittest.TestCase): class TestFiveCardHands(unittest.TestCase):
@ -41,7 +41,7 @@ class TestFiveCardHands(unittest.TestCase):
self.assertEqual([hand.rank(), hand.values()], [poker.Hand.STRAIGHT, [14, 13, 12, 11, 10]]) self.assertEqual([hand.rank(), hand.values()], [poker.Hand.STRAIGHT, [14, 13, 12, 11, 10]])
def test_ace_low_straight(self): def test_ace_low_straight(self):
hand = poker.Hand(['AH', '2S', '3C', '4S', '5S']) hand = poker.Hand(['AH', '2S', '3C', '4S', '5S'])
self.assertEqual([hand.rank(), hand.values()], [poker.Hand.STRAIGHT, [14, 5, 4, 3, 2]]) self.assertEqual([hand.rank(), hand.values()], [poker.Hand.STRAIGHT, [5, 4, 3, 2, 1]])
def test_compare_ace_low_straight(self): def test_compare_ace_low_straight(self):
low = poker.Hand(['AH', '2S', '3C', '4S', '5S']) low = poker.Hand(['AH', '2S', '3C', '4S', '5S'])
high = poker.Hand(['2S', '3C', '4S', '5S', '6S']) high = poker.Hand(['2S', '3C', '4S', '5S', '6S'])
@ -77,10 +77,10 @@ class TestSevenCardHands(unittest.TestCase):
hand = poker.Hand.create_best_hand(['AH', 'KS', 'QC', 'JS', '9S', '7D', 'TS']) 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]]) self.assertEqual([hand.rank(), hand.values()], [poker.Hand.STRAIGHT, [14, 13, 12, 11, 10]])
def test_ace_low_straight(self): def test_ace_low_straight(self):
hand = poker.Hand.create_best_hand(['AH', '2S', '3C', '4S', '6D', '4C', '5S']) hand = poker.Hand.create_best_hand(['AH', '2S', '3C', '4S', '9D', '4C', '5S'])
self.assertEqual([hand.rank(), hand.values()], [poker.Hand.STRAIGHT, [14, 5, 4, 3, 2]]) self.assertEqual([hand.rank(), hand.values()], [poker.Hand.STRAIGHT, [5, 4, 3, 2, 1]])
def test_compare_ace_low_straight(self): def test_compare_ace_low_straight(self):
low = poker.Hand.create_best_hand(['AH', '2S', '3C', '4S', '6D', '4C', '5S']) low = poker.Hand.create_best_hand(['AH', '2S', '3C', '4S', '9D', '4C', '5S'])
high = poker.Hand.create_best_hand(['2S', '3C', '4S', '5S', '8D', 'TC', '6S']) high = poker.Hand.create_best_hand(['2S', '3C', '4S', '5S', '8D', 'TC', '6S'])
self.assertTrue(low < high) self.assertTrue(low < high)
def test_compare_ranks(self): def test_compare_ranks(self):