Reputation: 432
I am learning OOP, have hard time grasping how to different classes interact with each other. I read so many examples but majority of them show how single class works, and that's clear, I want to see how different classes to interact among themselves. If someone has a good example how different classes interact it would be great.
Here I create Deck
instance newDeck
and then Player
instance p1
. Then I do this:
newCard.append(player.generateCard(newDeck))
where player
is p1
, so I call Player
method generateCard()
and pass newDeck
instance of class Deck
. Is this allowed?
Here I get error:
File "poker.py", line 67, in startGame
newCard.append(player.generateCard(newDeck))
AttributeError: 'str' object has no attribute 'generateCard'`
My code:
import random, string, sys
class Deck:
def __init__(self):
self.suits = ['s', 'h', 'd', 'c']
self.ranks = ['2', '3', '4', '5', '6' ,'7', '8', '9', '10', 'J', 'Q', 'K', 'A']
self.deck = [i+j for i in self.ranks for j in self.suits]
random.shuffle(self.deck)
def selectCards(self):
self.selectedCard = self.deck.pop()
return self.selectedCard
class Player:
def __init__(self, amount):
self.amount = amount
self.card = []
def generateCard(self, whichDeck):
self.whichDeck = whichDeck
holeCards = 2
for i in range(0, holeCards):
selCard = self.whichDeck.selectCards()
if len(selCard) == 2:
self.cardRank = list(selCard[0])
else:
self.cardRank = list('10')
self.cardSuit = list(selCard[-1])
self.generatedCard = list(self.cardRank + self.cardSuit)
self.card.append(self.generatedCard)
return self.card
class Game:
def __init__(self, numPlayers, startingStack):
self.startingStack = startingStack
self.numPlayers = numPlayers
def startGame(self):
newDeck = Deck()
playerList = ['p1', 'p2', 'p3', 'p4', 'p5', 'p6', 'p7', 'p8']
currentPlayer = 0
for player in playerList:
player = Player(self.startingStack)
currentPlayer += 1
if currentPlayer == self.numPlayers:
break
totalPlayers = currentPlayer
# -------------------------- GAME STARTS ---------------------------
newCard = []
currentPlayer = 0
for player in playerList:
newCard.append(player.generateCard(newDeck)) # ERROR IS HERE
if currentPlayer == self.numPlayers:
break
def main():
numberOfPlayers = 1
playerStack = 100
newGame = Game(numberOfPlayers, playerStack)
newGame.startGame()
if __name__ == '__main__':
main()
Upvotes: 0
Views: 381
Reputation: 1121494
Your playerList
object is still a list of strings. Your loop:
for player in playerList:
player = Player(self.startingStack)
currentPlayer += 1
if currentPlayer == self.numPlayers:
break
re-binds player
to a Player()
instance, but this doesn't change the playerList
object. In fact, by the time you get to the next iteration, the Player()
instance is discarded again as nothing else references it.
The for player in playerList
binds player
to each string in the list in turn, but the reference does not work the other direction, player
is just another Python name, another reference to the same object contained in playerList
. Assigning a different object to it will not also alter the list from which the strings were taken.
You probably wanted to build a new list here:
def startGame(self):
newDeck = Deck()
playerList = ['p1', 'p2', 'p3', 'p4', 'p5', 'p6', 'p7', 'p8']
players = []
for player in playerList[:self.numPlayers]:
player = Player(self.startingStack)
players.append(player)
totalPlayers = self.numPlayers
# -------------------------- GAME STARTS ---------------------------
newCard = []
for player in players:
newCard.append(player.generateCard(newDeck))
However, you are entirely ignoring the strings in playerList
here; may as well just build the list without consulting those:
def startGame(self):
newDeck = Deck()
players = [Player(self.startingStack) for _ in range(self.numPlayers)]
newCard = [player.generateCard(newDeck) for player in players]
but you don't need players
then as a separate list either:
def startGame(self):
newDeck = Deck()
newCard = [Player(self.startingStack).generateCard(newDeck)
for _ in range(self.numPlayers)]
Upvotes: 0
Reputation: 66785
You do not have any Player
instances, you create list of string
s:
playerList = ['p1', 'p2', 'p3', 'p4', 'p5', 'p6', 'p7', 'p8']
then in the loop you just do
for player in playerList:
player = Player(self.startingStack)
currentPlayer += 1
if currentPlayer == self.numPlayers:
break
and this local variable player
is lost, it is not magically appended to your playerList
Simply do something like
playerList = [ Player(self.startingStack) for _ in range(self.numPlayers) ]
instead of your loop
Upvotes: 1