So I'm trying to create a Deck of cards in Python. I am at the point where I'm trying to create the method to sort the deck of cards back into order.
2 of clubs, 3 of clubs, ...Ace of clubs
2 of Diamonds, 3 of Diamonds, ...Ace of Diamonds
2 of Hearts, 3 of Hearts, ...Ace of Hearts
2 of Spades, 3 of Spades, ...Ace of Spades
I have part of it already implemented but the sorting part is only KIND OF working. It successfully sorts them in the suit, but the rank part is kind of messed up. 10 comes before 2 and the Picture Cards are incorrect. My guess is that my __lt__ and __eq__ functions aren't processing the ranks correctly (esp the Picture Cards)
CODE:
import random
# deck = ["2C", "3C", "4C", "5C", "6C", "7C", "8C", "9C", "10C", "JC", "QC", "KC", "AC", "2D", "3D", "4D", "5D", "6D",
# "7D", "8D", "9D", "10D", "JD", "QD", "KD", "AD", "2H", "3H", "4H", "5H", "6H", "7H", "8H", "9H", "10H", "JH",
# "QH", "KH", "AH", "2S", "3S", "4S", "5S", "6S", "7S", "8S", "9S", "10S", "JS", "QS", "KS", "AS"]
from functools import total_ordering
graveyard = []
@total_ordering
class Card(object):
def __init__(self, rank, suit):
self.rank = rank
self.suit = suit
def __str__(self):
return '%s of %s' % (self.rank,
self.suit)
def __repr__(self): return str(self)
def __lt__(self, other):
t1 = self.suit, self.rank
t2 = other.suit, other.rank
return t1 < t2
def __gt__(self, other):
t1 = self.suit, self.rank
t2 = other.suit, other.rank
return t1 > t2
def __eq__(self, other):
t1 = self.suit, self.rank
t2 = other.suit, other.rank
return t1 == t2
class Deck(object):
def __init__(self):
"""
Idea for this found here.
https://stackoverflow.com/questions/8511745/sorting-a-hand-of-cards-accoring-to-rank-and-suit-in-python
I could use this to ALWAYS have a shuffled deck at the beginning or to just start with a 'clean' deck as above...
:return:
"""
self.rank = ['2', '3', '4', '5', '6', '7', '8', '9', '10', 'Jack', 'Queen', 'King', 'Ace']
self.suit = ['Clubs', 'Diamonds', 'Hearts', 'Spades']
self.deck = [Card(r, s) for r in self.rank for s in self.suit]
random.shuffle(self.deck)
def __getitem__(self, item):
return self.deck[item]
def deal(self):
"""
Return a card from the deck.
:return:
"""
topCard = self.deck.pop(0)
graveyard.append(topCard)
print(topCard)
def shuffle(self):
"""
Shuffle the deck
:return:
"""
self.deck.extend(graveyard)
random.shuffle(self.deck)
self.fan()
def fan(self):
"""
Print out the deck
:return:
"""
for card in self.deck:
print(card)
def order(self):
return self.deck.sort()
def printGraveyard(self):
for dead in graveyard:
print(dead)
d = Deck()
d.order()
d.fan()
OUTPUT:
10 of Clubs
2 of Clubs
3 of Clubs
4 of Clubs
5 of Clubs
6 of Clubs
7 of Clubs
8 of Clubs
9 of Clubs
Ace of Clubs
Jack of Clubs
King of Clubs
Queen of Clubs
10 of Diamonds
2 of Diamonds
3 of Diamonds
4 of Diamonds
5 of Diamonds
6 of Diamonds
7 of Diamonds
8 of Diamonds
9 of Diamonds
Ace of Diamonds
Jack of Diamonds
King of Diamonds
Queen of Diamonds
10 of Hearts
2 of Hearts
3 of Hearts
4 of Hearts
5 of Hearts
6 of Hearts
7 of Hearts
8 of Hearts
9 of Hearts
Ace of Hearts
Jack of Hearts
King of Hearts
Queen of Hearts
10 of Spades
2 of Spades
3 of Spades
4 of Spades
5 of Spades
6 of Spades
7 of Spades
8 of Spades
9 of Spades
Ace of Spades
Jack of Spades
King of Spades
Queen of Spades
I didn't test it, but I think you could create a class for the rank, like:
in Deck:
So in
class Card
you could do something like:You're correct, it's the comparision of the rank that compares the string, that is
"10"<"2"
and"Ace"<"Queen"
etc.What you could do is to for example write a suitable string to numeric rank function.
then you use this to rewrite the comparison: