Vinnaren i pepparkakshustävlingen!
2017-03-23, 07:40
  #1
Medlem
Lures avatar
Skriver ett kortspel för att lära mig OOP tänk. Kör Python 2.7

player1.table.append(player1.deck.cards[0]) lägger också till ett kort i player2.table, varför?

Jag ska ändra table till en underklass av Player men jag förstår inte varför det blir så.

samma sak händer om jag kör

hand = Hand()
hand2 = Hand()
istället för
hand = Hand([Minion()])
hand2 = Hand()

om jag kör Hand() två gånger så borde det ju bli två egna instanser men dem är refererad till varandra? Jag har försökt läsa pythons klass doc men jag är helt clueless, hjälp . Utöver det tar jag gärna tips om mitt klass upplägg.

Kod:
import sys;
import random;
print(sys.version);

class Card(object):
	"""A minion, spell or a trap"""

	def __init__(self, name = 'Empty Card', cost = 1):
		self.name = name
		self.cost = cost
		
	def __str__(self):
		return "{0} {1}".format(self.name, self.cost)

class Minion(Card):

	def __init__(self, attack = 1, defense = 1, name = 'A Dude', cost = 1, taunt = False, flying = False):
		Card.__init__(self, name, cost)
		self.attack = attack
		self.defense = defense 
		self.taunt = taunt
		self.flying = flying

	def __str__(self):
		return "{0} {1} {2}".format(self.attack, self.defense, self.name)

	def fight(self, other):
		self.defense = self.defense - other.attack
		other.defense = other.defense - self.attack

class Spell(Card):

	def __init__(self, name = 'Magic Default Bolt', cost = 1, targetting = 'pick', targets = 1, targetType = 'minion'):
		Card.__init__(self, name, cost)
		self.targeting = targeting #random or pick
		self.targets = targets #number of targets
		self.targetType = targetType #player, minion, all

		def __str__(self):
			return "{0} {1} {2}".format(super.self.name, self.cost)

#class Damage(Spell):

#class Buff(Spell):

class Deck(object):
	"""A Deck of cards"""

	def __init__(self, n):
		self.cards = [] 
		for x in range(n):
			self.cards.append(Minion(random.randint(1, 5),random.randint(1, 5)))

	def __str__(self):
		output = "Deck: "
		for card in self.cards:
			output += str(card) + " - " 
		return output[:-3] 

	def shuffle(self):
		temp = []
		for x in reversed(range(len(self.cards))):
			temp.append(self.cards.pop(random.randint(0,x)))
		self.deck = temp

class Hand(object):
	"""Player Hand, 0-7 cards"""

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

	def __str__(self):
		output = "Hand: "
		for card in self.cards:
			output += str(card) + " - " 
		return output[:-3] 

class Player(object):
	"""Handle player actions"""

	def __init__(self, name = 'Pringleskillen', deck = [], hand = [], table = [], graveyard = [], mana = 0, availableMana = 0, life = 30):
		self.name = name
		self.deck = deck  #gora om till underklass
		self.hand = hand  #gora om till underklass
		self.graveyard = graveyard #gora om till underklass
		self.table = table #gora om till underklass
		self.mana = mana
		self.availableMana = availableMana
		self.life = life
		
	def drawCard(self, n):
		for n in range(n):
			try:
				self.hand.cards.append(self.deck.cards.pop())
			except:
				print 'nope'

	def play(self, i):
		try:
			self.table.append(self.hand.cards.pop(i))
			print 'ja'
		except:
			print 'nope'

	def finishTurn(self):
		"""start AI turn, add one mana"""

class GameSession(object):

	def __init__(self, player1, player2,player1IsAI = False, player2IsAI = True):
		self.player1 = player1
		self.player1IsAI = player1IsAI
		self.player2 = player2
		self.player2IsAI = player2IsAI

class ConsoleGraphics(object):
	"""draw stuff"""

	def draw(self):

		print player2.name + ' Mana: ' + str(player2.availableMana) + '/' + str(player2.mana) 
		
		for card in player2.table:
			print '|' + str(card.attack) + ' ' + str(card.defense) + '|',
		else:
			print		

		print '_'*40

		for card in player1.table:
			print '|' + str(card.attack) + ' ' + str(card.defense) + '|',
		else:
			print

		print player1.name + ' Mana: ' + str(player1.availableMana) + '/' + str(player1.mana)


deck = Deck(6)
deck2 = Deck(5)

hand = Hand([Minion()])
hand2 = Hand()

player1 = Player('Drakdodaren Stiglovik', deck, hand)
player2 = Player('Viggo af Snedansikte', deck2, hand2)

print player1.deck
print player2.deck

player1.drawCard(1)
player2.drawCard(2)

print player1.hand
print player2.hand

player1.table.append(player1.deck.cards[0])
print player2.table[0]

game = GameSession(player1, player2)

g = ConsoleGraphics()
g.draw()
Citera
2017-03-23, 08:12
  #2
Medlem
Default argument i Python är luriga. Kolla upp listor som default argument.
Snabbkoll så kan ha fel.
Citera
2017-03-23, 08:21
  #3
Moderator
vhes avatar
Citat:
Ursprungligen postat av flirk
Default argument i Python är luriga. Kolla upp listor som default argument.
Snabbkoll så kan ha fel.

Du har helt rätt. Här finns en tydlig beskrivning av fenomenet: http://docs.python-guide.org/en/latest/writing/gotchas/
Citera
2017-03-23, 09:28
  #4
Medlem
Lures avatar
A new list is created once when the function is defined, and the same list is used in each successive call.

Aah ok, då känner jag mig inte dum i huvudet längre. Tack
Citera

Stöd Flashback

Flashback finansieras genom donationer från våra medlemmar och besökare. Det är med hjälp av dig vi kan fortsätta erbjuda en fri samhällsdebatt. Tack för ditt stöd!

Stöd Flashback