我正在学习Python编程,并且正在尝试制作一款流行的纸牌游戏。
我是从骨架开始的,所以我写了一些代码来创建卡座,发牌并洗牌。 现在,我想创建2个“拥有”一手牌的玩家,其中最多可以保留3张牌,并且可以从套牌中“抽出”牌。 我考虑过一个玩家类,其中定义了每个不同玩家的名称和手牌属性,但是当我尝试用玩家1来抓牌时,它也会将这些牌添加到玩家2的手牌中。我该如何更改它,以便将卡片添加到玩家中并且仅添加到玩家中,并将其从卡组中移除?我的解决方案出了什么问题?
输出:
['10 di Denari', '1 di Coppe']
['10 di Denari', '1 di Coppe', '6 di Denari', '5 di Denari']
您能帮助我了解如何使其工作吗?
编辑:是的,我粘贴了错误的代码,这是我需要帮助的代码:
import random
semi = ['Bastoni','Spade','Coppe','Denari']
numeri = [1,2,3,4,5,6,7,8,9,10]
mazzo = []
for element in numeri:
for seme in semi:
carta = str(element) + ' di ' + seme
mazzo.append(carta)
Rimanenti = len(mazzo)
def mischia():
random.shuffle(mazzo)
class Giocatore:
nome = None
mano = []
tola = []
def __init__(self,nome):
self.nome=nome
def draw(q):
for n in range(0, q):
pesco = random.choice(mazzo)
Giocatore.mano.append(pesco)
mazzo.remove(pesco)
def turno():
Giocatore.draw('Toni',1)
Giocatore.draw('Piero',1)
def inizio():
Giocatore.draw('Toni', 3)
Giocatore.draw('Piero', 3)
class Piero(Giocatore):
nome = 'Piero'
class Toni(Giocatore):
nome = 'Toni'
Toni.draw(2)
print(Toni.mano)
Piero.draw(2)
print(Piero.mano)
另一个编辑:
谢谢大家的回答!现在,我对整个事情有了更好的了解,我正在用不同的方式重写它!
答案 0 :(得分:0)
您使用的类不正确。创建Player类就像定义玩家身份,这是打牌游戏的想法。您不能仅使用玩家的 idea 玩纸牌游戏;您需要实际的球员来体现球员的才能。用编程的方式,玩家将实例化玩家类。
您正在尝试使用类本身而不是类实例来玩游戏。您需要实例化Giocatore
两次(每个玩家一次)并使用实例。要实例化,您需要执行以下操作:
player1 = Giocatore('Pietro')
player2 = Giocatore('Toni')
在底部,您将Giocatore
子类化为以玩家命名的新类。除非每个玩家具有不同的能力(即属性和/或方法),否则这是没有必要的。而且与实例化Giocatore
不同。
当我尝试用玩家1来抓牌时,它还会将卡片添加到玩家2的手中。...我该如何更改它以便将玩家的卡片添加到玩家中而只添加到玩家中,并将其从牌组中移出?我的解决方案出了什么问题?
有两个原因。首先,如上所述,您正在玩类本身。但是,即使您没有这样做,也存在另一个问题,即您已将mano
手设为 class 属性而不是 instance 属性。这意味着所有实例将共享该属性。因此所有玩家将分享完全相同的一手牌。在draw
方法中,应该是Giocatore.mano.append(pesco)
而不是self.mano.append(pesco)
。这样,您只将新卡放在该玩家的手中,而不是由所有玩家共同共享的手。
要使手成为实例属性,应在__init__
中定义它。该方法应如下所示:
def __init__(self, nome):
self.nome = nome
self.mano = []
这里self
是指实例。
关于从卡组中取出卡片,如果您已经在开始时使用random.shuffle
将它们随机化了,那么在绘制新卡片时就不需要使用random.choice
。我建议只从列表中弹出一个,就像这样:
def draw(self, n):
for _ in range(n):
self.mano.append(mazzo.pop())
答案 1 :(得分:0)
I think the main problem is that you are misunderstanding the difference between class variables and instance variables. I'll use a simple example:
class Player():
hand = [] # hand is a class variable, as it is not tied to an instance
p1 = Player() # p1 is an instance of Player
p2 = Player() # p2 is a separate instance of Player()
Now, if I add something to the hand of p1
:
p1.hand.append(1)
p2.hand
# [1]
This is because I have defined hand
at the class level, and so both p1.hand
and p2.hand
are really Player.hand
. To change this, you will want hand
to be attached to an instance, using self.hand
and the __init__
dunder method, which acts like a constructor for class instances.
class Player():
def __init__(self): # self is always passed as the first argument
self.hand = []
p1 = Player()
p2 = Player()
Now, p1.hand
is a completely different object than p2.hand
because they were created through each call to __init__
. Now if I add something to p1.hand
:
p1.hand.append(1)
p1.hand
# [1]
p2.hand
# []
They aren't both modified. Now, to touch on class functions. By default, functions in classes are instance level, which means that self
, or the class instance, will be implicitly passed as the first argument. If you don't have a placeholder for self
, you will get errors:
class A():
def a():
print("did something")
inst = A()
a.a()
# TypeError: a() takes 0 positional arguments but 1 was given
# To fix this
class A():
def a(self):
print("did something")
inst = A()
a.a()
# did something
Fortunately, you've identified what you need for this program to function properly, two players, a deck of cards, and a mechanism to take turns. Because you are using random.choice
to pick cards, I'd argue that you don't actually need a function to shuffle the deck. You can get the card by choosing a random card as you've done before:
semi = ['Bastoni','Spade','Coppe','Denari']
numeri = [1,2,3,4,5,6,7,8,9,10]
mazzo = ['%d di %s' % (element, seme) for seme in semi for element in numeri]
To draw a card, you can use the following:
# Use random.choice as you've done before
idx = random.coice(mazzo)
mazzo.remove(drawn_card)
The class method remove
will remove a value from the list. Paired with your class.hand
approach:
Toni = Player()
Toni.hand.append(drawn_card)
Or, as a method in the Player
class:
class Player():
def __init__(self):
self.hand = []
def draw(self):
# Need to convert set to list to choose
drawn_card = random.choice(mazzo)
mazzo.remove(drawn_card)
self.hand.append(drawn_card)
print(self.hand) # If you want to see the hand
toni = Player()
toni.draw()
# ['8 di Spade']
Though you could view that as a bit verbose. If you wanted to keep your shuffle method, then you could shuffle the deck every time and use pop
to grab a random card as @ibonyun suggested