Создание карточной игры на Python с использованием классов и функций - РЕДАКТИРОВАТЬ - PullRequest
0 голосов
/ 16 апреля 2019

Я изучаю программирование на Python и пытаюсь сделать рабочую популярную карточную игру.

Я начинаю со скелета, поэтому я написал некоторый код для создания колоды, раздачи карт и перетасовки колоды.Теперь я хочу создать 2 игроков, у которых есть «рука», в которой они могут хранить максимум 3 карты и могут «вытягивать» карты из колоды.Я подумал о классе игрока, в котором определены атрибуты имени и руки для каждого отдельного игрока, но когда я попытался взять карты с player1, он также добавил карты в руку player2.Как я могу изменить его, чтобы он добавлял карты игроку и только ему, удаляя их из колоды?Что не так с моим решением?

Вывод:

['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 голосов
/ 17 апреля 2019

Я думаю, что основная проблема в том, что вы неправильно понимаете разницу между переменными класса и переменными экземпляра. Я буду использовать простой пример:

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()

Теперь, если я добавлю что-то к руке p1:

p1.hand.append(1)

p2.hand
# [1]

Это потому, что я определил hand на уровне class , и поэтому p1.hand и p2.hand действительно Player.hand. Чтобы изменить это, вам нужно, чтобы hand был присоединен к экземпляру, используя self.hand и метод __init__ dunder, который действует как конструктор для экземпляров класса.

class Player():
    def __init__(self): # self is always passed as the first argument
        self.hand = []

p1 = Player() 
p2 = Player()

Теперь p1.hand - это совершенно другой объект, чем p2.hand, потому что они были созданы при каждом вызове __init__. Теперь, если я добавлю что-то к p1.hand:

p1.hand.append(1)
p1.hand
# [1]
p2.hand
# []

Они оба не изменены. Теперь коснемся функций класса. По умолчанию функции в классах имеют уровень экземпляра, что означает, что self, или класс instance , будет неявно передан в качестве первого аргумента. Если у вас нет места для self, вы получите ошибки:

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

Программа

К счастью, вы определили, что нужно для правильной работы этой программы, двух игроков, колоды карт и механизма по очереди. Поскольку вы используете random.choice для выбора карт, я бы сказал, что вам на самом деле не нужна функция, чтобы перетасовать колоду. Вы можете получить карту, выбрав случайную карту, как вы делали раньше:

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]

Чтобы нарисовать карту, вы можете использовать следующее:

# Use random.choice as you've done before
idx = random.coice(mazzo)
mazzo.remove(drawn_card)

Метод класса remove удалит значение из списка. В паре с вашим class.hand подходом:

Toni = Player()

Toni.hand.append(drawn_card)

Или, как метод в классе Player:

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']

Хотя вы можете считать это немного многословным. Если вы хотите сохранить свой метод перемешивания, вы можете каждый раз перетасовывать колоду и использовать pop, чтобы взять случайную карту, как @ibonyun предложил

0 голосов
/ 16 апреля 2019

Вы используете классы неправильно.Создание класса Player - это то же самое, что и определение уровня игрока, который является идеей того, что значит быть игроком в карточную игру.Вы не можете играть в карточную игру только с идеей игрока;вам нужны настоящие игроки, которые иллюстрируют игривость.С точки зрения программирования, игроки будут создавать класс Player.

Вы пытаетесь играть в игру с самим классом, а не с экземплярами класса.Вам нужно создать экземпляр Giocatore дважды (один раз для каждого игрока) и поиграть с экземплярами.Для создания экземпляра вам нужно сделать что-то вроде этого:

player1 = Giocatore('Pietro')
player2 = Giocatore('Toni')

Внизу вы подклассифицировали Giocatore с новыми классами, названными в честь игроков.Если у каждого игрока нет разных способностей (то есть атрибутов и / или методов), это не нужно.И это не то же самое, что создание экземпляра Giocatore.

, когда я пытался взять карты с player1, он также добавил карты в руку player2 .... Как я могу изменить это, чтобы добавитькарты игроку и только ему, удаляя их из колоды?Что не так с моим решением?

Есть две причины.Во-первых, вы играете с самим классом, как я описал выше.Но даже если вы этого не делали, есть дополнительная проблема, заключающаяся в том, что вы сделали атрибут mano a 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())
...