Python Pygame trying to display output as part of file name

Viewed 43

I have a list of playing card images and I am trying to randomly determine a card and then display the image of the card in Pygame. I am outputting a card number/suit combination, which matches the file name associated with the card (for example, Ace of Clubs is Ac with file name Ac.png). Everything works fine with creating a random card, and I can manually type in the card name into the Pygame part of the code and get it to display, but there is some sort of print issue where it displays None when I try to put the output below into the following code: Cutoff2 = pygame.image.load(Bob_CardOne + '.png')

Traceback (most recent call last):
  File "C:/Users/justi/PycharmProjects/ManCavePoker/main.py", line 176, in <module>
    Cutoff2 = pygame.image.load(Bob_CardOne + '.png')
TypeError: can only concatenate str (not "NoneType") to str

so then I do this: Cutoff2 = pygame.image.load(str(Bob_CardOne) + '.png')

but converting to string creates this error:

Traceback (most recent call last):
  File "C:/Users/justi/PycharmProjects/ManCavePoker/main.py", line 176, in <module>
    Cutoff2 = pygame.image.load(str(Bob_CardOne) + '.png')
FileNotFoundError: No such file or directory.

I've spent the better part of the day researching print issues with None, found lots of stuff on using return instead of print, repr, and other things but nothing seems to fit exactly what I'm trying to accomplish. Is there a better way to go about it or am I missing something subtle?

class Card(object):
    def __init__(self, suit, val):
        self.suit = suit
        self.value = val

    def show(self):
        print("{}{}".format(self.value, self.suit))

class Deck(object):
    def __init__(self):
        self.cards = []
        self.build()

    def build(self):
        for s in ["c", "d", "h", "s"]:
            for v in {"2": 2
                ,"3": 3
                ,"4": 4
                ,"5": 5
                ,"6": 6
                ,"7": 7
                ,"8": 8
                ,"9": 9
                ,"10": 10
                ,"J": 11
                ,"Q": 12
                ,"K": 13
                ,"A": 14}:
                    self.cards.append(Card(s,v))

    def show(self):
        for c in self.cards:
            c.show()

    def shuffle(self):
        for i in range(len(self.cards)-1,0,-1):
            r = random.randint(0,i)
            self.cards[i], self.cards[r] = self.cards[r], self.cards[i]

    def drawCard(self):
            return self.cards.pop()

class Player(object):
    def __init__(self, name):
        self.name = "Bob"
        self.hand = []

    def draw(self, deck):
        self.hand.append(deck.drawCard())
        return self

    def showHand(self):
        for card in self.hand:
            return card.show()

    # def printHand(self):
    #     for card in self.hand:
    #         return self.hand

deck = Deck()
#deck.show()
deck.shuffle()
#deck.show()

bob = Player("Bob")
bob.draw(deck)
Bob_CardOne = bob.showHand()
1 Answers

The Card.show method does not return anything. Therefore the method showHand does not return anything, too.

Return the name of the card:

class Card(object):
    def __init__(self, suit, val):
        self.suit = suit
        self.value = val

    def show(self):
        name = "{}{}".format(self.value, self.suit)
        print(name)
        return name 

The Player.showHand method does not have to iterate through the cards, but selects a card based on its index:

class Player(object):
    # [...]

    def showHand(self, index):
        
        if index < len(self.hand):
            card = self.hand[index]
            return card.show()
   
        return None

So you can get any card you want:

Bob_CardOne = bob.showHand(0)
Bob_CardTwo = bob.showHand(1)
Related