Hi,

I have a card class and deck class. The cards are in
suitList
rankList.

I call the cards from a file cards.txt and split them into the above.

I need to import the cards.txt and then shuffle them. I have the following code:

def shuffle(self):
import random
nCards = len(self.cards)
# Swap randomly selected card i with randomly selected card j
for i in range(nCards):
j = random.randrange(i, nCards)
[self.cards, self.cards[j]] = [self.cards[j], self.cards]

How do I get the cards shuffled and then use the shuffled deck to display the cards using Deck().

macca1111

Recommended Answers

All 11 Replies

Member Avatar for Mouche

Check the other threads about the card class and such. Once you have a deck in a list, you can use a shuffle() function and it will randomly switch the items around.

Check the other threads about the card class and such. Once you have a deck in a list, you can use a shuffle() function and it will randomly switch the items around.

Hi,

I have my cards in suitList and rankList.


When I use:

deck=Deck()
deck.shuffle()
print deck

It shuffles the ranks but returns all Hearts. How do I make the shuffle() function shuffle both rankList and suitList???

macca1111

Member Avatar for Mouche

Could you copy your entire code with code tags, please? Sorry my first post didn't really say anything at all.

Could you copy your entire code with code tags, please? Sorry my first post didn't really say anything at all.

import string
list1 = open('H:\cards.txt').read()
class Card:
    suitList = list1[1::2]
    rankList = list1[0::2]
    
    def __init__(self,suit,rank):
        self.suit = suit
        self.rank = rank
        
    def __repr__(self):
        return str(self)
    
    def __str__(self):
        return "%s of %s" % (self.rankList[self.rank],self.suitList[self.suit])
    
    def __cmp__(self,other):
       if self.suit > other.suit: return 1
       if self.suit < other.suit: return -1
       if self.rank > other.rank: return 1
       if self.rank < other.rank: return -1
       return 0
class Deck:
    def __init__(self):
        self.cards = []
        for suit in range(4):
            for rank in range(1,14):
                self.cards.append(Card(suit,rank))
    def printDeck(self):
        for card in self.cards:
            print card
                
    def __str__(self):
      s = ""
      for i in range(len(self.cards)):
        s = s + " " + str(self.cards[i]) + "\n"
      return s #= s + " " + str(self.cards[i]) + '\n'
    def shuffle(self):
        import random
        nCards = len(self.cards)
        # Swap randomly selected card i with randomly selected card j
        for i in range(nCards):
            j = random.randrange(i, nCards)
            [self.cards[i], self.cards[j]] = [self.cards[j], self.cards[i]]
    def removeCard(self, card):
        if card in self.cards:
          self.cards.remove(card)
          return 1
        else: return 0
    # return the top ca
    def popCard(self):
     return self.cards.pop()
    
def main():
    list2 = list1.split()
    Card.suitList = list2[1::2]
    Card.rankList = list2[0::2]
    deck = Deck()
    deck.shuffle()
    
    # replace suit with full word
    for index, suit in enumerate(Card.suitList):
        if suit == 'h':
            Card.suitList[index] = "Hearts"
        elif suit == 'c':
            Card.suitList[index] = "Clubs"
        elif suit == 's':
            Card.suitList[index] = "Spades"
        elif suit == 'd':
            Card.suitList[index] = "Diamonds"
    list3 = open('H:\cardsS.txt','w')
    list3.writeline(list2,)
    list3.close()
    print deck
    
    
main()

Ultimately what i'm trying to achieve is:

1.
Create a random file from a file with the cards in order. So read an ordered file (I can do). Then randonize it (only the rank are changing - not the suit).

(This is how the file is to be ordered)
2 h
3 d
Ace d
...

2.
Then deal a card from the top of the deck and remove it from the deck. I think I have the class in order, yet taking the card is not working.

3.
Then return the number of cards left.

4. Finally test it by dealing n number of cards and display them.

I am almost there, yet most of the problems I think lay with the syntax which is confusing me.

The last time I programmed anything was a C64 20 years ago.

Kind Regards
macca1111

Sorry,

I'm very new to this. I even had to do a search to find out what code tags are...

Why do you want to keep two lists, a card has both a rank and a suit, they belong together to make the card. If you just shuffle the rank list, then you lost the connection with the suit list. As I mentioned before, keep your cards in a list of (rank, suit) tuples. That list will by default sort by rank (item 0 of the tuple) and keep the suit along. The same goes for the random.shuffle().

Why do you want to keep two lists, a card has both a rank and a suit, they belong together to make the card. If you just shuffle the rank list, then you lost the connection with the suit list. As I mentioned before, keep your cards in a list of (rank, suit) tuples. That list will by default sort by rank (item 0 of the tuple) and keep the suit along. The same goes for the random.shuffle().

The following code is suppose to print a pack of cards in order, then shuffle them and reprint them again. Using Deck to print them it's not quite how I would like it.

This is how its printing...

[, , ...

I would like it to print:

Ace of Hearts
2 of Hearts
...

my file is saved like...

1 of h
2 of h
...

import string

class Card:

    
    def __init__(self,suit,rank):
        self.suit = suit
        self.rank = rank
        suitList = []
        rankList = []
        
    def __repr__(self):
        return str(self)
    
    def __str__(self):
        return "%s of %s" % (self.rankList[self.rank],self.suitList[self.suit])

class Deck():
    def __init__(self):
        self.cards = []
        for suit in range(4):
            for rank in range(1,14):
                self.cards.append(Card(suit,rank))

    def printDeck(self):
        for card in self.cards:
            print card

    def __str__(self):
        s = ""
        for i in range(len(self.cards)):
            s = s + " " + str(self.cards[i]) + '\n'
        return s

    def shuffle(self):
        import random
        nCards = len(self.cards)
        for i in range(nCards):
            j = random.randrange(i, nCards)
            [self.cards[i], self.cards[j]] = [self.cards[j], self.cards[i]]

def main():
    a = open('cards.txt','r')
    line = a.readlines()
    a.close()

    deck = Deck()
    
    cards =[]
    for i in line:
        cards.append(i.split())

    print deck

    #replace suit with full word
    for index, suit in enumerate(Card.suitList):
        if suit == 'h':
            Card.suitList[index] = "Hearts"
        elif suit == 'c':
            Card.suitList[index] = "Clubs"
        elif suit == 's':
            Card.suitList[index] = "Spades"
        elif suit == 'd':
            Card.suitList[index] = "Diamonds"
    print

I still don't understand your file structure or the reason for a file. Will this help ...

import random

def show_hand(hand):
    """give drawn cards more detailed descriptions and then display"""
    for item in hand:
        rank = item[0]
        suit = item[1]
        
        if rank == 1:
            rank = "Ace"
        elif rank == 11:
            rank = 'Jack'
        elif rank == 12:
            rank = 'Queen'
        elif rank == 13:
            rank = 'King'
        
        if suit == 'h':
            suit = "Hearts"
        elif suit == 'c':
            suit = "Clubs"
        elif suit == 's':
            suit = "Spades"
        elif suit == 'd':
            suit = "Diamonds"
            
        print "%s of %s" % (rank, suit)
        

card_list = [ (rank, suit) for suit in "hcds" for rank in range(1, 14)]
# test
print card_list

print

# pull 5 cards
hand = card_list[:5]
# show the hand
show_hand(hand)

"""
result =
Ace of Hearts
2 of Hearts
3 of Hearts
4 of Hearts
5 of Hearts
"""

print "-"*30

random.shuffle(card_list)
# pull 5 cards
hand = card_list[:5]
# sort the hand by rank
hand.sort()
# show the hand
show_hand(hand)

"""
possible result =
2 of Diamonds
5 of Hearts
Queen of Clubs
Queen of Diamonds
King of Diamonds
"""
Member Avatar for Mouche

So are classes a good choice for a card game or not?

So are classes a good choice for a card game or not?

For simple stuff I would say no! However, you may be a more advanced Python programmer and want to practice OOP, or have a rather complex card game project in mind.

For a beginner to take an existing OOP code and butcher around with it is not very productive and leads to rather frustrating confusion.

I still don't understand your file structure or the reason for a file. Will this help ...

import random
 
def show_hand(hand):
    """give drawn cards more detailed descriptions and then display"""
    for item in hand:
        rank = item[0]
        suit = item[1]
 
        if rank == 1:
            rank = "Ace"
        elif rank == 11:
            rank = 'Jack'
        elif rank == 12:
            rank = 'Queen'
        elif rank == 13:
            rank = 'King'
 
        if suit == 'h':
            suit = "Hearts"
        elif suit == 'c':
            suit = "Clubs"
        elif suit == 's':
            suit = "Spades"
        elif suit == 'd':
            suit = "Diamonds"
 
        print "%s of %s" % (rank, suit)
 
 
card_list = [ (rank, suit) for suit in "hcds" for rank in range(1, 14)]
# test
print card_list
 
print
 
# pull 5 cards
hand = card_list[:5]
# show the hand
show_hand(hand)
 
"""
result =
Ace of Hearts
2 of Hearts
3 of Hearts
4 of Hearts
5 of Hearts
"""
 
print "-"*30
 
random.shuffle(card_list)
# pull 5 cards
hand = card_list[:5]
# sort the hand by rank
hand.sort()
# show the hand
show_hand(hand)
 
"""
possible result =
2 of Diamonds
5 of Hearts
Queen of Clubs
Queen of Diamonds
King of Diamonds
"""

Hi,

Thks for your post.

I have posted my code after a bit more tweeking, yet still just not quite right.

I can replace the ranks ie the 1 to Ace and 11 to Jack etc, yet I have a couple of probs.

It only replaces the suit to hearts and the 1 at the beginning is moved to the end.

import string
list1 = open('H:\cards.txt').read()
class Card:
    suitList = list1[1::2]
    rankList = list1[0::2]
 
    def __init__(self,suit,rank):
        self.suit = suit
        self.rank = rank
 
    def __repr__(self):
        return str(self)
 
    def __str__(self):
        return "%s of %s" % (self.rankList[self.rank],self.suitList[self.suit])
 
class Deck:
    def __init__(self):
        self.cards = []
        for suit in range(4):
            for rank in range(1,14):
                self.cards.append(Card(suit,rank))
    def printDeck(self):
        for card in self.cards:
            print card
 
    def __str__(self):
      s = ""
      for i in range(len(self.cards)):
        s = s + " " + str(self.cards[i]) + "\n"
      return s #= s + " " + str(self.cards[i]) + '\n'
    def shuffle(self):
        import random
        nCards = len(self.cards)
        # Swap randomly selected card i with randomly selected card j
        for i in range(nCards):
            j = random.randrange(i, nCards)
            [self.cards[i], self.cards[j]] = [self.cards[j], self.cards[i]]
def main():
    list2 = list1.split()
    Card.suitList = list2[1::2]
    Card.rankList = list2[0::2]
    deck = Deck()
    #deck.shuffle()
    for index, rank in enumerate(Card.rankList):
        if rank == '1':
            Card.rankList[index] = "Ace"
        elif rank == '11':
            Card.rankList[index] = "Jack"
        elif rank == '12':
            Card.rankList[index] = "Queen"
        elif rank == '13':
            Card.rankList[index] = "King"
    for index, suit in enumerate(Card.suitList):
        if suit == 'h':
            Card.suitList[index] = "Hearts"
        elif suit == 'c':
            Card.suitList[index] = "Clubs"
        elif suit == 'd':
            Card.suitList[index] = "Diamonds"
        elif suit == 's':
            Card.suitList[index] = "Spades"

Would it be easier to replace the if.. statements with a tuples in the class like

suits = ("Hearts","Diamonds","Spades","Clubs")

My text file is:

1 h
2 h
...
1 d
2 d
...
1 s
2 s
...
1 c
2 c
...

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.