首页 > 解决方案 > Access attributes of classA from classB where classB is an attribute of classA

问题描述

I'm making BlackJack in python. The Dealer is an attribute of the Table and the Table also has an attribute which is the list of players. How can I make the dealer DealCards to the players on the Table that it is an attribute of, so that there can be multiple Tables, as at the moment it only does this on the Table called table?


def getIntInput(text):
    isInt = input(text)
    while True:
        try:
            return int(isInt)
        except:
            isInt = input(f"Invalid Input. {text}")

class Card():
    def __init__(self, suit, number):
        self.suit = suit
        self.number = number
  
    def __repr__(self):
        return f"{self.number} of {self.suit}"

class Deck():
    def __init__(self):
        self.cards = []
        numbers = "Ace 2 3 4 5 6 7 8 9 10 Jack Queen King".split()
        suits = ["Spades", "Hearts", "Diamonds", "Clubs"]
        for number in numbers:
            for suit in suits:
                self.cards.append(Card(suit,number))
    
    def shuffle(self):
        random.shuffle(self.cards)
    
    def deal(self):
        return self.cards.pop()
    
    def __repr__(self):
        return str(self.cards)

class Player():
    def __init__(self, name):
        self.name = name
        self.cards = []
        self.money = 1000
        self.isSplit = False
        self.currentBet = 0
    
    def __repr__(self):
        return f"{self.name}:{self.cards}:{self.money}"

    def receiveCard(self, card):
        self.cards.append(card)
    
    def calculateValue(self):
        count = 0
        for card in self.cards:
            cardValue = "Ace 2 3 4 5 6 7 8 9 10 Jack Queen King".split().index(card.number) + 1
            count += cardValue
        if count > 21:    #if bust
            return -1
        return count
    
    def getMove(self):
        move = input("Hit, stand, double, split or surrender: ").lower()
        playableMoves = ["hit","stand","double","split","surrender"]
        while move not in playbleMoves:
            move = input("Invalid move. Hit, stand, double, split or surrender: ").lower()
        return move

class HumanPlayer(Player):
    def __init__(self, name):
        Player.__init__(self,name)
    
class Dealer(Player):
    def __init__(self):
        Player.__init__(self,"DEALER")
    
    def dealCards(self):
        for x in range(2):
            for player in table.players:
                player.receiveCard(table.deck.deal())
            self.receiveCard(table.deck.deal())

class Table():
    def __init__(self):   #set up table
        self.deck = Deck()
        self.deck.shuffle()
        self.playerCount = getIntInput("Enter number of players: ")
        self.players = [HumanPlayer(input(f"Enter player {x+1}'s name: ")) for x in range(self.playerCount)]
        self.dealer = Dealer()
        
    def __repr__(self):
        temp = '\n'.join([str(x) for x in self.players])
        return f"TABLE\n{self.deck}\n{self.dealer}\n{temp}"
    
    def calculateWinnerOfRound(self):
        maxValue = self.dealer.calculateValue()
        maxValuePerson = self.dealer
        for player in self.players:
            if player.calculateValue() > maxValue:
                maxValue = player.calculateValue()
                maxValuePerson = player
        print(f"Player {maxValuePerson.name} wins")        
        
        maxValuePerson.money += maxValuePerson.currentBet
        for player in [self.dealer] + self.players:
            if player != maxValuePerson:
                player.money -= player.currentBet
    
table = Table()
table.dealer.dealCards()
table.calculateWinnerOfRound()

标签: python

解决方案


The only way I can think of (others may find betters) is to give ClassB the instantiated ClassA as an argument to its constructor, and assigning that instance to an attribute of ClassB. Example:

class ClassB:
    def __init__(self, parent, name):
        self.name = name
        print("Name of child class instance :", self.name)
        self.parent = parent
        print("Name of the child classes parent :", self.parent.name)

class ClassA:
    def __init__(self, name):
        self.name = name
        print("Name of ClassA instance :", self.name)
        self.child = ClassB(self, name * 2)

if __name__ == "__main__":
    classa = ClassA("somename")

推荐阅读