I'm writing a gin card game that deals with sets and melds of cards. A set is 3 or 4 cards with the same rank (i.e. 9c,9d,9h). A meld is a run of cards of the same rank (i.e. 8c,9c,10c). I want to sort a combined list of melds and sets.
Cards are represented like so:
class Card:
def __init__(self, rank, suit):
self.rank = rank
self.suit = suit
Cards are stored in CardGroups like so:
class CardGroup:
def __init__(self, card_list):
self.cards = []
for c in card_list:
self.cards.append(c)
Here's an example with the hand 2c,2h,2d,4h,5d,5s,5c,6c,7c,8c:
The melds in this hand all deal with clubs: (5c,6c,7c) and (6c,7c,8c). The sets are (2c,2d,2h) and (5c,5d,5s).
The resulting combined list might combine like so (melds, then sets):
unsorted_list = [ CardGroup([Card(5,'c'), Card(6,'c'), Card(7,'c')],
CardGroup([Card(6,'c'), Card(7,'c'), Card(8,'c')],
CardGroup([Card(2,'c'), Card(2,'d'), Card(2,'h')],
CardGroup([Card(5,'c'), Card(5,'d'), Card(5,'s')] ]
The resulting combined list should exist like so (card by card comparison):
sorted_list = [ CardGroup([Card(2,'c'), Card(2,'d'), Card(2,'h')],
CardGroup([Card(5,'c'), Card(5,'d'), Card(5,'s')],
CardGroup([Card(5,'c'), Card(6,'c'), Card(7,'c')],
CardGroup([Card(6,'c'), Card(7,'c'), Card(8,'c')] ]
Note that the second and third CardGroup both start with 5c. It is important that these are sorted correctly. In the case that we have a 4-set like 2c,3c,4c,5c we also implicitly have a 3-set of 2c,3c,4c. When sorting these two, we want the 3-set to come before the 4-set.
Things I've Tried:
unsorted_list.sort(key=lambda x: x.cards)
unsorted_list.sort(key=lambda x: x.cards[0])
unsorted_list.sort(key=lambda x: tuple(x.cards))
Thank you for the help!
Edit: Using a comparison operator was suggested as an answer. Here are the unit tests for such a solution:
Class TestCard:
def test___cmp__(self):
card1 = Card(5, 'd')
card2 = Card(6, 'c')
card3 = Card(6, 's')
self.assertLessEqual(card1.__cmp__(card2), -1)
self.assertLessEqual(card1.__cmp__(card3), -1)
self.assertEqual(card1.__cmp__(card1), 0)
self.assertGreaterEqual(card2.__cmp__(card1), 1)
self.assertLessEqual(card2.__cmp__(card3), -1)
self.assertGreaterEqual(card3.__cmp__(card1), 1)
self.assertGreaterEqual(card3.__cmp__(card2), 1)