使用类和函数在python上创建纸牌游戏-编辑

时间:2019-04-16 17:45:29

标签: python class playing-cards

我正在学习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)

另一个编辑:

谢谢大家的回答!现在,我对整个事情有了更好的了解,我正在用不同的方式重写它!

2 个答案:

答案 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

The Program

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