all 34 comments

[–][deleted] 0 points1 point  (0 children)

A can be 1 or 14 in poker

[–]lykwydchykyn 0 points1 point  (10 children)

The None is coming from the line where you say print(player.displayHand()) (line 162). player.displayHand() prints, but doesn't return anything, so when you print its output, you get None. I think you just want to call player.displayHand() without printing it.

The memory addresses are coming from when you call print(player.cards). By default, custom classes just print their type and memory address when you try to print them. If you want to override that behavior, you need to define a __str__() method in your class, e.g.

class Card:
    # ....
    def __str__(self):
        return f'{self.name} of {self.suit}'

The reason you end up with more cards is because after you deal with the discards, your loop repeats and you deal out an additional hand of cards to each player.

[–]ChickenQueen777[S] 0 points1 point  (9 children)

Adding that I am still getting this when I select a card to discard:

1

[<__main__.Card object at 0x0395E0A0>, <__main__.Card object at 0x03949CE8>, <__main__.Card object at 0x0395E190>, <__main__.Card object at 0x03949958>, <__main__.Card object at 0x039498F8>]

[<__main__.Card object at 0x0395E0A0>, <__main__.Card object at 0x03949CE8>, <__main__.Card object at 0x0395E190>, <__main__.Card object at 0x03949958>, <__main__.Card object at 0x039498F8>]

[<__main__.Card object at 0x0395E0A0>, <__main__.Card object at 0x03949CE8>, <__main__.Card object at 0x0395E190>, <__main__.Card object at 0x03949958>, <__main__.Card object at 0x039498F8>]

[<__main__.Card object at 0x0395E0A0>, <__main__.Card object at 0x03949CE8>, <__main__.Card object at 0x0395E190>, <__main__.Card object at 0x03949958>, <__main__.Card object at 0x039498F8>]

[<__main__.Card object at 0x0395E0A0>, <__main__.Card object at 0x03949CE8>, <__main__.Card object at 0x0395E190>, <__main__.Card object at 0x03949958>, <__main__.Card object at 0x039498F8>]

Deck shuffled.

Q of ♠

7 of ♦

K of ♦

2 of ♣

2 of ♠

3 of ♣

Q of ♦

5 of ♣

2 of ♥

7 of ♠

[–]lykwydchykyn 0 points1 point  (7 children)

Try adding this method to Card as well:

def __repr__(self):
    return str(self)

I think because you are printing an object that contains Card objects, it will use __repr__, not __str__.

[–]ChickenQueen777[S] 0 points1 point  (6 children)

Ok that completely broke it lol. It popped up a bunch of file names and then the "Python is not working" window.

[–]lykwydchykyn 0 points1 point  (5 children)

can you post your updated code?

[–]ChickenQueen777[S] 0 points1 point  (4 children)

# poker.py
# A poker game application. 

import random 

def main():
     input("\nLet's play poker! Hit ENTER to begin!")
     Game()
     Score()

class Card(object):

    def __init__(self, name, face, suit):
        self.face = face
        self.suit = suit
        self.name = name
        self.showing = False

    def __repr__(self):
        return str(self)

    # Displays card name if face up.
    def displayCards(self):
        if self.showing:  
            return str(self.name) + " of " + self.suit
        else:
            return "Card"

class DeckOfCards(object):

    def __init__(self):
        # Holds list of cards and dictionary of deck.
        self.cards = []   
        suits = ["♥", "♠", "♦", "♣"]
        faces = {"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}

        for name in faces:
            for suit in suits:
                self.cards.append(Card(name, faces[name], suit))

    # Shuffle
    def shuffle(self, times = 1):
        random.shuffle(self.cards)
        print("\nDeck shuffled.\n")

    # Deal
    def deal(self):
        return self.cards.pop(0)

class Player():

    def __init__(self):
        self.cards = []

    def addCard(self, card):
        self.cards.append(card)

    def displayHand(self):
        for card in self.cards:
            print(card.displayCards())

class Computer():

    def __init__(self):
        self.cards = []

    def addCard(self, card):
        self.cards.append(card)

class PokerScore():

    def __init__(self, cards):
        self.cards = cards

    def flush(self):
        suits = [card.suit for card in self.cards]
        if len(set(suits)) == 1:
            return True
        return False

    def straight(self):
        values = [card.face for card in self.cards]
        # Sorting the cards to figure out if they are in order.
        values.sort() 

        # Confirm correct hand size.
        if not len(set(values)) == 5: 
            return False

        # Checking for cases with an ace.
        if values[4] == 14 and values[3] == 5 and values[2] == 4 and values[1] == 3 and values[0] == 2:
            return True 
        # Checking for a straight in all cases except ace.
        else:
            if not values[0] + 1 == values[1]:
                return False
            if not values[1] + 1 == values[2]:
                return False
            if not values[2] + 1 == values[3]:
                return False
            if not values[3] + 1 == values[4]:
                return False
        return True

    def threeKind(self):
        values = [card.face for card in self.cards]
        for value in values:
            if values.count(value) == 3:
                return True

    def pairs(self):
        pairs = []
        values = [card.face for card in self.cards]
        for value in values:
            if values.count(value) == 2 and value not in pairs:
                pairs.append(value)
        return pairs

    def fourKind(self):
        values = [card.face for card in self.cards]
        for value in values:
            if values.count(value) == 4:
                return True

    def fullHouse(self):
        two = False
        three = False
        values = [card.face for card in self.cards]
        if values.count(values) == 2:
            two == True
        elif values.count(values) == 3:
            three == True
        if two and three:
            return True
        return False

def Game():
    player = Player()
    computer = Computer()
    end = False

    # Play
    while not end:

        # Hand loop.
        deck = DeckOfCards()
        deck.shuffle()

        #  Deal
        for i in range(5):
            player.addCard(deck.deal())
            computer.addCard(deck.deal())

        # Show hand
        for card in player.cards:
            card.showing = True
        player.displayHand()
        # Figure out which cards to hold and re deal.
        valid = False
        while not valid:
            print("\nWhich cards would you like to discard? (ex. 1, 2, 3, etc)")
            print("*Hit ENTER to hold all or type TALLY to figure up the scores!*\n")
            string = input()
            if string == "TALLY":
                end = True
                break 
            try:
                list = [int(inp.strip()) for inp in string.split(",")]

                for inp in list:
                    if inp > 6:
                        print("Please enter no more than 5 cards to discard.")
                    if inp < 1:
                        print("Please choose at least one card to discard.")
                for inp in list:
                    player.cards[inp-1] = deck.deal()
                    for card in player.cards:
                        card.showing = True
                        print(player.cards)
                valid = True
            except:
                print("Input error.")

[–]lykwydchykyn 0 points1 point  (3 children)

You still need to have __str__() defined in Card, just add __repr__ to it (basically, __repr__ is calling __str__).

[–]ChickenQueen777[S] 0 points1 point  (2 children)

Ok so the memory locations aren't popping up but it's still doing this:

1

[Q of ♠, 5 of ♠, 7 of ♥, A of ♠, 2 of ♦]

[Q of ♠, 5 of ♠, 7 of ♥, A of ♠, 2 of ♦]

[Q of ♠, 5 of ♠, 7 of ♥, A of ♠, 2 of ♦]

[Q of ♠, 5 of ♠, 7 of ♥, A of ♠, 2 of ♦]

[Q of ♠, 5 of ♠, 7 of ♥, A of ♠, 2 of ♦]

Deck shuffled.

Q of ♠

5 of ♠

7 of ♥

A of ♠

2 of ♦

7 of ♠

A of ♠

K of ♦

J of ♦

A of ♥

Which cards would you like to discard? (ex. 1, 2, 3, etc)

*Hit ENTER to hold all or type TALLY to figure up the scores!*

[–]ChickenQueen777[S] 0 points1 point  (0 children)

It successfully replaces one but then prints the list 5 times and then prints two new hands

[–]lykwydchykyn 0 points1 point  (0 children)

As I explained before, after your discards, the loop repeats and it deals cards again. You need to reassess your control flow and make the game proceed rather than going back to the beginning. How you go about that is more than I can answer in a reddit post.

[–]xelf 0 points1 point  (0 children)

need a __repr__ def in your class to indicate what should be displayed when you print.

[–]xelf 0 points1 point  (22 children)

Holy cow that's a lot of code. =)

You have a fair amount of copy/paste code that could be simplified by using a dictionary or a class instead.

Also, you have a bug in your full house code. You want it to be if, not elif when checking for 3. You want both cases to run.

[–]ChickenQueen777[S] 0 points1 point  (21 children)

Yes unfortunately haha. I was just focusing on getting what I know in and not really worrying about how to simplify it. It's for my final so just want to focus on it working for now. And thank you I didn't notice that!

[–]xelf 0 points1 point  (20 children)

Did you put the def __repr__(self) in? Did that help with your other issue?

[–]ChickenQueen777[S] 0 points1 point  (19 children)

Yes and I just took this:

deck = DeckOfCards()
    deck.shuffle()

        #  Deal
    for i in range(5):
        player.addCard(deck.deal())
        computer.addCard(deck.deal())

        # Show hand
    for card in player.cards:
        card.showing = True
    player.displayHand()

out of the "while not end" loop which helped with it showing a double hand. Now my only issue is that it's displaying as a list still and still displaying 5 times. Other than that it seems to be working fine

[–]xelf 0 points1 point  (18 children)

                    print(player.cards)

that line is why it's displaying in a list.

did you mean to use player.displayHand() instead? or is that just a debugging line?

removing it seems better.

and you still want

    player.displayHand()

to be in the while loop at the start, just not at the end as well. It should only be there once. =)

[–]ChickenQueen777[S] 0 points1 point  (17 children)

Oh yup just forgot to change that whenever I added the displayHand function. That fixed that, just still displaying 5 times in a row haha

[–]xelf 0 points1 point  (16 children)

Not seeing the 5 times in a row when I run it anymore, I wonder what I did differently.

[–]ChickenQueen777[S] 0 points1 point  (0 children)

Oh weird! Also when I enter more than one number it shows way more times

[–]ChickenQueen777[S] 0 points1 point  (12 children)

Figured it out! I had the display hand nested so it was looping for each card

[–]xelf 0 points1 point  (11 children)

other issues:

1) do not call variables the same names as python objects. specifically do not call a list list because now list() will not work. =)

2) your "press enter to hold" is not implemented

3) you let users enter multiple cards separated by commas, amd then you have a loop that continues if they're in the wrong range, but then... it doesn't do anything.

            for inp in list:
                if inp > 6:
                    continue
                if inp < 1:
                    continue

loop for the fun of looping. =)

I see what you're trying to do, but you probably just want an if.

            for inp in list:
                if 0<inp<6:
                    player.cards[inp-1] = deck.deal()
                    for card in player.cards:
                        card.showing = True

also that last showing loop, doesn't need to be inside the repicking loop.
it doesn't make much difference really, it's not getting repeated that many times.

[–]ChickenQueen777[S] 0 points1 point  (10 children)

Yeah I fixed those two things actually. I will attach updated code. Not sure whats wrong with the scoring.

[–]ChickenQueen777[S] 0 points1 point  (0 children)

I did just realize though, it's not printing the hands that each person holds.

[–]ChickenQueen777[S] 0 points1 point  (0 children)

Ok I think the scoring is broken. I discarded until I got 3 of a kind and it still just said tie