views:

74

answers:

3

Hello,

I am new to Python and this is my first time asking a stackOverflow question, but a long time reader. I am working on a simple card based game but am having trouble managing instances of my Hand class. If you look below you can see that the hand class is a simple container for cards(which are just int values) and each Player class contains a hand class. However, whenever I create multiple instances of my Player class they all seem to manipulate a single instance of the Hand class. From my experience in C and Java it seems that I am somehow making my Hand class static. If anyone could help with this problem I would appreciate it greatly.

Thank you, Thad

To clarify: An example of this situation would be

p = player.Player()
p1 = player.Player()
p.recieveCard(15)
p1.recieveCard(21)
p.viewHand()

which would result in: [15,21]
even though only one card was added to p

Hand class:

class Hand:

    index = 0
    cards = [] #Collections of cards

    #Constructor
    def __init__(self):
        self.index
        self.cards

    def addCard(self, card):
        """Adds a card to current hand"""
        self.cards.append(card)
        return card

    def discardCard(self, card):
        """Discards a card from current hand"""
        self.cards.remove(card)
        return card

    def viewCards(self):
        """Returns a collection of cards"""
        return self.cards

    def fold(self):
        """Folds the current hand"""
        temp = self.cards
        self.cards = []
        return temp

Player Class

import hand
class Player:

 name = ""
 position = 0
 chips = 0
 dealer = 0
        pHand = []

 def __init__ (self, nm, pos, buyIn, deal):
            self.name = nm
            self.position = pos
            self.chips = buyIn
            self.dealer = deal

            self.pHand = hand.Hand()
            return

        def recieveCard(self, card):
            """Recieve card from the dealer"""
            self.pHand.addCard(card)
            return card

        def discardCard(self, card):
            """Throw away a card"""
            self.pHand.discardCard(card)
            return card

        def viewHand(self):
            """View the players hand"""
            return self.pHand.viewCards()

        def getChips(self):
            """Get the number of chips the player currently holds"""
            return self.chips

        def setChips(self, chip):
            """Sets the number of chips the player holds"""
            self.chips = chip
            return

        def makeDealer(self):
            """Makes this player the dealer"""
            self.dealer = 1
            return

        def notDealer(self):
            """Makes this player not the dealer"""
            self.dealer = 0
            return

        def isDealer(self):
            """Returns flag wether this player is the dealer"""
            return self.dealer

        def getPosition(self):
            """Returns position of the player"""
            return self.position

        def getName(self):
            """Returns name of the player"""
            return self.name
+2  A: 

From my experience in C and Java it seems that I am somehow making my Hand class static.

Actually, that is basically what you're doing. Well, not really making the class static, but making the variable static.

When you write declarations like this:

class Hand:
    cards = []

that variable (cards) is associated with the class, not with the instance. To make an analogy to Java, every statement in a Python class that isn't part of a method of that class basically runs in a static initializer. You could almost think of it like this:

class Hand {
    static {
        cards = new object[];
    }
}

(merely a rough analogy, of course)

To create an instance variable in Python, you have to set it as an attribute of the instance, which requires you to wait until you have a reference to the instance. In practice, this means you initialize it in the constructor, like so:

class Hand:
    def __init__(self):
        self.cards = []
David Zaslavsky
Thank you so much! I can't tell you how much that helps.
BeensTheGreat
+2  A: 

Your problem is quite simple

if you assign lists to the body of python classes, when you append items to it, they will be store at Class level, not at instance level.

you can solve this problem by adding the line:

def init(self):

self.cards = []

this is a very known case of python pitfall, and I recommend you the reading: http://zephyrfalcon.org/labs/python_pitfalls.html

Gabriel Falcão
Wonderful article, thank you.
BeensTheGreat
A: 

As other answers noted, you were confused about class variables vs. instance variables. I suggest you review the basics of how Python classes work. Here is an answer I wrote for another question; reading this might help you.

http://stackoverflow.com/questions/1495666/how-to-define-a-class-in-python/1495740#1495740

steveha